Create more documentation (#7627)

* Documentation, format class, no modification.
This commit is contained in:
frytimo
2025-11-18 21:33:07 -04:00
committed by GitHub
parent e619c97ce6
commit adfc4cc469
104 changed files with 24461 additions and 21721 deletions

View File

@@ -54,6 +54,13 @@
} }
//define the functions //define the functions
/**
* Converts an array to a CSV string.
*
* @param array &$array The input array. It should be a multidimensional array where the first level keys are column headers and the second level arrays are rows.
*
* @return string|null The CSV string representation of the input array, or null if the input array is empty.
*/
function array2csv(array &$array) { function array2csv(array &$array) {
if (count($array) == 0) { if (count($array) == 0) {
return null; return null;
@@ -69,7 +76,14 @@
} }
//send download headers //send download headers
function download_send_headers($filename) { /**
* Sends HTTP headers to force a file download.
*
* @param string $filename The name of the file to be downloaded, excluding the path.
*
* @return void
*/
function download_send_headers($filename) {
// disable caching // disable caching
$now = gmdate("D, d M Y H:i:s"); $now = gmdate("D, d M Y H:i:s");
header("Expires: Tue, 03 Jul 2001 06:00:00 GMT"); header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");

View File

@@ -40,6 +40,16 @@
//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 //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')) { if (!function_exists('str_getcsv')) {
/**
* Parse a CSV string into an array.
*
* @param string $input The CSV data to parse.
* @param string $delimiter The field delimiter (default: ",").
* @param string $enclosure The field enclosure character (default: """).
* @param string $escape The escape character (default: "\"").
*
* @return array An array containing the parsed CSV fields.
*/
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") { function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
$fp = fopen("php://memory", 'r+'); $fp = fopen("php://memory", 'r+');
fputs($fp, $input); fputs($fp, $input);
@@ -212,6 +222,14 @@
} }
//get the parent table //get the parent table
/**
* Retrieve the parent table for a given table in a schema.
*
* @param array $schema The database schema to search in.
* @param string $table_name The name of the table for which to find the parent.
*
* @return mixed The name of the parent table, or NULL if not found.
*/
function get_parent($schema,$table_name) { function get_parent($schema,$table_name) {
foreach ($schema as $row) { foreach ($schema as $row) {
if ($row['table'] == $table_name) { if ($row['table'] == $table_name) {

View File

@@ -3,290 +3,315 @@
/** /**
* access controls class * access controls class
*/ */
class access_controls { class access_controls {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'access_controls'; const app_name = 'access_controls';
const app_uuid = '1416a250-f6e1-4edc-91a6-5c9b883638fd'; const app_uuid = '1416a250-f6e1-4edc-91a6-5c9b883638fd';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
/** /**
* called when the object is created * called when the object is created
*/ */
public function __construct(array $setting_array = []) { public function __construct(array $setting_array = []) {
//set domain and user UUIDs //set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; $this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; $this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$config = $setting_array['config'] ?? config::load(); $config = $setting_array['config'] ?? config::load();
$this->database = $setting_array['database'] ?? database::new(['config' => $config]); $this->database = $setting_array['database'] ?? database::new(['config' => $config]);
//assign private variables //assign private variables
$this->list_page = 'access_controls.php'; $this->list_page = 'access_controls.php';
} }
/** /**
* delete records * Deletes one or multiple records from the access controls table.
*/ *
public function delete($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 private variables //assign private variables
$this->permission_prefix = 'access_control_'; $this->permission_prefix = 'access_control_';
$this->table = 'access_controls'; $this->table = 'access_controls';
$this->uuid_prefix = 'access_control_'; $this->uuid_prefix = 'access_control_';
if (permission_exists($this->permission_prefix . 'delete')) { if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array['access_control_nodes'][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('access_control_node_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('access_control_node_delete', 'temp');
//clear the cache
$cache = new cache;
$cache->delete("configuration:acl.conf");
//create the event socket connection
event_socket::async("reloadacl");
//set message
message::add($text['message-delete']);
}
unset($records);
}
} }
}
public function delete_nodes($records) { //delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//assign private variables //build the delete array
$this->permission_prefix = 'access_control_node_'; foreach ($records as $x => $record) {
$this->table = 'access_control_nodes'; if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$this->uuid_prefix = 'access_control_node_'; $array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array['access_control_nodes'][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
if (permission_exists($this->permission_prefix . 'delete')) { }
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate('/app/access_controls/access_control_nodes.php')) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
} }
//delete multiple records //delete the checked rows
if (is_array($records) && @sizeof($records) != 0) { if (is_array($array) && @sizeof($array) != 0) {
//build the delete array //grant temporary permissions
foreach ($records as $x => $record) { $p = permissions::new();
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) { $p->add('access_control_node_delete', 'temp');
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
}
}
//delete the checked rows //execute delete
if (is_array($array) && @sizeof($array) != 0) { $this->database->delete($array);
unset($array);
//execute delete //revoke temporary permissions
$this->database->delete($array); $p->delete('access_control_node_delete', 'temp');
unset($array);
//clear the cache //clear the cache
$cache = new cache; $cache = new cache;
$cache->delete("configuration:acl.conf"); $cache->delete("configuration:acl.conf");
//create the event socket connection //create the event socket connection
event_socket::async("reloadacl"); event_socket::async("reloadacl");
//set message //set message
message::add($text['message-delete']); message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* copy records
*/
public function copy($records) {
//assign private variables
$this->permission_prefix = 'access_control_';
$this->table = 'access_controls';
$this->uuid_prefix = 'access_control_';
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $primary_uuid;
$array[$this->table][$x]['access_control_description'] = trim($row['access_control_description'] . ' (' . $text['label-copy'] . ')');
//nodes sub table
$sql_2 = "select * from v_access_control_nodes where access_control_uuid = :access_control_uuid";
$parameters_2['access_control_uuid'] = $row['access_control_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//copy data
$array['access_control_nodes'][$y] = $row_2;
//overwrite
$array['access_control_nodes'][$y]['access_control_node_uuid'] = uuid();
$array['access_control_nodes'][$y]['access_control_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('access_control_node_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('access_control_node_add', 'temp');
//clear the cache
$cache = new cache;
$cache->delete("configuration:acl.conf");
//create the event socket connection
event_socket::async("reloadacl");
//set message
message::add($text['message-copy']);
}
unset($records);
} }
unset($records);
} }
} }
} }
/**
* Deletes one or more access control nodes.
*
* @param array $records Array of records to delete, where each record is an associative array containing the
* 'uuid' and 'checked' keys.
*
* @return void
*/
public function delete_nodes($records) {
//assign private variables
$this->permission_prefix = 'access_control_node_';
$this->table = 'access_control_nodes';
$this->uuid_prefix = 'access_control_node_';
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate('/app/access_controls/access_control_nodes.php')) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//clear the cache
$cache = new cache;
$cache->delete("configuration:acl.conf");
//create the event socket connection
event_socket::async("reloadacl");
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Copy access controls and their nodes.
*
* @param array $records An array of records to copy. Each record should contain a 'checked' key with value 'true'
* and a 'uuid' key with the UUID of the access control or node to copy.
*
* @return void
*/
public function copy($records) {
//assign private variables
$this->permission_prefix = 'access_control_';
$this->table = 'access_controls';
$this->uuid_prefix = 'access_control_';
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $primary_uuid;
$array[$this->table][$x]['access_control_description'] = trim($row['access_control_description'] . ' (' . $text['label-copy'] . ')');
//nodes sub table
$sql_2 = "select * from v_access_control_nodes where access_control_uuid = :access_control_uuid";
$parameters_2['access_control_uuid'] = $row['access_control_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//copy data
$array['access_control_nodes'][$y] = $row_2;
//overwrite
$array['access_control_nodes'][$y]['access_control_node_uuid'] = uuid();
$array['access_control_nodes'][$y]['access_control_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('access_control_node_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('access_control_node_add', 'temp');
//clear the cache
$cache = new cache;
$cache->delete("configuration:acl.conf");
//create the event socket connection
event_socket::async("reloadacl");
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -35,12 +35,29 @@ class caller_context_filter implements filter {
private $domains; private $domains;
/**
* Initializes the object with an array of domain names.
*
* @param array $domain_names Array of domain names to initialize the object with.
*
* @return void
*/
public function __construct(array $domain_names) { public function __construct(array $domain_names) {
foreach ($domain_names as $name) { foreach ($domain_names as $name) {
$this->domains[$name] = true; $this->domains[$name] = true;
} }
} }
/**
* Invokes this method as a callable.
*
* @param string $key The event key, which is used for validation and filtering.
* @param mixed $value The value associated with the event key, used to determine
* whether the filter chain should drop the payload.
*
* @return bool|null Returns true if the key is not 'caller_context' or the value exists in the domains,
* otherwise returns null to drop the payload.
*/
public function __invoke(string $key, $value): ?bool { public function __invoke(string $key, $value): ?bool {
// return true when not on the event key caller_context to validate // return true when not on the event key caller_context to validate
if ($key !== 'caller_context') { if ($key !== 'caller_context') {

View File

@@ -35,10 +35,28 @@ class event_filter implements filter {
private $event_names; private $event_names;
/**
* Initializes the object with the event names to filter on.
*
* @param array $event_names Array of event names to initialize the object with
*/
public function __construct(array $event_names) { public function __construct(array $event_names) {
$this->add_event_names($event_names); $this->add_event_names($event_names);
} }
/**
* Invokes this method to filter events.
*
* @param string $key The key name that will be used for filtering, currently only
* supports the "event_name" key.
* @param mixed $value The value associated with the provided key.
*
* @return bool|null Returns true if the invocation is valid and the event name
* filter has not been applied yet. If the invocation has an "event_name"
* key and its corresponding value, this method will return a boolean
* indicating whether the event name already exists in the list of allowed
* names or not. Otherwise returns null.
*/
public function __invoke(string $key, $value): ?bool { public function __invoke(string $key, $value): ?bool {
if ($key !== 'event_name') { if ($key !== 'event_name') {
return true; return true;
@@ -69,17 +87,20 @@ class event_filter implements filter {
} }
} }
/**
* Checks if an event with the given name is present in the filters.
*
* @param string $name The name of the event to check for.
*
* @return bool|null True if the event is found, otherwise null. Returns null
* when the event is not allowed due to permissions constraints.
*/
public function has_event_name(string $name): ?bool { public function has_event_name(string $name): ?bool {
if (isset($this->event_names[$name])) if (isset($this->event_names[$name])) {
return true; return true;
// }
// If the event name is not allowed by the permissions given in
// this object, then the entire event must be dropped. I could //reject the payload
// not figure out a better way to do this except to throw an
// exception so that the caller can drop the message.
//
// TODO: Find another way not so expensive to reject the payload
//
return null; return null;
} }
} }

View File

@@ -34,10 +34,23 @@ class event_key_filter implements filter {
private $filters; private $filters;
/**
* Initializes a new instance of the object with specified filters.
*
* @param array $filters Optional array of initial filters to be applied.
*/
public function __construct(array $filters = []) { public function __construct(array $filters = []) {
$this->add_filters($filters); $this->add_filters($filters);
} }
/**
* Invokes a filter check with the given key and value.
*
* @param string $key The key of the filter to check
* @param mixed $value The value associated with the filter key
*
* @return bool|null True if the filter exists, false otherwise
*/
public function __invoke(string $key, $value): ?bool { public function __invoke(string $key, $value): ?bool {
return $this->has_filter_key($key); return $this->has_filter_key($key);
} }
@@ -84,6 +97,13 @@ class event_key_filter implements filter {
} }
} }
/**
* Checks if a filter key exists.
*
* @param string $key The filter key to check for existence.
*
* @return bool True if the filter key exists, false otherwise.
*/
public function has_filter_key(string $key): bool { public function has_filter_key(string $key): bool {
return isset($this->filters[$key]); return isset($this->filters[$key]);
} }

View File

@@ -46,6 +46,11 @@ class event_message implements filterable_payload {
* @var array * @var array
*/ */
private $event; private $event;
/**
* Body of the SIP MESSAGE used in SMS
* @var string
*/
private $body; private $body;
/** /**
@@ -102,6 +107,11 @@ class event_message implements filterable_payload {
return $this->event[$name] ?? ''; return $this->event[$name] ?? '';
} }
/**
* Return an array representation of this object.
*
* @return array
*/
public function __toArray(): array { public function __toArray(): array {
$array = []; $array = [];
foreach ($this->event as $key => $value) { foreach ($this->event as $key => $value) {
@@ -110,10 +120,22 @@ class event_message implements filterable_payload {
return $array; return $array;
} }
/**
* Convert the current object into an array representation.
*
* @return array
*/
public function to_array(): array { public function to_array(): array {
return $this->__toArray(); return $this->__toArray();
} }
/**
* Apply a filter to the event collection.
*
* @param filter $filter The filter function to apply
*
* @return self This object for method chaining
*/
public function apply_filter(filter $filter) { public function apply_filter(filter $filter) {
foreach ($this->event as $key => $value) { foreach ($this->event as $key => $value) {
$result = ($filter)($key, $value); $result = ($filter)($key, $value);
@@ -126,6 +148,16 @@ class event_message implements filterable_payload {
return $this; return $this;
} }
/**
* Parse an active calls JSON string and return a list of event messages.
*
* This method expects a JSON string where each row represents an active call, and returns
* a list of event_message objects populated with the relevant details for each call.
*
* @param string $json_string The JSON string to parse.
*
* @return array A list of event_message objects.
*/
public static function parse_active_calls($json_string): array { public static function parse_active_calls($json_string): array {
$calls = []; $calls = [];
$json_array = json_decode($json_string, true); $json_array = json_decode($json_string, true);
@@ -181,6 +213,15 @@ class event_message implements filterable_payload {
return null; return null;
} }
/**
* Creates a new instance from a switch event.
*
* @param array|string $raw_event The raw event data.
* @param filter|null $filter Optional filter to be applied on the created object.
* @param int $flags Flags controlling the creation process (see EVENT_SWAP_API and EVENT_USE_SUBCLASS).
*
* @return self
*/
public static function create_from_switch_event($raw_event, filter $filter = null, $flags = 3): self { public static function create_from_switch_event($raw_event, filter $filter = null, $flags = 3): self {
// Set the options from the flags passed // Set the options from the flags passed
@@ -264,6 +305,14 @@ class event_message implements filterable_payload {
return $this->body; return $this->body;
} }
/**
* Convert the event object to an array representation.
*
* This method iterates over the event properties and includes them in the returned array.
* If the body is not null, it will be included as a separate key-value pair in the resulting array.
*
* @return array
*/
public function event_to_array(): array { public function event_to_array(): array {
$array = []; $array = [];
foreach ($this->event as $key => $value) { foreach ($this->event as $key => $value) {
@@ -275,15 +324,39 @@ class event_message implements filterable_payload {
return $array; return $array;
} }
/**
* Return an iterator for this object.
*
* This method allows iteration over the event data as a Traversable object.
*
* @return \Traversable
*/
public function getIterator(): \Traversable { public function getIterator(): \Traversable {
yield from $this->event_to_array(); yield from $this->event_to_array();
} }
/**
* Check if a specific event key exists in this object.
*
* @param mixed $offset The key of the event to check for existence
*
* @return bool True if the event key exists, false otherwise
*/
public function offsetExists(mixed $offset): bool { public function offsetExists(mixed $offset): bool {
self::sanitize_event_key($offset); self::sanitize_event_key($offset);
return isset($this->event[$offset]); return isset($this->event[$offset]);
} }
/**
* Return the value associated with the given key from this event object.
*
* If the key is 'body', returns the event body. Otherwise, returns the value
* stored in the 'event' array for the given key.
*
* @param mixed $offset The key to retrieve the value for.
*
* @return mixed The value associated with the given key.
*/
public function offsetGet(mixed $offset): mixed { public function offsetGet(mixed $offset): mixed {
self::sanitize_event_key($offset); self::sanitize_event_key($offset);
if ($offset === self::BODY_ARRAY_KEY) { if ($offset === self::BODY_ARRAY_KEY) {
@@ -292,6 +365,16 @@ class event_message implements filterable_payload {
return $this->event[$offset]; return $this->event[$offset];
} }
/**
* Set the value for a given offset in this object.
*
* @param mixed $offset The key or index to set the value for. If it is
* {@link self::BODY_ARRAY_KEY}, this method will replace the
* entire body of the event with the provided value.
* @param mixed $value The new value to be associated with the offset.
*
* @return void
*/
public function offsetSet(mixed $offset, mixed $value): void { public function offsetSet(mixed $offset, mixed $value): void {
self::sanitize_event_key($offset); self::sanitize_event_key($offset);
if ($offset === self::BODY_ARRAY_KEY) { if ($offset === self::BODY_ARRAY_KEY) {
@@ -301,6 +384,15 @@ class event_message implements filterable_payload {
} }
} }
/**
* Unsets a property from the event array.
*
* This method first sanitizes the provided offset using the sanitize_event_key method to prevent potential security vulnerabilities.
* If the sanitized offset is equal to the BODY_ARRAY_KEY, it sets the body property of this object to null.
* Otherwise, it removes the specified key from the event array.
*
* @param mixed $offset The index or key to be unset from the event array.
*/
public function offsetUnset(mixed $offset): void { public function offsetUnset(mixed $offset): void {
self::sanitize_event_key($offset); self::sanitize_event_key($offset);
if ($offset === self::BODY_ARRAY_KEY) { if ($offset === self::BODY_ARRAY_KEY) {

View File

@@ -35,6 +35,11 @@ class extension_filter {
private $extensions; private $extensions;
/**
* Initializes the class with an array of extensions for fast lookup.
*
* @param array $extensions An optional array of extension configurations. Defaults to [].
*/
public function __construct(array $extensions = []) { public function __construct(array $extensions = []) {
//organize the extensions in a way we can use isset for fast lookup //organize the extensions in a way we can use isset for fast lookup
foreach ($extensions as $extension) { foreach ($extensions as $extension) {
@@ -43,6 +48,14 @@ class extension_filter {
} }
} }
/**
* Invokes this instance with a key-value pair for fast lookup.
*
* @param string $key The presence ID key to look up in the extensions array.
* @param mixed $value The value associated with the key, which is used as an index in the extensions array.
*
* @return bool|null True if no match was found or the key is not 'channel_presence_id', null otherwise when dropping a message.
*/
public function __invoke(string $key, $value): ?bool { public function __invoke(string $key, $value): ?bool {
//only match on channel_presence_id key //only match on channel_presence_id key
if ($key === 'channel_presence_id' && !isset($this->extensions[$value])) { if ($key === 'channel_presence_id' && !isset($this->extensions[$value])) {

View File

@@ -1,209 +1,256 @@
<?php <?php
class azure{ class azure {
public static $formats = array ( /**
'English-Zira' => * Array of available speech formats.
array ( *
'lang' => 'en-US', * This array contains a list of voice names and their corresponding languages
'gender' => 'Female', * and genders. The keys are the voice names, and the values are arrays containing
'name' => 'Microsoft Server Speech Text to Speech Voice (en-US, ZiraRUS)' * the language code and gender.
), *
'English-Jessa' => * @var array
array ( */
'lang' => 'en-US', public static $formats = [
'gender' => 'Female', 'English-Zira' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (en-US, JessaRUS)' [
), 'lang' => 'en-US',
'English-Benjamin' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-US, ZiraRUS)',
'lang' => 'en-US', ],
'gender' => 'Male', 'English-Jessa' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (en-US, BenjaminRUS)' [
), 'lang' => 'en-US',
'British-Susan' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-US, JessaRUS)',
'lang' => 'en-GB', ],
'gender' => 'Female', 'English-Benjamin' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (en-GB, Susan, Apollo)' [
), 'lang' => 'en-US',
'British-Hazel' => 'gender' => 'Male',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-US, BenjaminRUS)',
'lang' => 'en-GB', ],
'gender' => 'Female', 'British-Susan' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (en-GB, HazelRUS)' [
), 'lang' => 'en-GB',
'British-George' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-GB, Susan, Apollo)',
'lang' => 'en-GB', ],
'gender' => 'Male', 'British-Hazel' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (en-GB, George, Apollo)' [
), 'lang' => 'en-GB',
'Australian-Catherine' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-GB, HazelRUS)',
'lang' => 'en-AU', ],
'gender' => 'Female', 'British-George' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (en-AU, Catherine)' [
), 'lang' => 'en-GB',
'Spanish-Helena' => 'gender' => 'Male',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-GB, George, Apollo)',
'lang' => 'es-ES', ],
'gender' => 'Female', 'Australian-Catherine' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (es-ES, HelenaRUS)' [
), 'lang' => 'en-AU',
'Spanish-Laura' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (en-AU, Catherine)',
'lang' => 'es-ES', ],
'gender' => 'Female', 'Spanish-Helena' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (es-ES, Laura, Apollo)' [
), 'lang' => 'es-ES',
'Spanish-Pablo' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (es-ES, HelenaRUS)',
'lang' => 'es-ES', ],
'gender' => 'Male', 'Spanish-Laura' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (es-ES, Pablo, Apollo)' [
), 'lang' => 'es-ES',
'French-Julie' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (es-ES, Laura, Apollo)',
'lang' => 'fr-FR', ],
'gender' => 'Female', 'Spanish-Pablo' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (fr-FR, Julie, Apollo)' [
), 'lang' => 'es-ES',
'French-Hortense' => 'gender' => 'Male',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (es-ES, Pablo, Apollo)',
'lang' => 'fr-FR', ],
'gender' => 'Female', 'French-Julie' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (fr-FR, HortenseRUS)' [
), 'lang' => 'fr-FR',
'French-Paul' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (fr-FR, Julie, Apollo)',
'lang' => 'fr-FR', ],
'gender' => 'Male', 'French-Hortense' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (fr-FR, Paul, Apollo)' [
), 'lang' => 'fr-FR',
'German-Hedda' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (fr-FR, HortenseRUS)',
'lang' => 'de-DE', ],
'gender' => 'Female', 'French-Paul' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (de-DE, Hedda)' [
), 'lang' => 'fr-FR',
'Russian-Irina' => 'gender' => 'Male',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (fr-FR, Paul, Apollo)',
'lang' => 'ru-RU', ],
'gender' => 'Female', 'German-Hedda' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (ru-RU, Irina, Apollo)' [
), 'lang' => 'de-DE',
'Russian-Pavel' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (de-DE, Hedda)',
'lang' => 'ru-RU', ],
'gender' => 'Male', 'Russian-Irina' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (ru-RU, Pavel, Apollo)' [
), 'lang' => 'ru-RU',
'Chinese-Huihui' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (ru-RU, Irina, Apollo)',
'lang' => 'zh-CN', ],
'gender' => 'Female', 'Russian-Pavel' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (zh-CN, HuihuiRUS)' [
), 'lang' => 'ru-RU',
'Chinese-Yaoyao' => 'gender' => 'Male',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (ru-RU, Pavel, Apollo)',
'lang' => 'zh-CN', ],
'gender' => 'Female', 'Chinese-Huihui' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (zh-CN, Yaoyao, Apollo)' [
), 'lang' => 'zh-CN',
'Chinese-Kangkang' => 'gender' => 'Female',
array ( 'name' => 'Microsoft Server Speech Text to Speech Voice (zh-CN, HuihuiRUS)',
'lang' => 'zh-CN', ],
'gender' => 'Male', 'Chinese-Yaoyao' =>
'name' => 'Microsoft Server Speech Text to Speech Voice (zh-CN, Kangkang, Apollo)' [
) 'lang' => 'zh-CN',
); 'gender' => 'Female',
'name' => 'Microsoft Server Speech Text to Speech Voice (zh-CN, Yaoyao, Apollo)',
],
'Chinese-Kangkang' =>
[
'lang' => 'zh-CN',
'gender' => 'Male',
'name' => 'Microsoft Server Speech Text to Speech Voice (zh-CN, Kangkang, Apollo)',
],
];
/**
* Initializes the object with provided setting array.
*
* @param array $setting_array An optional array of setting values. Defaults to an empty array.
*/
public function __construct(array $setting_array = []) { public function __construct(array $setting_array = []) {
//set domain and user UUIDs //set domain and user UUIDs
$domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; $domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; $user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$config = $setting_array['config'] ?? config::load(); $config = $setting_array['config'] ?? config::load();
$this->database = $setting_array['database'] ?? database::new(['config' => $config]); $this->database = $setting_array['database'] ?? database::new(['config' => $config]);
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $domain_uuid, 'user_uuid' => $user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $domain_uuid, 'user_uuid' => $user_uuid]);
} }
private static function getTokenUrl(){ /**
return "https://api.cognitive.microsoft.com/sts/v1.0/issueToken"; * Returns the URL for obtaining a token from Microsoft Cognitive Services.
} *
* @return string The URL for issuing a token
*/
private static function getTokenUrl() {
return "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
}
private static function getApiUrl(){ /**
return "https://speech.platform.bing.com/synthesize"; * Returns the URL for interacting with Microsoft Bing Speech API.
} *
* @return string The URL for making requests to the Bing Speech API
*/
private static function getApiUrl() {
return "https://speech.platform.bing.com/synthesize";
}
private static function getSubscriptionKey(settings $settings){ /**
return $settings->get('azure', 'key'); * Returns the subscription key from Azure settings.
} *
* @param settings $settings The settings object containing Azure configuration
*
* @return string The subscription key for Azure services
*/
private static function getSubscriptionKey(settings $settings) {
return $settings->get('azure', 'key');
}
private static function _getToken(settings $settings){ /**
$url = self::getTokenUrl(); * Obtains a token from Microsoft Cognitive Services.
$subscriptionKey = self::getSubscriptionKey($settings); *
* @param settings $settings Settings object containing subscription key and other parameters.
*
* @return string The response from the server, which is expected to be an XML token.
*/
private static function _getToken(settings $settings) {
$url = self::getTokenUrl();
$subscriptionKey = self::getSubscriptionKey($settings);
$headers = array(); $headers = [];
$headers[] = 'Ocp-Apim-Subscription-Key: '. $subscriptionKey; $headers[] = 'Ocp-Apim-Subscription-Key: ' . $subscriptionKey;
$headers[] = 'Content-Length: 0'; $headers[] = 'Content-Length: 0';
$ch = curl_init(); $ch = curl_init();
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ( $ch, CURLOPT_URL, $url ); curl_setopt($ch, CURLOPT_URL, $url);
//curl_setopt($ch, CURLOPT_SSLVERSION, 1); //curl_setopt($ch, CURLOPT_SSLVERSION, 1);
curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 60 ); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt ( $ch, CURLOPT_TIMEOUT, 300 ); curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt ( $ch, CURLOPT_VERBOSE, false); curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POST, true);
//curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string); //curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
$response = curl_exec($ch); $response = curl_exec($ch);
curl_close($ch); curl_close($ch);
return $response; return $response;
} }
public static function synthesize(settings $settings, $data, $format_key){ /**
* Synthesizes the given data into a WAV audio file using Microsoft Cognitive Services.
*
* @param object $settings Settings for the API call
* @param string $data The text to be synthesized
* @param string $format_key The key of the format in self::$formats
*
* @return string The path to the generated WAV file
*/
public static function synthesize(settings $settings, $data, $format_key) {
$lang = self::$formats[$format_key]['lang']; $lang = self::$formats[$format_key]['lang'];
$gender = self::$formats[$format_key]['gender']; $gender = self::$formats[$format_key]['gender'];
$name = self::$formats[$format_key]['name']; $name = self::$formats[$format_key]['name'];
$token = self::_getToken($settings); $token = self::_getToken($settings);
$url = self::getApiUrl(); $url = self::getApiUrl();
$headers = array(); $headers = [];
$headers[] = 'Authorization: Bearer '. $token; $headers[] = 'Authorization: Bearer ' . $token;
$headers[] = 'Content-Type: application/ssml+xml'; $headers[] = 'Content-Type: application/ssml+xml';
$headers[] = 'X-Microsoft-OutputFormat: riff-16khz-16bit-mono-pcm'; $headers[] = 'X-Microsoft-OutputFormat: riff-16khz-16bit-mono-pcm';
$headers[] = 'User-Agent: TTS'; $headers[] = 'User-Agent: TTS';
$xml_post_string = "<speak version='1.0' xml:lang='".$lang."'> $xml_post_string = "<speak version='1.0' xml:lang='" . $lang . "'>
<voice xml:lang='".$lang."' xml:gender='".$gender."' name='".$name."'>"; <voice xml:lang='" . $lang . "' xml:gender='" . $gender . "' name='" . $name . "'>";
$xml_post_string .= $data; $xml_post_string .= $data;
$xml_post_string .= "</voice> $xml_post_string .= "</voice>
</speak>"; </speak>";
$ch = curl_init(); $ch = curl_init();
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ( $ch, CURLOPT_URL, $url ); curl_setopt($ch, CURLOPT_URL, $url);
//curl_setopt($ch, CURLOPT_SSLVERSION, 1); //curl_setopt($ch, CURLOPT_SSLVERSION, 1);
curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 60 ); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt ( $ch, CURLOPT_TIMEOUT, 300 ); curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt ( $ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
$response = curl_exec($ch); $response = curl_exec($ch);
$filename = "tts_".time().".wav"; $filename = "tts_" . time() . ".wav";
file_put_contents("/var/www/html/fusionpbx/app/voiplyrecording/tts_record/".$filename, $response); file_put_contents("/var/www/html/fusionpbx/app/voiplyrecording/tts_record/" . $filename, $response);
curl_close($ch); curl_close($ch);
return $filename; return $filename;
} }
} }

View File

@@ -66,7 +66,9 @@
private $domain_name; private $domain_name;
/** /**
* Called when the object is created * Initializes the object with domain and user UUIDs, domain name, and database objects.
*
* @param array $setting_array An optional array containing settings for this object. Defaults to an empty array.
*/ */
public function __construct(array $setting_array = []) { public function __construct(array $setting_array = []) {
//set domain and user UUIDs //set domain and user UUIDs
@@ -83,7 +85,10 @@
} }
/** /**
* Get the call activity * Handles the call activity by retrieving extensions and their user status,
* sending a command to retrieve active calls, and building a response array.
*
* @return mixed The response array containing extension details and active call information.
*/ */
public function call_activity() { public function call_activity() {

View File

@@ -68,7 +68,9 @@
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with settings and default values.
*
* @param array $setting_array Associative array of setting keys to their respective values (optional)
*/ */
public function __construct(array $setting_array = []) { public function __construct(array $setting_array = []) {
//set domain and user UUIDs //set domain and user UUIDs
@@ -92,7 +94,13 @@
} }
/** /**
* delete records * Deletes one or multiple records from the access controls table.
*
* @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) { public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) { if (permission_exists($this->permission_prefix.'delete')) {
@@ -141,7 +149,13 @@
} }
/** /**
* toggle records * Toggles the state of the specified 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) { public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) { if (permission_exists($this->permission_prefix.'edit')) {
@@ -212,7 +226,12 @@
} }
/** /**
* 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) { public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) { if (permission_exists($this->permission_prefix.'add')) {

View File

@@ -456,6 +456,17 @@ if (permission_exists('call_block_all') || permission_exists('call_block_ring_gr
echo " ".$text['label-action']."\n"; echo " ".$text['label-action']."\n";
echo "</td>\n"; echo "</td>\n";
echo "<td class='vtable' align='left'>\n"; echo "<td class='vtable' align='left'>\n";
/**
* Select a call block action.
*
* This function generates an HTML select element for selecting a call block
* action. It includes options for rejecting, busy, holding, and other actions,
* as well as options for extensions, IVRs, ring groups, and voicemail.
*
* @param bool $label Whether to include the label option or not.
*
* @return void The function does not return any value.
*/
function call_block_action_select($label = false) { function call_block_action_select($label = false) {
global $select_margin, $text, $call_block_app, $call_block_data, $extensions, $ivrs, $voicemails, $ring_groups; global $select_margin, $text, $call_block_app, $call_block_data, $extensions, $ivrs, $voicemails, $ring_groups;
echo "<select class='formfld' style='".$select_margin."' name='call_block_action'>\n"; echo "<select class='formfld' style='".$select_margin."' name='call_block_action'>\n";

View File

@@ -3,495 +3,529 @@
/** /**
* call block class * call block class
*/ */
class call_block { class call_block {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'call_block'; const app_name = 'call_block';
const app_uuid = '9ed63276-e085-4897-839c-4f2e36d92d6c'; const app_uuid = '9ed63276-e085-4897-839c-4f2e36d92d6c';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
/** /**
* declare public variables * declare public variables
*/ */
public $call_block_direction; public $call_block_direction;
public $extension_uuid; public $extension_uuid;
public $call_block_app; public $call_block_app;
public $call_block_data; public $call_block_data;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; * @return void
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; */
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$config = $setting_array['config'] ?? config::load(); $config = $setting_array['config'] ?? config::load();
$this->database = $setting_array['database'] ?? database::new(['config' => $config]); $this->database = $setting_array['database'] ?? database::new(['config' => $config]);
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
//assign private variables //assign private variables
$this->permission_prefix = 'call_block_'; $this->permission_prefix = 'call_block_';
$this->list_page = 'call_block.php'; $this->list_page = 'call_block.php';
$this->table = 'call_block'; $this->table = 'call_block';
$this->uuid_prefix = 'call_block_'; $this->uuid_prefix = 'call_block_';
$this->toggle_field = 'call_block_enabled'; $this->toggle_field = 'call_block_enabled';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
} }
/** /**
* delete records * Deletes one or more records.
*/ *
public function delete($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'delete')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked, build where clause for below
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//get necessary call block details
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, call_block_number from v_" . $this->table . " ";
$sql .= "where ( ";
$sql .= " domain_uuid = :domain_uuid ";
if (permission_exists('call_block_domain')) {
$sql .= " or domain_uuid is null ";
}
$sql .= ") ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$call_block_numbers[$row['uuid']] = $row['call_block_number'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
$x = 0;
foreach ($call_block_numbers as $call_block_uuid => $call_block_number) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $call_block_uuid;
if (!permission_exists('call_block_domain')) {
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//clear the cache
$cache = new cache;
foreach ($call_block_numbers as $call_block_number) {
$cache->delete("app:call_block:" . $this->domain_name . ":" . $call_block_number);
} }
//delete multiple records //set message
if (is_array($records) && @sizeof($records) != 0) { message::add($text['message-delete']);
}
//filter out unchecked, build where clause for below unset($records);
foreach($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//get necessary call block details
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, call_block_number from v_".$this->table." ";
$sql .= "where ( ";
$sql .= " domain_uuid = :domain_uuid ";
if (permission_exists('call_block_domain')) {
$sql .= " or domain_uuid is null ";
}
$sql .= ") ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$call_block_numbers[$row['uuid']] = $row['call_block_number'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
$x = 0;
foreach ($call_block_numbers as $call_block_uuid => $call_block_number) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $call_block_uuid;
if (!permission_exists('call_block_domain')) {
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//clear the cache
$cache = new cache;
foreach ($call_block_numbers as $call_block_number) {
$cache->delete("app:call_block:".$this->domain_name.":".$call_block_number);
}
//set message
message::add($text['message-delete']);
}
unset($records);
}
} }
} }
}
/** /**
* toggle records * Toggles the state of one or more records.
*/ *
public function toggle($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'edit')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, call_block_number from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
$call_block_numbers[] = $row['call_block_number'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//clear the cache
$cache = new cache;
foreach ($call_block_numbers as $call_block_number) {
$cache->delete("app:call_block:".$this->domain_name.":".$call_block_number);
}
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
} }
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle, call_block_number from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
$call_block_numbers[] = $row['call_block_number'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//clear the cache
$cache = new cache;
foreach ($call_block_numbers as $call_block_number) {
$cache->delete("app:call_block:" . $this->domain_name . ":" . $call_block_number);
}
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
} }
}
/** /**
* copy records * Copies one or more records
*/ *
public function copy($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'add')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = uuid();
$array[$this->table][$x]['call_block_description'] = trim($row['call_block_description'].' ('.$text['label-copy'].')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
} }
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = uuid();
$array[$this->table][$x]['call_block_description'] = trim($row['call_block_description'] . ' (' . $text['label-copy'] . ')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
} }
}
/** /**
* add records * Adds one or more records
*/ *
public function add($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'add')) { * 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 add($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//add the checked records
if (is_array($records) && @sizeof($records) != 0) {
//filter checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
} }
}
//add the checked records //get the caller id info from call detail records
if (is_array($records) && @sizeof($records) != 0) { if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select caller_id_name, caller_id_number, caller_destination from v_xml_cdr ";
$sql .= "where xml_cdr_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
unset($sql, $parameters);
}
//filter checked records //get the caller id info from call detail records
foreach ($records as $x => $record) { if (is_uuid($this->domain_uuid)) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) { //get the destination country code
$uuids[] = "'".$record['uuid']."'"; $sql = "select distinct(destination_prefix), ";
} $sql .= "(select count(destination_prefix) from v_destinations where domain_uuid = :domain_uuid and destination_prefix = d.destination_prefix) as count ";
$sql .= "from v_destinations as d ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and destination_prefix <> '' ";
$sql .= "and destination_enabled = true ";
$sql .= "order by count desc limit 1; ";
$parameters['domain_uuid'] = $this->domain_uuid;
$destination_country_code = $this->database->select($sql, $parameters ?? null, 'column');
unset($sql, $parameters);
//use the the destination country code to set the country code
if (!empty($destination_country_code)) {
$destination_country_code = trim($destination_country_code, "+ ");
$country_code = $destination_country_code;
}
}
//get the users that are assigned to the extension
if (!permission_exists('call_block_extension')) {
$sql = "select extension_uuid from v_extension_users ";
$sql .= "where user_uuid = :user_uuid ";
$parameters['user_uuid'] = $this->user_uuid;
$user_extensions = $this->database->select($sql, $parameters ?? null, 'all');
unset($sql, $parameters);
}
//get the country code from default settings
if ($this->settings->get('domain', 'country_code', null) !== null) {
$country_code = $this->settings->get('domain', 'country_code');
}
//loop through records
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//remove e.164 and country code
if (substr($row["caller_id_number"], 0, 1) == "+") {
//format e.164
$call_block_number = str_replace("+" . trim($country_code), "", trim($row["caller_id_number"]));
} elseif (!empty($row["caller_id_number"])) {
//remove the country code if its the first in the string
$call_block_number = ltrim(trim($row["caller_id_number"]), $country_code ?? '');
} else {
$call_block_number = '';
}
//build insert array
if (permission_exists('call_block_extension')) {
$array['call_block'][$x]['call_block_uuid'] = uuid();
$array['call_block'][$x]['domain_uuid'] = $this->domain_uuid;
$array['call_block'][$x]['call_block_direction'] = $this->call_block_direction;
if (is_uuid($this->extension_uuid)) {
$array['call_block'][$x]['extension_uuid'] = $this->extension_uuid;
} }
if ($this->call_block_direction == 'inbound') {
//get the caller id info from call detail records $array['call_block'][$x]['call_block_name'] = '';
if (is_array($uuids) && @sizeof($uuids) != 0) { $array['call_block'][$x]['call_block_country_code'] = trim($country_code ?? '');
$sql = "select caller_id_name, caller_id_number, caller_destination from v_xml_cdr "; $array['call_block'][$x]['call_block_number'] = $call_block_number;
$sql .= "where xml_cdr_uuid in (".implode(', ', $uuids).") "; $array['call_block'][$x]['call_block_description'] = trim($row["caller_id_name"]);
$rows = $this->database->select($sql, $parameters ?? null, 'all');
unset($sql, $parameters);
} }
if ($this->call_block_direction == 'outbound') {
//get the caller id info from call detail records $array['call_block'][$x]['call_block_number'] = trim($row["caller_destination"]);
if (is_uuid($this->domain_uuid)) {
//get the destination country code
$sql = "select distinct(destination_prefix), ";
$sql .= "(select count(destination_prefix) from v_destinations where domain_uuid = :domain_uuid and destination_prefix = d.destination_prefix) as count ";
$sql .= "from v_destinations as d ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and destination_prefix <> '' ";
$sql .= "and destination_enabled = true ";
$sql .= "order by count desc limit 1; ";
$parameters['domain_uuid'] = $this->domain_uuid;
$destination_country_code = $this->database->select($sql, $parameters ?? null, 'column');
unset($sql, $parameters);
//use the the destination country code to set the country code
if (!empty($destination_country_code)) {
$destination_country_code = trim($destination_country_code, "+ ");
$country_code = $destination_country_code;
}
} }
$array['call_block'][$x]['call_block_count'] = 0;
//get the users that are assigned to the extension $array['call_block'][$x]['call_block_app'] = $this->call_block_app;
if (!permission_exists('call_block_extension')) { $array['call_block'][$x]['call_block_data'] = $this->call_block_data;
$sql = "select extension_uuid from v_extension_users "; $array['call_block'][$x]['call_block_enabled'] = true;
$sql .= "where user_uuid = :user_uuid "; $array['call_block'][$x]['date_added'] = time();
$parameters['user_uuid'] = $this->user_uuid; $x++;
$user_extensions = $this->database->select($sql, $parameters ?? null, 'all'); } else {
unset($sql, $parameters); if (is_array($user_extensions)) {
} foreach ($user_extensions as $field) {
if (is_uuid($field['extension_uuid'])) {
//get the country code from default settings $array['call_block'][$x]['call_block_uuid'] = uuid();
if ($this->settings->get('domain', 'country_code', null) !== null) { $array['call_block'][$x]['domain_uuid'] = $this->domain_uuid;
$country_code = $this->settings->get('domain', 'country_code'); $array['call_block'][$x]['call_block_direction'] = $this->call_block_direction;
} $array['call_block'][$x]['extension_uuid'] = $field['extension_uuid'];
if ($this->call_block_direction == 'inbound') {
//loop through records $array['call_block'][$x]['call_block_name'] = '';
if (is_array($rows) && @sizeof($rows) != 0) { $array['call_block'][$x]['call_block_country_code'] = trim($country_code ?? '');
foreach ($rows as $x => $row) { $array['call_block'][$x]['call_block_number'] = $call_block_number;
$array['call_block'][$x]['call_block_description'] = trim($row["caller_id_name"]);
//remove e.164 and country code
if (substr($row["caller_id_number"],0,1) == "+") {
//format e.164
$call_block_number = str_replace("+".trim($country_code), "", trim($row["caller_id_number"]));
} }
elseif (!empty($row["caller_id_number"])) { if ($this->call_block_direction == 'outbound') {
//remove the country code if its the first in the string $array['call_block'][$x]['call_block_number'] = trim($row["caller_destination"]);
$call_block_number = ltrim(trim($row["caller_id_number"]), $country_code ?? '');
}
else {
$call_block_number = '';
}
//build insert array
if (permission_exists('call_block_extension')) {
$array['call_block'][$x]['call_block_uuid'] = uuid();
$array['call_block'][$x]['domain_uuid'] = $this->domain_uuid;
$array['call_block'][$x]['call_block_direction'] = $this->call_block_direction;
if (is_uuid($this->extension_uuid)) {
$array['call_block'][$x]['extension_uuid'] = $this->extension_uuid;
}
if ($this->call_block_direction == 'inbound') {
$array['call_block'][$x]['call_block_name'] = '';
$array['call_block'][$x]['call_block_country_code'] = trim($country_code ?? '');
$array['call_block'][$x]['call_block_number'] = $call_block_number;
$array['call_block'][$x]['call_block_description'] = trim($row["caller_id_name"]);
}
if ($this->call_block_direction == 'outbound') {
$array['call_block'][$x]['call_block_number'] = trim($row["caller_destination"]);
}
$array['call_block'][$x]['call_block_count'] = 0;
$array['call_block'][$x]['call_block_app'] = $this->call_block_app;
$array['call_block'][$x]['call_block_data'] = $this->call_block_data;
$array['call_block'][$x]['call_block_enabled'] = true;
$array['call_block'][$x]['date_added'] = time();
$x++;
}
else {
if (is_array($user_extensions)) {
foreach ($user_extensions as $field) {
if (is_uuid($field['extension_uuid'])) {
$array['call_block'][$x]['call_block_uuid'] = uuid();
$array['call_block'][$x]['domain_uuid'] = $this->domain_uuid;
$array['call_block'][$x]['call_block_direction'] = $this->call_block_direction;
$array['call_block'][$x]['extension_uuid'] = $field['extension_uuid'];
if ($this->call_block_direction == 'inbound') {
$array['call_block'][$x]['call_block_name'] = '';
$array['call_block'][$x]['call_block_country_code'] = trim($country_code ?? '');
$array['call_block'][$x]['call_block_number'] = $call_block_number;
$array['call_block'][$x]['call_block_description'] = trim($row["caller_id_name"]);
}
if ($this->call_block_direction == 'outbound') {
$array['call_block'][$x]['call_block_number'] = trim($row["caller_destination"]);
}
$array['call_block'][$x]['call_block_count'] = 0;
$array['call_block'][$x]['call_block_app'] = $this->call_block_app;
$array['call_block'][$x]['call_block_data'] = $this->call_block_data;
$array['call_block'][$x]['call_block_enabled'] = true;
$array['call_block'][$x]['date_added'] = time();
$x++;
}
}
}
}
}
}
//add records
if (is_array($array) && @sizeof($array) != 0) {
//ensure call block is enabled in the dialplan (build update array)
$sql = "select dialplan_uuid from v_dialplans ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and app_uuid = '".self::app_uuid."' ";
$sql .= "and dialplan_enabled <> true ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters);
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
$array['dialplans'][$x]['dialplan_uuid'] = $row['dialplan_uuid'];
$array['dialplans'][$x]['dialplan_enabled'] = true;
} }
$array['call_block'][$x]['call_block_count'] = 0;
$array['call_block'][$x]['call_block_app'] = $this->call_block_app;
$array['call_block'][$x]['call_block_data'] = $this->call_block_data;
$array['call_block'][$x]['call_block_enabled'] = true;
$array['call_block'][$x]['date_added'] = time();
$x++;
} }
unset($rows, $parameters); }
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
$response = $this->database->message;
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//set message
message::add($text['message-add']);
} }
}
} }
}
//add records
if (is_array($array) && @sizeof($array) != 0) {
//ensure call block is enabled in the dialplan (build update array)
$sql = "select dialplan_uuid from v_dialplans ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and app_uuid = '" . self::app_uuid . "' ";
$sql .= "and dialplan_enabled <> true ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters);
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
$array['dialplans'][$x]['dialplan_uuid'] = $row['dialplan_uuid'];
$array['dialplans'][$x]['dialplan_enabled'] = true;
}
}
unset($rows, $parameters);
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
$response = $this->database->message;
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//set message
message::add($text['message-add']);
}
} }
} //method
} //class }
} //method
} //class

View File

@@ -61,7 +61,15 @@
$broadcast_toll_allow = ''; $broadcast_toll_allow = '';
//function to Upload CSV/TXT file //function to Upload CSV/TXT file
function upload_file($sql, $broadcast_phone_numbers) { /**
* Uploads a file and prepares the SQL query for broadcasting phone numbers.
*
* @param string $sql The initial SQL query.
* @param mixed $broadcast_phone_numbers The phone numbers to broadcast, or an empty value if not applicable.
*
* @return array An array containing the result code ('code') and the prepared SQL query ('sql').
*/
function upload_file($sql, $broadcast_phone_numbers) {
$upload_csv = $sql = ''; $upload_csv = $sql = '';
if (isset($_FILES['broadcast_phone_numbers_file']) && !empty($_FILES['broadcast_phone_numbers_file']) && $_FILES['broadcast_phone_numbers_file']['size'] > 0) { if (isset($_FILES['broadcast_phone_numbers_file']) && !empty($_FILES['broadcast_phone_numbers_file']) && $_FILES['broadcast_phone_numbers_file']['size'] > 0) {
$filename=$_FILES["broadcast_phone_numbers_file"]["tmp_name"]; $filename=$_FILES["broadcast_phone_numbers_file"]["tmp_name"];

View File

@@ -46,6 +46,17 @@
ini_set('max_execution_time',3600); ini_set('max_execution_time',3600);
//define the asynchronous command function //define the asynchronous command function
/**
* Asynchronously executes a command.
*
* This method runs the given $cmd as an asynchronous process. On Windows, it uses
* proc_open to create a new process with pipes for stdin, stdout, and stderr. On
* Posix systems (e.g., Linux, macOS), it uses exec to run the command in the background.
*
* @param string $cmd The command to execute asynchronously.
*
* @return int|bool The return value of proc_close() on Windows or false on failure; null if not executed successfully.
*/
function cmd_async($cmd) { function cmd_async($cmd) {
//windows //windows
if (stristr(PHP_OS, 'WIN')) { if (stristr(PHP_OS, 'WIN')) {

View File

@@ -28,168 +28,189 @@
/** /**
* call broadcast class * call broadcast class
*/ */
class call_broadcast { class call_broadcast {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'call_broadcast'; const app_name = 'call_broadcast';
const app_uuid = 'efc11f6b-ed73-9955-4d4d-3a1bed75a056'; const app_uuid = 'efc11f6b-ed73-9955-4d4d-3a1bed75a056';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
/** /**
* called when the object is created * Initializes the object with the provided settings.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An optional array of settings, defaulting to an empty array.
//set domain and user UUIDs *
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; * @return void
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; */
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign private variables
$this->permission_prefix = 'call_broadcast_';
$this->list_page = 'call_broadcast.php';
$this->table = 'call_broadcasts';
$this->uuid_prefix = 'call_broadcast_';
}
/**
* delete records
*/
public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* copy records
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = uuid();
$array[$this->table][$x]['broadcast_description'] = trim($row['broadcast_description'].' ('.$text['label-copy'].')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign private variables
$this->permission_prefix = 'call_broadcast_';
$this->list_page = 'call_broadcast.php';
$this->table = 'call_broadcasts';
$this->uuid_prefix = 'call_broadcast_';
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = uuid();
$array[$this->table][$x]['broadcast_description'] = trim($row['broadcast_description'] . ' (' . $text['label-copy'] . ')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -60,6 +60,15 @@
} }
//convert the string to a named array //convert the string to a named array
/**
* Converts a string into a named array based on the specified delimiter.
*
* @param string $tmp_str The input string to be converted.
* @param string $tmp_delimiter The delimiter used to split the string and field values.
*
* @return array A 2D array where each inner array represents a row in the original string,
* with keys corresponding to the field names from the first line of the string.
*/
function str_to_named_array($tmp_str, $tmp_delimiter) { function str_to_named_array($tmp_str, $tmp_delimiter) {
$tmp_array = explode ("\n", $tmp_str); $tmp_array = explode ("\n", $tmp_str);
$result = array(); $result = array();

File diff suppressed because it is too large Load Diff

View File

@@ -25,430 +25,459 @@
*/ */
//define the call_flows class //define the call_flows class
class call_flows { class call_flows {
/** /**
* declare public variables * declare public variables
*/ */
public $toggle_field; public $toggle_field;
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'call_flows'; const app_name = 'call_flows';
const app_uuid = 'b1b70f85-6b42-429b-8c5a-60c8b02b7d14'; const app_uuid = 'b1b70f85-6b42-429b-8c5a-60c8b02b7d14';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Constructor for the class.
*/ *
public function __construct(array $setting_array = []) { * This method initializes the object with setting_array and session data.
//set domain and user UUIDs *
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; * @param array $setting_array An optional array of settings to override default values. Defaults to [].
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; */
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign private variables //assign private variables
$this->permission_prefix = 'call_flow_'; $this->permission_prefix = 'call_flow_';
$this->list_page = 'call_flows.php'; $this->list_page = 'call_flows.php';
$this->table = 'call_flows'; $this->table = 'call_flows';
$this->uuid_prefix = 'call_flow_'; $this->uuid_prefix = 'call_flow_';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
} }
/** /**
* delete records * Deletes one or multiple records from the access controls table.
*/ *
public function delete($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'delete')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked call flows, build where clause for below
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//get necessary call flow details
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, dialplan_uuid, call_flow_context from v_" . $this->table . " ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$call_flows[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
$call_flow_contexts[] = $row['call_flow_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
$x = 0;
foreach ($call_flows as $call_flow_uuid => $call_flow) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $call_flow_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplans'][$x]['dialplan_uuid'] = $call_flow['dialplan_uuid'];
$array['dialplans'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplan_details'][$x]['dialplan_uuid'] = $call_flow['dialplan_uuid'];
$array['dialplan_details'][$x]['domain_uuid'] = $this->domain_uuid;
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_delete', 'temp');
$p->add('dialplan_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_delete', 'temp');
$p->delete('dialplan_detail_delete', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
if (is_array($call_flow_contexts) && @sizeof($call_flow_contexts) != 0) {
$call_flow_contexts = array_unique($call_flow_contexts);
$cache = new cache;
foreach ($call_flow_contexts as $call_flow_context) {
$cache->delete("dialplan:" . $call_flow_context);
}
} }
//delete multiple records //clear the destinations session array
if (is_array($records) && @sizeof($records) != 0) { if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
//filter out unchecked call flows, build where clause for below
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//get necessary call flow details
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, dialplan_uuid, call_flow_context from v_".$this->table." ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$call_flows[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
$call_flow_contexts[] = $row['call_flow_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
$x = 0;
foreach ($call_flows as $call_flow_uuid => $call_flow) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $call_flow_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplans'][$x]['dialplan_uuid'] = $call_flow['dialplan_uuid'];
$array['dialplans'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplan_details'][$x]['dialplan_uuid'] = $call_flow['dialplan_uuid'];
$array['dialplan_details'][$x]['domain_uuid'] = $this->domain_uuid;
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_delete', 'temp');
$p->add('dialplan_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_delete', 'temp');
$p->delete('dialplan_detail_delete', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
if (is_array($call_flow_contexts) && @sizeof($call_flow_contexts) != 0) {
$call_flow_contexts = array_unique($call_flow_contexts);
$cache = new cache;
foreach ($call_flow_contexts as $call_flow_context) {
$cache->delete("dialplan:".$call_flow_context);
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete']);
}
unset($records);
} }
//set message
message::add($text['message-delete']);
}
unset($records);
} }
} }
}
/** /**
* toggle records * Toggles the state of one or more records.
*/ *
public function toggle($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'edit')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
//add multi-lingual support * whether the corresponding checkbox was checked for deletion.
$language = new text; *
$text = $language->get(); * @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (!empty($uuids)) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle, ";
$sql .= "dialplan_uuid, call_flow_feature_code, call_flow_context from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (!empty($rows)) {
foreach ($rows as $row) {
$call_flows[$row['uuid']]['state'] = $row['toggle'];
$call_flows[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
$call_flows[$row['uuid']]['call_flow_feature_code'] = $row['call_flow_feature_code'];
$call_flow_contexts[] = $row['call_flow_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($call_flows as $uuid => $call_flow) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $call_flow['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
if ($this->toggle_field == 'call_flow_enabled') {
$array['dialplans'][$x]['dialplan_uuid'] = $call_flow['dialplan_uuid'];
$array['dialplans'][$x]['dialplan_enabled'] = $call_flow['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
}
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
if (is_array($call_flow_contexts) && @sizeof($call_flow_contexts) != 0) {
$call_flow_contexts = array_unique($call_flow_contexts);
$cache = new cache;
foreach ($call_flow_contexts as $call_flow_context) {
$cache->delete("dialplan:" . $call_flow_context);
}
} }
//toggle the checked records //clear the destinations session array
if (is_array($records) && @sizeof($records) != 0) { if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
//get current toggle state
foreach($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (!empty($uuids)) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, ";
$sql .= "dialplan_uuid, call_flow_feature_code, call_flow_context from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (!empty($rows)) {
foreach ($rows as $row) {
$call_flows[$row['uuid']]['state'] = $row['toggle'];
$call_flows[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
$call_flows[$row['uuid']]['call_flow_feature_code'] = $row['call_flow_feature_code'];
$call_flow_contexts[] = $row['call_flow_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($call_flows as $uuid => $call_flow) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $call_flow['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
if ($this->toggle_field == 'call_flow_enabled') {
$array['dialplans'][$x]['dialplan_uuid'] = $call_flow['dialplan_uuid'];
$array['dialplans'][$x]['dialplan_enabled'] = $call_flow['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
}
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
if (is_array($call_flow_contexts) && @sizeof($call_flow_contexts) != 0) {
$call_flow_contexts = array_unique($call_flow_contexts);
$cache = new cache;
foreach ($call_flow_contexts as $call_flow_context) {
$cache->delete("dialplan:".$call_flow_context);
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-toggle']);
}
unset($records);
//toggle the presence
if ($this->toggle_field != 'call_flow_enabled') {
foreach($call_flows as $uuid => $row) {
//prepare the event
$cmd = "sendevent PRESENCE_IN\n";
$cmd .= "proto: flow\n";
$cmd .= "login: ".$row['call_flow_feature_code']."@".$this->domain_name."\n";
$cmd .= "from: ".$row['call_flow_feature_code']."@".$this->domain_name."\n";
$cmd .= "status: Active (1 waiting)\n";
$cmd .= "rpid: unknown\n";
$cmd .= "event_type: presence\n";
$cmd .= "alt_event_type: dialog\n";
$cmd .= "event_count: 1\n";
$cmd .= "unique-id: ".uuid()."\n";
$cmd .= "Presence-Call-Direction: outbound\n";
if ($call_flow['state'] == 'true') {
$cmd .= "answer-state: confirmed\n";
}
else {
$cmd .= "answer-state: terminated\n";
}
//send the event
$switch_result = event_socket::command($cmd);
}
}
unset($call_flows);
} }
//set message
message::add($text['message-toggle']);
}
unset($records);
//toggle the presence
if ($this->toggle_field != 'call_flow_enabled') {
foreach ($call_flows as $uuid => $row) {
//prepare the event
$cmd = "sendevent PRESENCE_IN\n";
$cmd .= "proto: flow\n";
$cmd .= "login: " . $row['call_flow_feature_code'] . "@" . $this->domain_name . "\n";
$cmd .= "from: " . $row['call_flow_feature_code'] . "@" . $this->domain_name . "\n";
$cmd .= "status: Active (1 waiting)\n";
$cmd .= "rpid: unknown\n";
$cmd .= "event_type: presence\n";
$cmd .= "alt_event_type: dialog\n";
$cmd .= "event_count: 1\n";
$cmd .= "unique-id: " . uuid() . "\n";
$cmd .= "Presence-Call-Direction: outbound\n";
if ($call_flow['state'] == 'true') {
$cmd .= "answer-state: confirmed\n";
} else {
$cmd .= "answer-state: terminated\n";
}
//send the event
$switch_result = event_socket::command($cmd);
}
}
unset($call_flows);
} }
} }
}
/** /**
* copy records * Copies one or more records
*/ *
public function copy($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'add')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
} }
}
//copy the checked records //create insert array from existing data
if (is_array($records) && @sizeof($records) != 0) { if (is_array($uuids) && @sizeof($uuids) != 0) {
//get checked records //primary table
foreach($records as $x => $record) { $sql = "select * from v_" . $this->table . " ";
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) { $sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$uuids[] = "'".$record['uuid']."'"; $sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
$new_call_flow_uuid = uuid();
$new_dialplan_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
} }
} }
//create insert array from existing data //copy data
if (is_array($uuids) && @sizeof($uuids) != 0) { $array[$this->table][$x] = $row;
//primary table //overwrite
$sql = "select * from v_".$this->table." "; $array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $new_call_flow_uuid;
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) "; $array[$this->table][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") "; $array[$this->table][$x]['call_flow_description'] = trim($row['call_flow_description'] . ' (' . $text['label-copy'] . ')');
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
$new_call_flow_uuid = uuid();
$new_dialplan_uuid = uuid();
//convert boolean values to a string //call flow dialplan record
foreach($row as $key => $value) { $sql_2 = "select * from v_dialplans where dialplan_uuid = :dialplan_uuid";
if (gettype($value) == 'boolean') { $parameters_2['dialplan_uuid'] = $row['dialplan_uuid'];
$value = $value ? 'true' : 'false'; $dialplan = $this->database->select($sql_2, $parameters_2, 'row');
$row[$key] = $value; if (is_array($dialplan) && @sizeof($dialplan) != 0) {
}
}
//copy data //convert boolean values to a string
$array[$this->table][$x] = $row; foreach ($dialplan as $key => $value) {
if (gettype($value) == 'boolean') {
//overwrite $value = $value ? 'true' : 'false';
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $new_call_flow_uuid; $dialplan[$key] = $value;
$array[$this->table][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$array[$this->table][$x]['call_flow_description'] = trim($row['call_flow_description'].' ('.$text['label-copy'].')');
//call flow dialplan record
$sql_2 = "select * from v_dialplans where dialplan_uuid = :dialplan_uuid";
$parameters_2['dialplan_uuid'] = $row['dialplan_uuid'];
$dialplan = $this->database->select($sql_2, $parameters_2, 'row');
if (is_array($dialplan) && @sizeof($dialplan) != 0) {
//convert boolean values to a string
foreach($dialplan as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$dialplan[$key] = $value;
}
}
//copy data
$array['dialplans'][$x] = $dialplan;
//overwrite
$array['dialplans'][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$dialplan_xml = $dialplan['dialplan_xml'];
$dialplan_xml = str_replace($row['call_flow_uuid'], $new_call_flow_uuid, $dialplan_xml); //replace source call_flow_uuid with new
$dialplan_xml = str_replace($dialplan['dialplan_uuid'], $new_dialplan_uuid, $dialplan_xml); //replace source dialplan_uuid with new
$array['dialplans'][$x]['dialplan_xml'] = $dialplan_xml;
$array['dialplans'][$x]['dialplan_description'] = trim($dialplan['dialplan_description'].' ('.$text['label-copy'].')');
}
unset($sql_2, $parameters_2, $dialplan);
//create call flow context array
$call_flow_contexts = $row['call_flow_context'];
}
} }
unset($sql, $parameters, $rows, $row); }
}
//save the changes and set the message //copy data
if (is_array($array) && @sizeof($array) != 0) { $array['dialplans'][$x] = $dialplan;
//grant temporary permissions //overwrite
$p = permissions::new(); $array['dialplans'][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$p->add('dialplan_add', 'temp'); $dialplan_xml = $dialplan['dialplan_xml'];
$dialplan_xml = str_replace($row['call_flow_uuid'], $new_call_flow_uuid, $dialplan_xml); //replace source call_flow_uuid with new
//save the array $dialplan_xml = str_replace($dialplan['dialplan_uuid'], $new_dialplan_uuid, $dialplan_xml); //replace source dialplan_uuid with new
$array['dialplans'][$x]['dialplan_xml'] = $dialplan_xml;
$this->database->save($array); $array['dialplans'][$x]['dialplan_description'] = trim($dialplan['dialplan_description'] . ' (' . $text['label-copy'] . ')');
unset($array);
//revoke temporary permissions
$p->delete('dialplan_add', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
if (is_array($call_flow_contexts) && @sizeof($call_flow_contexts) != 0) {
$call_flow_contexts = array_unique($call_flow_contexts);
$cache = new cache;
foreach ($call_flow_contexts as $call_flow_context) {
$cache->delete("dialplan:".$call_flow_context);
}
}
//set message
message::add($text['message-copy']);
} }
unset($records); unset($sql_2, $parameters_2, $dialplan);
//create call flow context array
$call_flow_contexts = $row['call_flow_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_add', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
if (is_array($call_flow_contexts) && @sizeof($call_flow_contexts) != 0) {
$call_flow_contexts = array_unique($call_flow_contexts);
$cache = new cache;
foreach ($call_flow_contexts as $call_flow_context) {
$cache->delete("dialplan:" . $call_flow_context);
}
} }
} //set message
} //method message::add($text['message-copy']);
} //class }
unset($records);
}
}
} //method
} //class

View File

@@ -49,6 +49,15 @@
$text = $language->get(); $text = $language->get();
//define the destination_select function //define the destination_select function
/**
* Displays a select input element with options for destinations.
*
* @param string $select_name The name attribute of the select input element.
* @param int $select_value The value to be selected in the select input element.
* @param int $select_default The default value if select_value is empty.
*
* @return void
*/
function destination_select($select_name, $select_value, $select_default) { function destination_select($select_name, $select_value, $select_default) {
if (empty($select_value)) { $select_value = $select_default; } if (empty($select_value)) { $select_value = $select_default; }
echo " <select class='formfld' style='width: 55px;' name='$select_name'>\n"; echo " <select class='formfld' style='width: 55px;' name='$select_name'>\n";

View File

@@ -1,311 +1,334 @@
<?php <?php
/* /*
FusionPBX FusionPBX
Version: MPL 1.1 Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with 1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/ http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis, Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the for the specific language governing rights and limitations under the
License. License.
The Original Code is FusionPBX The Original Code is FusionPBX
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com> Mark J Crane <markjcrane@fusionpbx.com>
Copyright (C) 2010 - 2025 Copyright (C) 2010 - 2025
All Rights Reserved. All Rights Reserved.
Contributor(s): Contributor(s):
Mark J Crane <markjcrane@fusionpbx.com> Mark J Crane <markjcrane@fusionpbx.com>
Luis Daniel Lucio Quiroz <dlucio@okay.com.mx> Luis Daniel Lucio Quiroz <dlucio@okay.com.mx>
Errol Samuels <voiptology@gmail.com> Errol Samuels <voiptology@gmail.com>
*/ */
//define the call_forward class //define the call_forward class
class call_forward { class call_forward {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'call_forward'; const app_name = 'call_forward';
const app_uuid = '19806921-e8ed-dcff-b325-dd3e5da4959d'; const app_uuid = '19806921-e8ed-dcff-b325-dd3e5da4959d';
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
public $domain_uuid; * @var string
*/
public $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
public $domain_name; * @var string
*/
public $domain_name;
/** /**
* declare public variables * declare public variables
*/ */
public $debug; public $debug;
public $extension_uuid; public $extension_uuid;
public $forward_all_destination; public $forward_all_destination;
public $forward_all_enabled; public $forward_all_enabled;
public $accountcode; public $accountcode;
public $outbound_caller_id_name; public $outbound_caller_id_name;
public $outbound_caller_id_number; public $outbound_caller_id_number;
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $extension; private $extension;
private $number_alias; private $number_alias;
private $toll_allow; private $toll_allow;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; * @return void
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; */
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
//assign private variables
$this->toggle_field = 'forward_all_enabled';
$this->toggle_values = ['true', 'false'];
}
public function set() {
//determine whether to update the dial string
$sql = "select * from v_extensions ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and extension_uuid = :extension_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['extension_uuid'] = $this->extension_uuid;
$row = $this->database->select($sql, $parameters, 'row');
if (is_array($row) && @sizeof($row) != 0) {
$this->extension = $row["extension"];
$this->number_alias = $row["number_alias"];
$this->accountcode = $row["accountcode"];
$this->toll_allow = $row["toll_allow"];
$this->outbound_caller_id_name = $row["outbound_caller_id_name"];
$this->outbound_caller_id_number = $row["outbound_caller_id_number"];
}
unset($sql, $parameters, $row);
//build extension update array
$array['extensions'][0]['extension_uuid'] = $this->extension_uuid;
$array['extensions'][0]['forward_all_destination'] = strlen($this->forward_all_destination) != 0 ? $this->forward_all_destination : null;
if (empty($this->forward_all_destination) || $this->forward_all_enabled == "false") {
$array['extensions'][0]['forward_all_enabled'] = 'false';
} else {
$array['extensions'][0]['forward_all_enabled'] = 'true';
}
//grant temporary permissions
$p = permissions::new();
$p->add('extension_add', 'temp');
//execute update
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('extension_add', 'temp');
//delete extension from the cache
$cache = new cache;
$cache->delete(gethostname().":directory:" . $this->extension . "@" . $this->domain_name);
if (!empty($this->number_alias)) {
$cache->delete(gethostname().":directory:" . $this->number_alias . "@" . $this->domain_name);
}
}
/**
* Toggle an array of call_forward records
* @param array $records array of records to toggle
*/
public function toggle(array $records) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: calls.php');
exit;
}
//validate there are records to process
if (count($records) < 1) return;
//check we have permission for this action
if (permission_exists('call_forward')) {
// initialize an empty array
$uuids = [];
$extensions = [];
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//toggle the checked records
if (count($uuids) > 0) {
$sql = "select extension_uuid as uuid, extension, number_alias, ";
$sql .= "call_timeout, do_not_disturb, ";
$sql .= "forward_all_enabled, forward_all_destination, ";
$sql .= "forward_busy_enabled, forward_busy_destination, ";
$sql .= "forward_no_answer_enabled, forward_no_answer_destination, ";
$sql .= $this->toggle_field . " as toggle, follow_me_uuid ";
$sql .= "from v_extensions ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and extension_uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$extensions[$row['uuid']]['extension'] = $row['extension'];
$extensions[$row['uuid']]['number_alias'] = $row['number_alias'];
$extensions[$row['uuid']]['call_timeout'] = $row['call_timeout'];
$extensions[$row['uuid']]['do_not_disturb'] = $row['do_not_disturb'];
$extensions[$row['uuid']]['forward_all_enabled'] = $row['forward_all_enabled'];
$extensions[$row['uuid']]['forward_all_destination'] = $row['forward_all_destination'];
$extensions[$row['uuid']]['forward_busy_enabled'] = $row['forward_busy_enabled'];
$extensions[$row['uuid']]['forward_busy_destination'] = $row['forward_busy_destination'];
$extensions[$row['uuid']]['forward_no_answer_enabled'] = $row['forward_no_answer_enabled'];
$extensions[$row['uuid']]['forward_no_answer_destination'] = $row['forward_no_answer_destination'];
$extensions[$row['uuid']]['state'] = $row['toggle'];
$extensions[$row['uuid']]['follow_me_uuid'] = $row['follow_me_uuid'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($extensions as $uuid => $extension) {
//check destination
$destination_exists = $extension['forward_all_destination'] != '' ? true : false;
//determine new state
$new_state = $extension['state'] == $this->toggle_values[1] && $destination_exists ? $this->toggle_values[0] : $this->toggle_values[1];
//toggle feature
if ($new_state != $extension['state']) {
$array['extensions'][$x]['extension_uuid'] = $uuid;
$array['extensions'][$x][$this->toggle_field] = $new_state;
}
//disable other features
if ($new_state == $this->toggle_values[0]) { //true
$array['extensions'][$x]['do_not_disturb'] = $this->toggle_values[1]; //false
$array['extensions'][$x]['follow_me_enabled'] = $this->toggle_values[1]; //false
if (is_uuid($extension['follow_me_uuid'])) {
$array['follow_me'][$x]['follow_me_uuid'] = $extension['follow_me_uuid'];
$array['follow_me'][$x]['follow_me_enabled'] = $this->toggle_values[1]; //false
}
}
//increment counter
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('extension_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('extension_edit', 'temp');
//send feature event notify to the phone
if ($this->settings->get('device', 'feature_sync', false)) {
foreach ($extensions as $uuid => $extension) {
$feature_event_notify = new feature_event_notify;
$feature_event_notify->domain_name = $this->domain_name;
$feature_event_notify->extension = $extension['extension'];
$feature_event_notify->do_not_disturb = $extension['do_not_disturb'];
$feature_event_notify->ring_count = ceil($extension['call_timeout'] / 6);
$feature_event_notify->forward_all_enabled = $extension['forward_all_enabled'];
$feature_event_notify->forward_busy_enabled = $extension['forward_busy_enabled'];
$feature_event_notify->forward_no_answer_enabled = $extension['forward_no_answer_enabled'];
//workarounds: send 0 as freeswitch doesn't send NOTIFY when destination values are nil
$feature_event_notify->forward_all_destination = $extension['forward_all_destination'] != '' ? $extension['forward_all_destination'] : '0';
$feature_event_notify->forward_busy_destination = $extension['forward_busy_destination'] != '' ? $extension['forward_busy_destination'] : '0';
$feature_event_notify->forward_no_answer_destination = $extension['forward_no_answer_destination'] != '' ? $extension['forward_no_answer_destination'] : '0';
$feature_event_notify->send_notify();
unset($feature_event_notify);
}
}
//synchronize configuration
if (!empty($this->settings->get('switch', 'extensions')) && is_readable($this->settings->get('switch', 'extensions'))) {
$ext = new extension;
$ext->xml();
unset($ext);
}
//clear the cache
$cache = new cache;
foreach ($extensions as $uuid => $extension) {
$cache->delete(gethostname().":directory:" . $extension['extension'] . "@" . $_SESSION['domain_name']);
if ($extension['number_alias'] != '') {
$cache->delete(gethostname().":directory:" . $extension['number_alias'] . "@" . $_SESSION['domain_name']);
}
}
//set message
message::add($text['message-toggle']);
}
unset($records, $extensions, $extension);
}
}
//assign private variables
$this->toggle_field = 'forward_all_enabled';
$this->toggle_values = ['true', 'false'];
} }
/**
* Sets the extension with the provided values.
*
* @return void
*/
public function set() {
//determine whether to update the dial string
$sql = "select * from v_extensions ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and extension_uuid = :extension_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['extension_uuid'] = $this->extension_uuid;
$row = $this->database->select($sql, $parameters, 'row');
if (is_array($row) && @sizeof($row) != 0) {
$this->extension = $row["extension"];
$this->number_alias = $row["number_alias"];
$this->accountcode = $row["accountcode"];
$this->toll_allow = $row["toll_allow"];
$this->outbound_caller_id_name = $row["outbound_caller_id_name"];
$this->outbound_caller_id_number = $row["outbound_caller_id_number"];
}
unset($sql, $parameters, $row);
//build extension update array
$array['extensions'][0]['extension_uuid'] = $this->extension_uuid;
$array['extensions'][0]['forward_all_destination'] = strlen($this->forward_all_destination) != 0 ? $this->forward_all_destination : null;
if (empty($this->forward_all_destination) || $this->forward_all_enabled == "false") {
$array['extensions'][0]['forward_all_enabled'] = 'false';
} else {
$array['extensions'][0]['forward_all_enabled'] = 'true';
}
//grant temporary permissions
$p = permissions::new();
$p->add('extension_add', 'temp');
//execute update
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('extension_add', 'temp');
//delete extension from the cache
$cache = new cache;
$cache->delete(gethostname() . ":directory:" . $this->extension . "@" . $this->domain_name);
if (!empty($this->number_alias)) {
$cache->delete(gethostname() . ":directory:" . $this->number_alias . "@" . $this->domain_name);
}
}
/**
* 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(array $records) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: calls.php');
exit;
}
//validate there are records to process
if (count($records) < 1) return;
//check we have permission for this action
if (permission_exists('call_forward')) {
// initialize an empty array
$uuids = [];
$extensions = [];
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//toggle the checked records
if (count($uuids) > 0) {
$sql = "select extension_uuid as uuid, extension, number_alias, ";
$sql .= "call_timeout, do_not_disturb, ";
$sql .= "forward_all_enabled, forward_all_destination, ";
$sql .= "forward_busy_enabled, forward_busy_destination, ";
$sql .= "forward_no_answer_enabled, forward_no_answer_destination, ";
$sql .= $this->toggle_field . " as toggle, follow_me_uuid ";
$sql .= "from v_extensions ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and extension_uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$extensions[$row['uuid']]['extension'] = $row['extension'];
$extensions[$row['uuid']]['number_alias'] = $row['number_alias'];
$extensions[$row['uuid']]['call_timeout'] = $row['call_timeout'];
$extensions[$row['uuid']]['do_not_disturb'] = $row['do_not_disturb'];
$extensions[$row['uuid']]['forward_all_enabled'] = $row['forward_all_enabled'];
$extensions[$row['uuid']]['forward_all_destination'] = $row['forward_all_destination'];
$extensions[$row['uuid']]['forward_busy_enabled'] = $row['forward_busy_enabled'];
$extensions[$row['uuid']]['forward_busy_destination'] = $row['forward_busy_destination'];
$extensions[$row['uuid']]['forward_no_answer_enabled'] = $row['forward_no_answer_enabled'];
$extensions[$row['uuid']]['forward_no_answer_destination'] = $row['forward_no_answer_destination'];
$extensions[$row['uuid']]['state'] = $row['toggle'];
$extensions[$row['uuid']]['follow_me_uuid'] = $row['follow_me_uuid'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($extensions as $uuid => $extension) {
//check destination
$destination_exists = $extension['forward_all_destination'] != '' ? true : false;
//determine new state
$new_state = $extension['state'] == $this->toggle_values[1] && $destination_exists ? $this->toggle_values[0] : $this->toggle_values[1];
//toggle feature
if ($new_state != $extension['state']) {
$array['extensions'][$x]['extension_uuid'] = $uuid;
$array['extensions'][$x][$this->toggle_field] = $new_state;
}
//disable other features
if ($new_state == $this->toggle_values[0]) { //true
$array['extensions'][$x]['do_not_disturb'] = $this->toggle_values[1]; //false
$array['extensions'][$x]['follow_me_enabled'] = $this->toggle_values[1]; //false
if (is_uuid($extension['follow_me_uuid'])) {
$array['follow_me'][$x]['follow_me_uuid'] = $extension['follow_me_uuid'];
$array['follow_me'][$x]['follow_me_enabled'] = $this->toggle_values[1]; //false
}
}
//increment counter
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('extension_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('extension_edit', 'temp');
//send feature event notify to the phone
if ($this->settings->get('device', 'feature_sync', false)) {
foreach ($extensions as $uuid => $extension) {
$feature_event_notify = new feature_event_notify;
$feature_event_notify->domain_name = $this->domain_name;
$feature_event_notify->extension = $extension['extension'];
$feature_event_notify->do_not_disturb = $extension['do_not_disturb'];
$feature_event_notify->ring_count = ceil($extension['call_timeout'] / 6);
$feature_event_notify->forward_all_enabled = $extension['forward_all_enabled'];
$feature_event_notify->forward_busy_enabled = $extension['forward_busy_enabled'];
$feature_event_notify->forward_no_answer_enabled = $extension['forward_no_answer_enabled'];
//workarounds: send 0 as freeswitch doesn't send NOTIFY when destination values are nil
$feature_event_notify->forward_all_destination = $extension['forward_all_destination'] != '' ? $extension['forward_all_destination'] : '0';
$feature_event_notify->forward_busy_destination = $extension['forward_busy_destination'] != '' ? $extension['forward_busy_destination'] : '0';
$feature_event_notify->forward_no_answer_destination = $extension['forward_no_answer_destination'] != '' ? $extension['forward_no_answer_destination'] : '0';
$feature_event_notify->send_notify();
unset($feature_event_notify);
}
}
//synchronize configuration
if (!empty($this->settings->get('switch', 'extensions')) && is_readable($this->settings->get('switch', 'extensions'))) {
$ext = new extension;
$ext->xml();
unset($ext);
}
//clear the cache
$cache = new cache;
foreach ($extensions as $uuid => $extension) {
$cache->delete(gethostname() . ":directory:" . $extension['extension'] . "@" . $_SESSION['domain_name']);
if ($extension['number_alias'] != '') {
$cache->delete(gethostname() . ":directory:" . $extension['number_alias'] . "@" . $_SESSION['domain_name']);
}
}
//set message
message::add($text['message-toggle']);
}
unset($records, $extensions, $extension);
}
}
}
?> ?>

File diff suppressed because it is too large Load Diff

View File

@@ -110,7 +110,14 @@
//set the default //set the default
if (empty($profile)) { $profile = "default"; } if (empty($profile)) { $profile = "default"; }
//define fucntion get_conference_pin - used to find a unique pin number /**
* Generates a unique pin number for a conference room.
*
* @param int $length The length of the pin number to be generated.
* @param string $conference_room_uuid The UUID of the conference room.
*
* @return string A unique pin number if available, or generates another one recursively until an available one is found.
*/
function get_conference_pin($length, $conference_room_uuid) { function get_conference_pin($length, $conference_room_uuid) {
//set the variable as global //set the variable as global
global $database; global $database;

View File

@@ -26,35 +26,45 @@
*/ */
//define the blf_notify class //define the blf_notify class
class call_center_notify { class call_center_notify {
public $debug; public $debug;
public $domain_name; public $domain_name;
public $agent_name; public $agent_name;
public $answer_state; public $answer_state;
public $agent_uuid; public $agent_uuid;
//feature_event method //feature_event method
public function send_call_center_notify() {
$esl = event_socket::create(); /**
if ($esl->is_connected()) { * Sends a presence notification to the call center.
//send the event *
$event = "sendevent PRESENCE_IN\n"; * This method creates an event socket connection and sends a PRESENCE_IN event
$event .= "proto: agent\n"; * if the connection is established. The event contains information about the agent's
$event .= "event_type: presence\n"; * presence, including their name, domain, unique ID, and answer state.
$event .= "alt_event_type: dialog\n"; *
$event .= "Presence-Call-Direction: outbound\n"; * @return boolean True if the event was successfully sent, false otherwise.
$event .= "state: Active (1 waiting)\n"; */
$event .= "from: agent+".$this->agent_name."@".$this->domain_name."\n"; public function send_call_center_notify() {
$event .= "login: agent+".$this->agent_name."@".$this->domain_name."\n";
$event .= "unique-id: ".$this->agent_uuid."\n";
$event .= "answer-state: ".$this->answer_state."\n";
$esl->request('api ' . $event);
//echo $event."<br />";
}
} //function
} //class $esl = event_socket::create();
if ($esl->is_connected()) {
//send the event
$event = "sendevent PRESENCE_IN\n";
$event .= "proto: agent\n";
$event .= "event_type: presence\n";
$event .= "alt_event_type: dialog\n";
$event .= "Presence-Call-Direction: outbound\n";
$event .= "state: Active (1 waiting)\n";
$event .= "from: agent+" . $this->agent_name . "@" . $this->domain_name . "\n";
$event .= "login: agent+" . $this->agent_name . "@" . $this->domain_name . "\n";
$event .= "unique-id: " . $this->agent_uuid . "\n";
$event .= "answer-state: " . $this->answer_state . "\n";
$esl->request('api ' . $event);
//echo $event."<br />";
}
} //function
} //class
?> ?>

File diff suppressed because it is too large Load Diff

View File

@@ -27,401 +27,441 @@
/** /**
* conference_controls class * conference_controls class
*/ */
class conference_controls { class conference_controls {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'conference_controls'; const app_name = 'conference_controls';
const app_uuid = 'e1ad84a2-79e1-450c-a5b1-7507a043e048'; const app_uuid = 'e1ad84a2-79e1-450c-a5b1-7507a043e048';
/** /**
* declare private variables * declare private variables
*/ */
private $database; private $database;
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $description_field; private $description_field;
private $location; private $location;
/** /**
* declare public variables * declare public variables
*/ */
public $conference_control_uuid; public $conference_control_uuid;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set objects * an empty array.
$this->database = $setting_array['database'] ?? database::new(); *
} * @return void
*/
/** public function __construct(array $setting_array = []) {
* delete rows from the database //set objects
*/ $this->database = $setting_array['database'] ?? database::new();
public function delete($records) {
//assign the variables
$this->name = 'conference_control';
$this->table = 'conference_controls';
$this->location = 'conference_controls.php';
if (permission_exists($this->name.'_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
$array['conference_control_details'][$x][$this->name.'_uuid'] = $record['uuid'];
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_control_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_control_detail_delete', 'temp');
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
public function delete_details($records) {
//assign the variables
$this->name = 'conference_control_detail';
$this->table = 'conference_control_details';
$this->location = 'conference_control_edit.php?id='.$this->conference_control_uuid;
if (permission_exists($this->name.'_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate('/app/conference_controls/conference_control_details.php')) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
}
//increment the id
$x++;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle a field between two values
*/
public function toggle($records) {
//assign the variables
$this->name = 'conference_control';
$this->table = 'conference_controls';
$this->toggle_field = 'control_enabled';
$this->toggle_values = ['true','false'];
$this->location = 'conference_controls.php';
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
public function toggle_details($records) {
//assign the variables
$this->name = 'conference_control_detail';
$this->table = 'conference_control_details';
$this->toggle_field = 'control_enabled';
$this->toggle_values = ['true','false'];
$this->location = 'conference_control_edit.php?id='.$this->conference_control_uuid;
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate('/app/conference_controls/conference_control_details.php')) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
if (!empty($states) && is_array($states) && @sizeof($states) != 0) {
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
}
//save the changes
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy rows from the database
*/
public function copy($records) {
//assign the variables
$this->name = 'conference_control';
$this->table = 'conference_controls';
$this->description_field = 'control_description';
$this->location = 'conference_controls.php';
if (permission_exists($this->name.'_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name.'_uuid'] = $primary_uuid;
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '').' ('.$text['label-copy'].')';
//details sub table
$sql_2 = "select * from v_conference_control_details where conference_control_uuid = :conference_control_uuid";
$parameters_2['conference_control_uuid'] = $row['conference_control_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
}
//copy data
$array['conference_control_details'][$y] = $row_2;
//overwrite
$array['conference_control_details'][$y]['conference_control_detail_uuid'] = uuid();
$array['conference_control_details'][$y]['conference_control_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2); }
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
} }
/**
* Deletes one or 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 delete($records) {
//assign the variables
$this->name = 'conference_control';
$this->table = 'conference_controls';
$this->location = 'conference_controls.php';
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
$array['conference_control_details'][$x][$this->name . '_uuid'] = $record['uuid'];
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_control_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_control_detail_delete', 'temp');
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Deletes conference control details.
*
* @param array $records An array of records to delete, where each record contains a 'checked' key with value 'true'.
*
* @return void
*/
public function delete_details($records) {
//assign the variables
$this->name = 'conference_control_detail';
$this->table = 'conference_control_details';
$this->location = 'conference_control_edit.php?id=' . $this->conference_control_uuid;
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate('/app/conference_controls/conference_control_details.php')) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
}
//increment the id
$x++;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
//assign the variables
$this->name = 'conference_control';
$this->table = 'conference_controls';
$this->toggle_field = 'control_enabled';
$this->toggle_values = ['true', 'false'];
$this->location = 'conference_controls.php';
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* 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_details($records) {
//assign the variables
$this->name = 'conference_control_detail';
$this->table = 'conference_control_details';
$this->toggle_field = 'control_enabled';
$this->toggle_values = ['true', 'false'];
$this->location = 'conference_control_edit.php?id=' . $this->conference_control_uuid;
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate('/app/conference_controls/conference_control_details.php')) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
if (!empty($states) && is_array($states) && @sizeof($states) != 0) {
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
}
//save the changes
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
//assign the variables
$this->name = 'conference_control';
$this->table = 'conference_controls';
$this->description_field = 'control_description';
$this->location = 'conference_controls.php';
if (permission_exists($this->name . '_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name . '_uuid'] = $primary_uuid;
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '') . ' (' . $text['label-copy'] . ')';
//details sub table
$sql_2 = "select * from v_conference_control_details where conference_control_uuid = :conference_control_uuid";
$parameters_2['conference_control_uuid'] = $row['conference_control_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach ($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
}
//copy data
$array['conference_control_details'][$y] = $row_2;
//overwrite
$array['conference_control_details'][$y]['conference_control_detail_uuid'] = uuid();
$array['conference_control_details'][$y]['conference_control_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -27,405 +27,442 @@
/** /**
* conference_profiles class * conference_profiles class
*/ */
class conference_profiles { class conference_profiles {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'conference_profiles'; const app_name = 'conference_profiles';
const app_uuid = 'c33e2c2a-847f-44c1-8c0d-310df5d65ba9'; const app_uuid = 'c33e2c2a-847f-44c1-8c0d-310df5d65ba9';
/** /**
* declare private variables * declare private variables
*/ */
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $description_field; private $description_field;
private $location; private $location;
private $database; private $database;
/** /**
* declare public variables * declare public variables
*/ */
public $conference_profile_uuid; public $conference_profile_uuid;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set objects * an empty array.
$this->database = $setting_array['database'] ?? database::new(); *
} * @return void
*/
public function __construct(array $setting_array = []) {
//set objects
$this->database = $setting_array['database'] ?? database::new();
}
/** /**
* delete rows from the database * Deletes one or more records.
*/ *
public function delete($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 //assign the variables
$this->name = 'conference_profile'; $this->name = 'conference_profile';
$this->table = 'conference_profiles'; $this->table = 'conference_profiles';
$this->location = 'conference_profiles.php'; $this->location = 'conference_profiles.php';
if (permission_exists($this->name.'_delete')) { if (permission_exists($this->name . '_delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
$array['conference_profile_params'][$x][$this->name . '_uuid'] = $record['uuid'];
} }
//delete multiple records //increment the id
if (is_array($records) && @sizeof($records) != 0) { $x++;
//build the delete array }
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
$array['conference_profile_params'][$x][$this->name.'_uuid'] = $record['uuid'];
}
//increment the id //delete the checked rows
$x++; if (is_array($array) && @sizeof($array) != 0) {
}
//delete the checked rows //grant temporary permissions
if (is_array($array) && @sizeof($array) != 0) { $p = permissions::new();
$p->add('conference_profile_param_delete', 'temp');
//grant temporary permissions //execute delete
$p = permissions::new(); $this->database->delete($array);
$p->add('conference_profile_param_delete', 'temp'); unset($array);
//execute delete //revoke temporary permissions
$this->database->delete($array); $p->delete('conference_profile_param_delete', 'temp');
unset($array);
//revoke temporary permissions //set message
$p->delete('conference_profile_param_delete', 'temp'); message::add($text['message-delete']);
}
//set message unset($records);
message::add($text['message-delete']);
}
unset($records);
}
} }
} }
}
public function delete_params($records) { /**
* Deletes multiple parameters from the conference profile.
*
* @param array $records An array of records to delete, where each record contains a 'checked' key with value 'true' and an 'uuid' key containing the UUID of the parameter to be deleted.
*
* @return void
*/
public function delete_params($records) {
//assign the variables //assign the variables
$this->name = 'conference_profile_param'; $this->name = 'conference_profile_param';
$this->table = 'conference_profile_params'; $this->table = 'conference_profile_params';
$this->location = 'conference_profile_edit.php?id='.$this->conference_profile_uuid; $this->location = 'conference_profile_edit.php?id=' . $this->conference_profile_uuid;
if (permission_exists($this->name.'_delete')) { if (permission_exists($this->name . '_delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate('/app/conference_profiles/conference_profile_params.php')) { if (!$token->validate('/app/conference_profiles/conference_profile_params.php')) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//delete multiple records
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
} }
//delete multiple records //increment the id
if (!empty($records) && is_array($records) && @sizeof($records) != 0) { $x++;
//build the delete array }
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
}
//increment the id //delete the checked rows
$x++; if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
} //execute delete
$this->database->delete($array);
unset($array);
//delete the checked rows //set message
if (!empty($array) && is_array($array) && @sizeof($array) != 0) { message::add($text['message-delete']);
//execute delete }
$this->database->delete($array); unset($records);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
} }
} }
}
/** /**
* toggle a field between two values * Toggles the state of one or more records.
*/ *
public function toggle($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
* 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 //assign the variables
$this->name = 'conference_profile'; $this->name = 'conference_profile';
$this->table = 'conference_profiles'; $this->table = 'conference_profiles';
$this->toggle_field = 'profile_enabled'; $this->toggle_field = 'profile_enabled';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
$this->location = 'conference_profiles.php'; $this->location = 'conference_profiles.php';
if (permission_exists($this->name.'_edit')) { if (permission_exists($this->name . '_edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
} }
}
//toggle the checked records if (is_array($uuids) && @sizeof($uuids) != 0) {
if (is_array($records) && @sizeof($records) != 0) { $sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
//get current toggle state $sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
foreach($records as $record) { $rows = $this->database->select($sql, $parameters ?? null, 'all');
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) { if (is_array($rows) && @sizeof($rows) != 0) {
$uuids[] = "'".$record['uuid']."'"; foreach ($rows as $row) {
} $states[$row['uuid']] = $row['toggle'];
} }
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
} }
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
} }
} }
}
public function toggle_params($records) { /**
* Toggles the enabled state of multiple parameters in a conference profile.
*
* @param array $records An array of records to toggle, where each record contains a 'checked' key with value 'true' and an 'uuid' key containing the UUID of the parameter to be toggled.
*
* @return void
*/
public function toggle_params($records) {
//assign the variables //assign the variables
$this->name = 'conference_profile_param'; $this->name = 'conference_profile_param';
$this->table = 'conference_profile_params'; $this->table = 'conference_profile_params';
$this->toggle_field = 'profile_param_enabled'; $this->toggle_field = 'profile_param_enabled';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
$this->location = 'conference_profile_edit.php?id='.$this->conference_profile_uuid; $this->location = 'conference_profile_edit.php?id=' . $this->conference_profile_uuid;
if (permission_exists($this->name.'_edit')) { if (permission_exists($this->name . '_edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate('/app/conference_profiles/conference_profile_params.php')) { if (!$token->validate('/app/conference_profiles/conference_profile_params.php')) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//toggle the checked records
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
} }
}
//toggle the checked records if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
if (!empty($records) && is_array($records) && @sizeof($records) != 0) { $sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
//get current toggle state $sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
foreach ($records as $record) { $rows = $this->database->select($sql, $parameters ?? null, 'all');
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) { if (is_array($rows) && @sizeof($rows) != 0) {
$uuids[] = "'".$record['uuid']."'"; foreach ($rows as $row) {
} $states[$row['uuid']] = $row['toggle'];
} }
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
if (!empty($states) && is_array($states) && @sizeof($states) != 0) {
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
}
//save the changes
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
} }
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
if (!empty($states) && is_array($states) && @sizeof($states) != 0) {
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
}
//save the changes
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
} }
} }
}
/** /**
* copy rows from the database * Copies one or more records
*/ *
public function copy($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
* 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 //assign the variables
$this->name = 'conference_profile'; $this->name = 'conference_profile';
$this->table = 'conference_profiles'; $this->table = 'conference_profiles';
$this->description_field = 'profile_description'; $this->description_field = 'profile_description';
$this->location = 'conference_profiles.php'; $this->location = 'conference_profiles.php';
if (permission_exists($this->name.'_add')) { if (permission_exists($this->name . '_add')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
} }
}
//copy the checked records //create the array from existing data
if (is_array($records) && @sizeof($records) != 0) { if (is_array($uuids) && @sizeof($uuids) != 0) {
//get checked records //primary table
foreach($records as $record) { $sql = "select * from v_" . $this->table . " ";
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) { $sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$uuids[] = "'".$record['uuid']."'"; $rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
} }
} }
//create the array from existing data //copy data
if (is_array($uuids) && @sizeof($uuids) != 0) { $array[$this->table][$x] = $row;
//primary table //add copy to the description
$sql = "select * from v_".$this->table." "; $array[$this->table][$x][$this->name . '_uuid'] = $primary_uuid;
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") "; $array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '') . ' (' . $text['label-copy'] . ')';
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string //params sub table
foreach($row as $key => $value) { $sql_2 = "select * from v_conference_profile_params where conference_profile_uuid = :conference_profile_uuid";
if (gettype($value) == 'boolean') { $parameters_2['conference_profile_uuid'] = $row['conference_profile_uuid'];
$value = $value ? 'true' : 'false'; $rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
$row[$key] = $value; if (is_array($rows_2) && @sizeof($rows_2) != 0) {
} foreach ($rows_2 as $row_2) {
}
//copy data //convert boolean values to a string
$array[$this->table][$x] = $row; foreach ($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
//add copy to the description $value = $value ? 'true' : 'false';
$array[$this->table][$x][$this->name.'_uuid'] = $primary_uuid; $row_2[$key] = $value;
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '').' ('.$text['label-copy'].')';
//params sub table
$sql_2 = "select * from v_conference_profile_params where conference_profile_uuid = :conference_profile_uuid";
$parameters_2['conference_profile_uuid'] = $row['conference_profile_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
}
//copy data
$array['conference_profile_params'][$y] = $row_2;
//overwrite
$array['conference_profile_params'][$y]['conference_profile_param_uuid'] = uuid();
$array['conference_profile_params'][$y]['conference_profile_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
} }
} }
unset($sql, $parameters, $rows, $row);
//copy data
$array['conference_profile_params'][$y] = $row_2;
//overwrite
$array['conference_profile_params'][$y]['conference_profile_param_uuid'] = uuid();
$array['conference_profile_params'][$y]['conference_profile_uuid'] = $primary_uuid;
//increment
$y++;
}
} }
unset($sql_2, $parameters_2, $rows_2, $row_2);
//save the changes and set the message }
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_profile_param_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_profile_param_add', 'temp');
//set message
message::add($text['message-copy']);
}
unset($records);
} }
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_profile_param_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_profile_param_add', 'temp');
//set message
message::add($text['message-copy']);
}
unset($records);
} }
} }
} }
}

View File

@@ -25,396 +25,426 @@
*/ */
//define the conferences class //define the conferences class
class conferences { class conferences {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'conferences'; const app_name = 'conferences';
const app_uuid = 'b81412e8-7253-91f4-e48e-42fc2c9a38d9'; const app_uuid = 'b81412e8-7253-91f4-e48e-42fc2c9a38d9';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/**
* User 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 * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
*/ * the session global array
private $user_uuid; *
* @var string
/** */
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array private $user_uuid;
* @var string
*/ /**
private $domain_uuid; * 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 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
* @var string */
*/ private $domain_uuid;
private $domain_name;
/**
/** * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* declare private variables * in the session global array
*/ *
private $permission_prefix; * @var string
private $list_page; */
private $table; private $domain_name;
private $uuid_prefix;
private $toggle_field; /**
private $toggle_values; * declare private variables
*/
/** private $permission_prefix;
* called when the object is created private $list_page;
*/ private $table;
public function __construct(array $setting_array = []) { private $uuid_prefix;
//set domain and user UUIDs private $toggle_field;
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; private $toggle_values;
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; /**
* Initializes the object with setting array.
//set objects *
$this->database = $setting_array['database'] ?? database::new(); * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
* an empty array.
//assign private variables *
$this->permission_prefix = 'conference_'; * @return void
$this->list_page = 'conferences.php'; */
$this->table = 'conferences'; public function __construct(array $setting_array = []) {
$this->uuid_prefix = 'conference_'; //set domain and user UUIDs
$this->toggle_field = 'conference_enabled'; $this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->toggle_values = ['true','false']; $this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
} $this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
/** //set objects
* delete records $this->database = $setting_array['database'] ?? database::new();
*/
public function delete($records) { //assign private variables
if (permission_exists($this->permission_prefix.'delete')) { $this->permission_prefix = 'conference_';
$this->list_page = 'conferences.php';
//add multi-lingual support $this->table = 'conferences';
$language = new text; $this->uuid_prefix = 'conference_';
$text = $language->get(); $this->toggle_field = 'conference_enabled';
$this->toggle_values = ['true', 'false'];
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
//get the dialplan uuid
$sql = "select dialplan_uuid from v_conferences ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and conference_uuid = :conference_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['conference_uuid'] = $record['uuid'];
$dialplan_uuid = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//build array
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['conference_users'][$x]['conference_uuid'] = $record['uuid'];
$array['conference_users'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplans'][$x]['dialplan_uuid'] = $dialplan_uuid;
$array['dialplans'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplan_details'][$x]['dialplan_uuid'] = $dialplan_uuid;
$array['dialplan_details'][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_user_delete', 'temp');
$p->add('dialplan_detail_delete', 'temp');
$p->add('dialplan_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_user_delete', 'temp');
$p->delete('dialplan_detail_delete', 'temp');
$p->delete('dialplan_delete', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
$cache = new cache;
$cache->delete("dialplan:".$this->domain_name);
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle records
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, dialplan_uuid from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$conferences[$row['uuid']]['state'] = $row['toggle'];
$conferences[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($conferences as $uuid => $conference) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $conference['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$array['dialplans'][$x]['dialplan_uuid'] = $conference['dialplan_uuid'];
$array['dialplans'][$x]['dialplan_enabled'] = $conference['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
$cache = new cache;
$cache->delete("dialplan:".$this->domain_name);
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy records
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$new_conference_uuid = uuid();
$new_dialplan_uuid = uuid();
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $new_conference_uuid;
$array[$this->table][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$array[$this->table][$x]['conference_description'] = trim($row['conference_description'].' ('.$text['label-copy'].')');
//conference users sub table
$sql_2 = "select * from v_conference_users ";
$sql_2 .= "where conference_uuid = :conference_uuid ";
$sql_2 .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters_2['conference_uuid'] = $row['conference_uuid'];
$parameters_2['domain_uuid'] = $this->domain_uuid;
$conference_users = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($conference_users) && @sizeof($conference_users) != 0) {
foreach ($conference_users as $conference_user) {
//convert boolean values to a string
foreach($conference_user as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$conference_user[$key] = $value;
}
}
//copy data
$array['conference_users'][$y] = $conference_user;
//overwrite
$array['conference_users'][$y]['conference_user_uuid'] = uuid();
$array['conference_users'][$y]['conference_uuid'] = $new_conference_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $conference_users, $conference_user);
//conference dialplan record
$sql_3 = "select * from v_dialplans where dialplan_uuid = :dialplan_uuid";
$parameters_3['dialplan_uuid'] = $row['dialplan_uuid'];
$dialplan = $this->database->select($sql_3, $parameters_3, 'row');
if (is_array($dialplan) && @sizeof($dialplan) != 0) {
//convert boolean values to a string
foreach($dialplan as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$dialplan[$key] = $value;
}
}
//copy data
$array['dialplans'][$x] = $dialplan;
//overwrite
$array['dialplans'][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$dialplan_xml = $dialplan['dialplan_xml'];
$dialplan_xml = str_replace($row['conference_uuid'], $new_conference_uuid, $dialplan_xml); //replace source conference_uuid with new
$dialplan_xml = str_replace($dialplan['dialplan_uuid'], $new_dialplan_uuid, $dialplan_xml); //replace source dialplan_uuid with new
$array['dialplans'][$x]['dialplan_xml'] = $dialplan_xml;
$array['dialplans'][$x]['dialplan_description'] = trim($dialplan['dialplan_description'].' ('.$text['label-copy'].')');
}
unset($sql_3, $parameters_3, $dialplan);
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_user_add', 'temp');
$p->add('dialplan_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_user_add', 'temp');
$p->delete('dialplan_add', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
$cache = new cache;
$cache->delete("dialplan:".$this->domain_name);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
//get the dialplan uuid
$sql = "select dialplan_uuid from v_conferences ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and conference_uuid = :conference_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['conference_uuid'] = $record['uuid'];
$dialplan_uuid = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//build array
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['conference_users'][$x]['conference_uuid'] = $record['uuid'];
$array['conference_users'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplans'][$x]['dialplan_uuid'] = $dialplan_uuid;
$array['dialplans'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplan_details'][$x]['dialplan_uuid'] = $dialplan_uuid;
$array['dialplan_details'][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_user_delete', 'temp');
$p->add('dialplan_detail_delete', 'temp');
$p->add('dialplan_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_user_delete', 'temp');
$p->delete('dialplan_detail_delete', 'temp');
$p->delete('dialplan_delete', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
$cache = new cache;
$cache->delete("dialplan:" . $this->domain_name);
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle, dialplan_uuid from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$conferences[$row['uuid']]['state'] = $row['toggle'];
$conferences[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($conferences as $uuid => $conference) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $conference['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$array['dialplans'][$x]['dialplan_uuid'] = $conference['dialplan_uuid'];
$array['dialplans'][$x]['dialplan_enabled'] = $conference['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
$cache = new cache;
$cache->delete("dialplan:" . $this->domain_name);
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$new_conference_uuid = uuid();
$new_dialplan_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $new_conference_uuid;
$array[$this->table][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$array[$this->table][$x]['conference_description'] = trim($row['conference_description'] . ' (' . $text['label-copy'] . ')');
//conference users sub table
$sql_2 = "select * from v_conference_users ";
$sql_2 .= "where conference_uuid = :conference_uuid ";
$sql_2 .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters_2['conference_uuid'] = $row['conference_uuid'];
$parameters_2['domain_uuid'] = $this->domain_uuid;
$conference_users = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($conference_users) && @sizeof($conference_users) != 0) {
foreach ($conference_users as $conference_user) {
//convert boolean values to a string
foreach ($conference_user as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$conference_user[$key] = $value;
}
}
//copy data
$array['conference_users'][$y] = $conference_user;
//overwrite
$array['conference_users'][$y]['conference_user_uuid'] = uuid();
$array['conference_users'][$y]['conference_uuid'] = $new_conference_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $conference_users, $conference_user);
//conference dialplan record
$sql_3 = "select * from v_dialplans where dialplan_uuid = :dialplan_uuid";
$parameters_3['dialplan_uuid'] = $row['dialplan_uuid'];
$dialplan = $this->database->select($sql_3, $parameters_3, 'row');
if (is_array($dialplan) && @sizeof($dialplan) != 0) {
//convert boolean values to a string
foreach ($dialplan as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$dialplan[$key] = $value;
}
}
//copy data
$array['dialplans'][$x] = $dialplan;
//overwrite
$array['dialplans'][$x]['dialplan_uuid'] = $new_dialplan_uuid;
$dialplan_xml = $dialplan['dialplan_xml'];
$dialplan_xml = str_replace($row['conference_uuid'], $new_conference_uuid, $dialplan_xml); //replace source conference_uuid with new
$dialplan_xml = str_replace($dialplan['dialplan_uuid'], $new_dialplan_uuid, $dialplan_xml); //replace source dialplan_uuid with new
$array['dialplans'][$x]['dialplan_xml'] = $dialplan_xml;
$array['dialplans'][$x]['dialplan_description'] = trim($dialplan['dialplan_description'] . ' (' . $text['label-copy'] . ')');
}
unset($sql_3, $parameters_3, $dialplan);
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('conference_user_add', 'temp');
$p->add('dialplan_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('conference_user_add', 'temp');
$p->delete('dialplan_add', 'temp');
//apply settings reminder
$_SESSION["reload_xml"] = true;
//clear the cache
$cache = new cache;
$cache->delete("dialplan:" . $this->domain_name);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -143,6 +143,13 @@
} }
//define an alternative kick all //define an alternative kick all
/**
* Ends a conference by killing all its members and destroying the session.
*
* @param string $name The name of the conference to end.
*
* @return void
*/
function conference_end($name) { function conference_end($name) {
$switch_cmd = "conference '".$name."' xml_list"; $switch_cmd = "conference '".$name."' xml_list";
$xml_str = trim(event_socket::api($switch_cmd)); $xml_str = trim(event_socket::api($switch_cmd));

View File

@@ -236,6 +236,20 @@
//define the array _difference function //define the array _difference function
//this adds old and new values to the array //this adds old and new values to the array
/**
* Calculates the difference between two arrays.
*
* This function recursively iterates through both input arrays, comparing each key-value pair. If a value in $array2 is not present in $array1,
* it is marked as 'new' in the returned array. If a value in $array1 is not present in $array2, it is also included in the returned array with a marker
* indicating its origin.
*
* The function handles nested arrays by recursively calling itself for matching keys.
*
* @param mixed[] $array1 The first input array to compare.
* @param mixed[] $array2 The second input array to compare.
*
* @return mixed[] An array containing the differences between the two input arrays, with added markers indicating origin.
*/
function array_difference($array1, $array2) { function array_difference($array1, $array2) {
$array = array(); $array = array();
if (is_array($array1)) { if (is_array($array1)) {

View File

@@ -36,7 +36,9 @@ class database_transactions {
/** /**
* Removes old entries for in the database database_transactions table * Removes old entries for in the database database_transactions table
* see {@link https://github.com/fusionpbx/fusionpbx-app-maintenance/} FusionPBX Maintenance App * see {@link https://github.com/fusionpbx/fusionpbx-app-maintenance/} FusionPBX Maintenance App
*
* @param settings $settings Settings object * @param settings $settings Settings object
*
* @return void * @return void
*/ */
public static function database_maintenance(settings $settings): void { public static function database_maintenance(settings $settings): void {

View File

@@ -73,6 +73,17 @@
$available_columns[] = 'destination_order'; $available_columns[] = 'destination_order';
//define the functions //define the functions
/**
* Converts an associative or numerical array into a CSV string.
*
* This function takes an array and returns its contents as a properly formatted
* CSV string. If the input array is empty, it will return null.
*
* @param array $array The array to be converted into a CSV string.
* It can be either an associative or numerical array.
*
* @return string A CSV string representation of the input array, or null if the array is empty.
*/
function array2csv(array &$array) { function array2csv(array &$array) {
if (count($array) == 0) { if (count($array) == 0) {
return null; return null;
@@ -87,6 +98,17 @@
return ob_get_clean(); return ob_get_clean();
} }
/**
* Sends HTTP headers for a file download.
*
* This function sends the necessary HTTP headers to force the browser to download
* a file instead of displaying it in the browser. The filename specified should be
* a path to the file on the server, not a URL.
*
* @param string $filename The name and path to the file that will be downloaded by the client.
*
* @return void This function does not return anything.
*/
function download_send_headers($filename) { function download_send_headers($filename) {
// disable caching // disable caching
$now = gmdate("D, d M Y H:i:s"); $now = gmdate("D, d M Y H:i:s");

View File

@@ -38,18 +38,6 @@
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//built in str_getcsv requires PHP 5.3 or higher, this function can be used to reproduct the functionality but requirs PHP 5.1.0 or higher
if(!function_exists('str_getcsv')) {
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
$fp = fopen("php://memory", 'r+');
fputs($fp, $input);
rewind($fp);
$data = fgetcsv($fp, null, $delimiter, $enclosure); // $escape only got added in 5.3.0
fclose($fp);
return $data;
}
}
//get the http get values and set them as php variables //get the http get values and set them as php variables
$action = $_POST["action"] ?? null; $action = $_POST["action"] ?? null;
$from_row = $_POST["from_row"] ?? null; $from_row = $_POST["from_row"] ?? null;
@@ -132,6 +120,14 @@
} }
//get the parent table //get the parent table
/**
* Retrieves the parent table of a given table in a database schema.
*
* @param array $schema Database schema containing table information
* @param string $table_name Name of the table for which to retrieve the parent
*
* @return mixed Parent table name, or null if no matching table is found
*/
function get_parent($schema,$table_name) { function get_parent($schema,$table_name) {
foreach ($schema as $row) { foreach ($schema as $row) {
if ($row['table'] == $table_name) { if ($row['table'] == $table_name) {

View File

@@ -79,6 +79,14 @@
$destination_array = $destination->all('dialplan'); $destination_array = $destination->all('dialplan');
//function to return the action names in the order defined //function to return the action names in the order defined
/**
* Returns a list of actions based on the provided destination array and actions.
*
* @param array $destination_array The array containing the data to process.
* @param array $destination_actions The array of actions to apply to the destination array.
*
* @return array A list of actions resulting from the processing of the destination array and actions.
*/
function action_name($destination_array, $destination_actions) { function action_name($destination_array, $destination_actions) {
global $settings; global $settings;
$actions = []; $actions = [];
@@ -175,8 +183,8 @@
$page = $_GET['page']; $page = $_GET['page'];
} }
if (!isset($page)) { $page = 0; $_GET['page'] = 0; } if (!isset($page)) { $page = 0; $_GET['page'] = 0; }
list($paging_controls, $rows_per_page) = paging($num_rows, $param, $rows_per_page); [$paging_controls, $rows_per_page] = paging($num_rows, $param, $rows_per_page);
list($paging_controls_mini, $rows_per_page) = paging($num_rows, $param, $rows_per_page, true); [$paging_controls_mini, $rows_per_page] = paging($num_rows, $param, $rows_per_page, true);
$offset = $rows_per_page * $page; $offset = $rows_per_page * $page;
//get the list //get the list

View File

@@ -51,6 +51,21 @@
$label_required = $text['label-required']; $label_required = $text['label-required'];
//define the functions //define the functions
/**
* Converts a multi-dimensional array to CSV format.
*
* This function assumes that the input array is a collection of devices,
* where each device has an array of columns. The function will take all
* column headers from all devices and use them as the header row in the
* generated CSV file.
*
* If any duplicate column headers are found, they will be removed by
* truncating at the pipe character (|).
*
* @param array &$array A multi-dimensional array of device data.
*
* @return string The CSV formatted data as a string. Returns null if the input array is empty.
*/
function array2csv(array &$array) { function array2csv(array &$array) {
if (count($array) == 0) { if (count($array) == 0) {
return null; return null;
@@ -86,6 +101,15 @@
return ob_get_clean(); return ob_get_clean();
} }
/**
* Sends HTTP headers to force a file download.
*
* This function sets various HTTP headers to instruct the browser to download the file instead of displaying it in the browser window.
*
* @param string $filename The filename to use for the downloaded file.
*
* @return void No return value. This function only sends HTTP headers and does not generate any output.
*/
function download_send_headers($filename) { function download_send_headers($filename) {
// disable caching // disable caching
$now = gmdate("D, d M Y H:i:s"); $now = gmdate("D, d M Y H:i:s");

View File

@@ -38,18 +38,6 @@
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//built in str_getcsv requires PHP 5.3 or higher, this function can be used to reproduct the functionality but requirs PHP 5.1.0 or higher
if (!function_exists('str_getcsv')) {
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
$fp = fopen("php://memory", 'r+');
fputs($fp, $input);
rewind($fp);
$data = fgetcsv($fp, null, $delimiter, $enclosure, $escape);
fclose($fp);
return $data;
}
}
//set the max php execution time //set the max php execution time
ini_set('max_execution_time',7200); ini_set('max_execution_time',7200);
@@ -225,7 +213,15 @@
} }
//get the parent table //get the parent table
function get_parent($schema,$table_name) { /**
* Retrieves the parent table name for a given table in the schema.
*
* @param array $schema An associative array of schema definitions
* @param string $table_name The name of the table to retrieve the parent for
*
* @return string|null The parent table name if found, otherwise null
*/
function get_parent($schema, $table_name) {
foreach ($schema as $row) { foreach ($schema as $row) {
if ($row['table'] == $table_name) { if ($row['table'] == $table_name) {
return $row['parent']; return $row['parent'];

File diff suppressed because it is too large Load Diff

View File

@@ -44,8 +44,10 @@
//declared functions //declared functions
/** /**
* Checks if a dialplan detail record is marked for deletion * Checks if a dialplan detail record is marked for deletion
*
* @param string $uuid UUID of the dialplan detail record * @param string $uuid UUID of the dialplan detail record
* @param array $deleted_details array of dialplan detail records marked for deletion * @param array $deleted_details array of dialplan detail records marked for deletion
*
* @return bool Returns true if user has permission and dialplan detail is marked for deletion * @return bool Returns true if user has permission and dialplan detail is marked for deletion
*/ */
function marked_for_deletion(string $uuid, array $deleted_details): bool { function marked_for_deletion(string $uuid, array $deleted_details): bool {

File diff suppressed because it is too large Load Diff

View File

@@ -3,294 +3,332 @@
/** /**
* email_queue class * email_queue class
*/ */
class email_queue { class email_queue {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'email_queue'; const app_name = 'email_queue';
const app_uuid = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7'; const app_uuid = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare the variables * declare the variables
*/ */
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $location; private $location;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; * @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
//assign the variables
$this->name = 'email_queue';
$this->table = 'email_queue';
$this->toggle_field = '';
$this->toggle_values = ['true','false'];
$this->location = 'email_queue.php';
}
/**
* delete rows from the database
*/
public function delete($records) {
if (permission_exists($this->name.'_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
$array['email_queue_attachments'][$x][$this->name.'_uuid'] = $record['uuid'];
//$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* resend emails in the queue
*/
public function resend($records) {
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//resend multiple emails
if (is_array($records) && @sizeof($records) != 0) {
//build the message array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
$array[$this->table][$x]['email_status'] = 'waiting';
$array[$this->table][$x]['email_retry_count'] = null;
}
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-resending_messages']);
}
unset($records);
}
}
}
/**
* toggle a field between two values
*/
public function toggle($records) {
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy rows from the database
*/
public function copy($records) {
if (permission_exists($this->name.'_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name.'_uuid'] = uuid();
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign the variables
$this->name = 'email_queue';
$this->table = 'email_queue';
$this->toggle_field = '';
$this->toggle_values = ['true', 'false'];
$this->location = 'email_queue.php';
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
$array['email_queue_attachments'][$x][$this->name . '_uuid'] = $record['uuid'];
//$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Resend multiple records.
*
* This method will resend the specified records if the permission to edit exists.
* It first checks if the token is valid, then it iterates over the records and
* updates their status to 'waiting' and resets the retry count. Finally, it saves
* the changes to the database.
*
* @param array $records The records to resend.
*
* @return void
*/
public function resend($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//resend multiple emails
if (is_array($records) && @sizeof($records) != 0) {
//build the message array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
$array[$this->table][$x]['email_status'] = 'waiting';
$array[$this->table][$x]['email_retry_count'] = null;
}
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-resending_messages']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->name . '_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name . '_uuid'] = uuid();
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -27,303 +27,336 @@
/** /**
* event_guard_logs class * event_guard_logs class
*/ */
class event_guard { class event_guard {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'event_guard'; const app_name = 'event_guard';
const app_uuid = 'c5b86612-1514-40cb-8e2c-3f01a8f6f637'; const app_uuid = 'c5b86612-1514-40cb-8e2c-3f01a8f6f637';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare the variables * declare the variables
*/ */
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $location; private $location;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; * @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign the variables
$this->name = 'event_guard_log';
$this->table = 'event_guard_logs';
$this->toggle_field = '';
$this->toggle_values = ['block','pending'];
$this->location = 'event_guard_logs.php';
}
/**
* delete rows from the database
*/
public function delete($records) {
if (permission_exists($this->name.'_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$array[$this->table][$x]['event_guard_log_uuid'] = $record['event_guard_log_uuid'];
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* update rows from the database change status to pending
*/
public function unblock($records) {
if (permission_exists($this->name.'_unblock')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$array[$this->table][$x]['event_guard_log_uuid'] = $record['event_guard_log_uuid'];
$array[$this->table][$x]['log_status'] = 'pending';
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->save($array);
unset($array);
//initialize the settings object
$setting = new settings(["category" => 'switch']);
//send unblock event
$cmd = "sendevent CUSTOM\n";
$cmd .= "Event-Name: CUSTOM\n";
$cmd .= "Event-Subclass: event_guard:unblock\n";
$esl = event_socket::create();
$switch_result = event_socket::command($cmd);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle a field between two values
*/
public function toggle($records) {
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$uuids[] = "'".$record['event_guard_log_uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy rows from the database
*/
public function copy($records) {
if (permission_exists($this->name.'_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$uuids[] = "'".$record['event_guard_log_uuid']."'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where event_guard_log_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x]['event_guard_log_uuid'] = uuid();
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign the variables
$this->name = 'event_guard_log';
$this->table = 'event_guard_logs';
$this->toggle_field = '';
$this->toggle_values = ['block', 'pending'];
$this->location = 'event_guard_logs.php';
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$array[$this->table][$x]['event_guard_log_uuid'] = $record['event_guard_log_uuid'];
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Unblocks multiple records.
*
* @param array $records An array of records to unblock, each containing 'event_guard_log_uuid' and 'checked' keys.
*
* @return void
*/
public function unblock($records) {
if (permission_exists($this->name . '_unblock')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$array[$this->table][$x]['event_guard_log_uuid'] = $record['event_guard_log_uuid'];
$array[$this->table][$x]['log_status'] = 'pending';
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->save($array);
unset($array);
//initialize the settings object
$setting = new settings(["category" => 'switch']);
//send unblock event
$cmd = "sendevent CUSTOM\n";
$cmd .= "Event-Name: CUSTOM\n";
$cmd .= "Event-Subclass: event_guard:unblock\n";
$esl = event_socket::create();
$switch_result = event_socket::command($cmd);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$uuids[] = "'" . $record['event_guard_log_uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->name . '_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['event_guard_log_uuid'])) {
$uuids[] = "'" . $record['event_guard_log_uuid'] . "'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where event_guard_log_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x]['event_guard_log_uuid'] = uuid();
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -115,6 +115,13 @@
echo "pid_file: ".$pid_file."\n"; echo "pid_file: ".$pid_file."\n";
//function to check if the process exists //function to check if the process exists
/**
* Checks if a process exists.
*
* @param string $file Path to the file containing the process ID (PID)
*
* @return bool True if the process exists, false otherwise
*/
function process_exists($file) { function process_exists($file) {
//set the default exists to false //set the default exists to false
@@ -373,6 +380,13 @@
} }
//run command and capture standard output //run command and capture standard output
/**
* Execute a shell command and capture its output.
*
* @param string $command The shell command to execute
*
* @return string The output of the executed command
*/
function shell($command) { function shell($command) {
ob_start(); ob_start();
$result = system($command); $result = system($command);
@@ -381,6 +395,15 @@
} }
//block an ip address //block an ip address
/**
* Execute a block command for iptables or pf based on the firewall type.
*
* @param string $ip_address The IP address to block
* @param string $filter The filter name for iptables or pf
* @param array $event The event data containing 'to-user' and 'to-host'
*
* @return boolean True if the block command was executed successfully, false otherwise
*/
function block($ip_address, $filter, $event) { function block($ip_address, $filter, $event) {
//define the global variables //define the global variables
global $database, $debug, $firewall_path, $firewall_name; global $database, $debug, $firewall_path, $firewall_name;
@@ -434,6 +457,14 @@
} }
//unblock the ip address //unblock the ip address
/**
* Unblock a specified IP address from a firewall.
*
* @param string $ip_address The IP address to unblock.
* @param string $filter The filter name used in the firewall configuration.
*
* @return bool True if the IP address was successfully unblocked, false otherwise.
*/
function unblock($ip_address, $filter) { function unblock($ip_address, $filter) {
//define the global variables //define the global variables
global $debug, $firewall_path, $firewall_name; global $debug, $firewall_path, $firewall_name;
@@ -470,6 +501,13 @@
} }
//is the ip address blocked //is the ip address blocked
/**
* Check if an IP address is blocked in the configured firewall.
*
* @param string $ip_address The IP address to check
*
* @return bool True if the address is blocked, False otherwise
*/
function is_blocked($ip_address) { function is_blocked($ip_address) {
//define the global variables //define the global variables
global $firewall_path, $firewall_name; global $firewall_path, $firewall_name;
@@ -502,6 +540,17 @@
} }
//determine if the IP address has been allowed by the access control list node cidr //determine if the IP address has been allowed by the access control list node cidr
/**
* Determine if access is allowed for a given IP address.
*
* This method checks the cache, user logs, event guard logs, access controls,
* and registration to determine if access should be granted. If no valid reason
* is found to deny access, it will be automatically allowed.
*
* @param string $ip_address The IP address to check for access.
*
* @return boolean True if access is allowed, false otherwise.
*/
function access_allowed($ip_address) { function access_allowed($ip_address) {
//define global variables //define global variables
global $debug; global $debug;
@@ -586,6 +635,13 @@
} }
//is the ip address registered //is the ip address registered
/**
* Checks if the given IP address is registered on the network.
*
* @param string $ip_address The IP address to check for registration.
*
* @return bool True if the IP address is registered, false otherwise.
*/
function is_registered($ip_address) { function is_registered($ip_address) {
//invalid ip address //invalid ip address
if (!filter_var($ip_address, FILTER_VALIDATE_IP)) { if (!filter_var($ip_address, FILTER_VALIDATE_IP)) {
@@ -609,6 +665,13 @@
} }
//determine if the IP address has been allowed by the access control list node cidr //determine if the IP address has been allowed by the access control list node cidr
/**
* Checks if the given IP address is authorized by any access control node.
*
* @param string $ip_address The IP address to check for authorization.
*
* @return bool True if the IP address is authorized, false otherwise.
*/
function access_control_allowed($ip_address) { function access_control_allowed($ip_address) {
global $database; global $database;
@@ -653,6 +716,13 @@
} }
//determine if the IP address has been allowed by a successful authentication //determine if the IP address has been allowed by a successful authentication
/**
* Determines if a user's IP address is allowed based on their login history.
*
* @param string $ip_address The IP address to check for access.
*
* @return bool True if the IP address is allowed, false otherwise.
*/
function user_log_allowed($ip_address) { function user_log_allowed($ip_address) {
global $database, $debug; global $database, $debug;
@@ -689,6 +759,13 @@
} }
//determine if the IP address has been unblocked in the event guard log //determine if the IP address has been unblocked in the event guard log
/**
* Determines if an IP address is allowed based on event guard logs.
*
* @param string $ip_address The IP address to check for access.
*
* @return bool True if the IP address is allowed, false otherwise.
*/
function event_guard_log_allowed($ip_address) { function event_guard_log_allowed($ip_address) {
global $database, $debug; global $database, $debug;
@@ -724,6 +801,13 @@
} }
//check if the iptables chain exists //check if the iptables chain exists
/**
* Determines if a pf table exists in the firewall configuration.
*
* @param string $table The name of the pf table to check for existence.
*
* @return bool True if the pf table exists, false otherwise.
*/
function pf_table_exists($table) { function pf_table_exists($table) {
//define the global variables //define the global variables
global $firewall_path, $firewall_name; global $firewall_path, $firewall_name;
@@ -741,6 +825,13 @@
} }
//add IP table chains //add IP table chains
/**
* Adds a new IPtables chain and inserts it into the INPUT table.
*
* @param string $chain The name of the IPtables chain to add.
*
* @return bool True if the chain was successfully added, false otherwise.
*/
function iptables_chain_add($chain) { function iptables_chain_add($chain) {
//define the global variables //define the global variables
global $firewall_path; global $firewall_path;
@@ -769,6 +860,13 @@
} }
//check if the iptables chain exists //check if the iptables chain exists
/**
* Determines if a specified iptables chain exists.
*
* @param string $chain The name of the iptables chain to check for existence.
*
* @return bool True if the iptables chain exists, false otherwise.
*/
function iptables_chain_exists($chain) { function iptables_chain_exists($chain) {
//define the global variables //define the global variables
global $firewall_path; global $firewall_path;
@@ -784,5 +882,3 @@
return false; return false;
} }
} }
?>

View File

@@ -27,292 +27,321 @@
/** /**
* extension_settings class * extension_settings class
*/ */
class extension_settings { class extension_settings {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'extension_settings'; const app_name = 'extension_settings';
const app_uuid = '1416a250-f6e1-4edc-91a6-5c9b883638fd'; const app_uuid = '1416a250-f6e1-4edc-91a6-5c9b883638fd';
/** /**
* declare the public variables * declare the public variables
*/ */
public $extension_uuid; public $extension_uuid;
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare the private variables * declare the private variables
*/ */
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $description_field; private $description_field;
private $location; private $location;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; * @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign the variables //assign the variables
$this->name = 'extension_setting'; $this->name = 'extension_setting';
$this->table = 'extension_settings'; $this->table = 'extension_settings';
$this->toggle_field = 'extension_setting_enabled'; $this->toggle_field = 'extension_setting_enabled';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
$this->description_field = 'extension_setting_description'; $this->description_field = 'extension_setting_description';
$this->location = 'extension_settings.php'; $this->location = 'extension_settings.php';
}
/**
* delete rows from the database
*/
public function delete($records) {
if (permission_exists($this->name.'_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
if (empty($this->extension_uuid)) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle, extension_uuid ";
$sql .= "from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in :uuid ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['uuid'] = $record['uuid'];
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$this->extension_uuid = $rows[0]['extension_uuid'];
}
unset($sql, $parameters);
}
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//clear the cache
if (!empty($this->extension_uuid)) {
$sql = "select extension, number_alias, user_context from v_extensions ";
$sql .= "where extension_uuid = :extension_uuid ";
$parameters['extension_uuid'] = $this->extension_uuid;
$extension = $this->database->select($sql, $parameters, 'row');
$cache = new cache;
$cache->delete(gethostname().":directory:".$extension["extension"]."@".$extension["user_context"]);
$cache->delete(gethostname().":directory:".$extension["number_alias"]."@".$extension["user_context"]);
}
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle a field between two values
*/
public function toggle($records) {
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle, extension_uuid from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$this->extension_uuid = $rows[0]['extension_uuid'];
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//clear the cache
$sql = "select extension, number_alias, user_context from v_extensions ";
$sql .= "where extension_uuid = :extension_uuid ";
$parameters['extension_uuid'] = $this->extension_uuid;
$extension = $this->database->select($sql, $parameters, 'row');
$cache = new cache;
$cache->delete(gethostname().":directory:".$extension["extension"]."@".$extension["user_context"]);
$cache->delete(gethostname().":directory:".$extension["number_alias"]."@".$extension["user_context"]);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy rows from the database
*/
public function copy($records) {
if (permission_exists($this->name.'_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->name.'_uuid'] = uuid();
$array[$this->table][$x][$this->name.'_enabled'] = $row['extension_setting_enabled'] === true ? 'true' : 'false';
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '').' ('.$text['label-copy'].')';
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
} }
/**
* Deletes one or 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 delete($records) {
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
if (empty($this->extension_uuid)) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle, extension_uuid ";
$sql .= "from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in :uuid ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['uuid'] = $record['uuid'];
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$this->extension_uuid = $rows[0]['extension_uuid'];
}
unset($sql, $parameters);
}
}
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//clear the cache
if (!empty($this->extension_uuid)) {
$sql = "select extension, number_alias, user_context from v_extensions ";
$sql .= "where extension_uuid = :extension_uuid ";
$parameters['extension_uuid'] = $this->extension_uuid;
$extension = $this->database->select($sql, $parameters, 'row');
$cache = new cache;
$cache->delete(gethostname() . ":directory:" . $extension["extension"] . "@" . $extension["user_context"]);
$cache->delete(gethostname() . ":directory:" . $extension["number_alias"] . "@" . $extension["user_context"]);
}
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle, extension_uuid from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$this->extension_uuid = $rows[0]['extension_uuid'];
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//clear the cache
$sql = "select extension, number_alias, user_context from v_extensions ";
$sql .= "where extension_uuid = :extension_uuid ";
$parameters['extension_uuid'] = $this->extension_uuid;
$extension = $this->database->select($sql, $parameters, 'row');
$cache = new cache;
$cache->delete(gethostname() . ":directory:" . $extension["extension"] . "@" . $extension["user_context"]);
$cache->delete(gethostname() . ":directory:" . $extension["number_alias"] . "@" . $extension["user_context"]);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->name . '_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->name . '_uuid'] = uuid();
$array[$this->table][$x][$this->name . '_enabled'] = $row['extension_setting_enabled'] === true ? 'true' : 'false';
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '') . ' (' . $text['label-copy'] . ')';
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -93,6 +93,13 @@
$available_columns[] = 'forward_user_not_registered_enabled'; $available_columns[] = 'forward_user_not_registered_enabled';
//define the functions //define the functions
/**
* Converts a multi-dimensional array into a CSV string.
*
* @param array &$array The input array to be converted. It is expected that all rows of the array have the same number of columns.
*
* @return string|null The CSV string representation of the input array, or null if the input array is empty.
*/
function array2csv(array &$array) { function array2csv(array &$array) {
if (count($array) == 0) { if (count($array) == 0) {
return null; return null;
@@ -107,6 +114,11 @@
return ob_get_clean(); return ob_get_clean();
} }
/**
* Sets the headers for a file download.
*
* @param string $filename The name of the file to be downloaded.
*/
function download_send_headers($filename) { function download_send_headers($filename) {
// disable caching // disable caching
$now = gmdate("D, d M Y H:i:s"); $now = gmdate("D, d M Y H:i:s");

View File

@@ -50,6 +50,16 @@
$page = isset($_REQUEST['page']) && is_numeric($_REQUEST['page']) ? $_REQUEST['page'] : 0; $page = isset($_REQUEST['page']) && is_numeric($_REQUEST['page']) ? $_REQUEST['page'] : 0;
//return the first item if data type = array, returns value if data type = text //return the first item if data type = array, returns value if data type = text
/**
* Returns the first item of a given value.
*
* If the value is an array, returns the first element of the array.
* Otherwise, returns the value as is.
*
* @param mixed $value The value to retrieve the first item from.
*
* @return mixed The first item of the value.
*/
function get_first_item($value) { function get_first_item($value) {
return is_array($value) ? $value[0] : $value; return is_array($value) ? $value[0] : $value;
} }

View File

@@ -38,18 +38,6 @@
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//built in str_getcsv requires PHP 5.3 or higher, this function can be used to reproduct the functionality but requirs PHP 5.1.0 or higher
if (!function_exists('str_getcsv')) {
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
$fp = fopen("php://memory", 'r+');
fputs($fp, $input);
rewind($fp);
$data = fgetcsv($fp, null, $delimiter, $enclosure, $escape);
fclose($fp);
return $data;
}
}
//get the http get values and set them as php variables //get the http get values and set them as php variables
$action = $_POST["action"] ?? null; $action = $_POST["action"] ?? null;
$from_row = $_POST["from_row"] ?? null; $from_row = $_POST["from_row"] ?? null;
@@ -224,6 +212,14 @@
} }
//get the parent table //get the parent table
/**
* Retrieves the parent table name for a given table in the database schema.
*
* @param array $schema The database schema, where each element is an associative array containing 'table' and 'parent' keys.
* @param string $table_name The name of the table for which to retrieve the parent table name.
*
* @return mixed|null The parent table name if found, otherwise null.
*/
function get_parent($schema,$table_name) { function get_parent($schema,$table_name) {
foreach ($schema as $row) { foreach ($schema as $row) {
if ($row['table'] == $table_name) { if ($row['table'] == $table_name) {

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,13 @@ $sql .= "and fax_email_outbound_subject_tag is not null ";
$result = $database->select($sql, null, 'all'); $result = $database->select($sql, null, 'all');
unset($sql); unset($sql);
/**
* Converts an array to a map where each unique value in the array is mapped to true.
*
* @param array &$arr The input array
*
* @return array|false A map where each unique value in the array is mapped to true, or false if the input array is empty.
*/
function arr_to_map(&$arr){ function arr_to_map(&$arr){
if (!empty($arr)){ if (!empty($arr)){
$map = Array(); $map = Array();

View File

@@ -127,6 +127,13 @@
//define function correct_path //define function correct_path
if (!function_exists('correct_path')) { if (!function_exists('correct_path')) {
/**
* Corrects a file path to match the current operating system's conventions.
*
* @param string $p The file path to correct
*
* @return string The corrected file path
*/
function correct_path($p) { function correct_path($p) {
global $IS_WINDOWS; global $IS_WINDOWS;
if ($IS_WINDOWS) { if ($IS_WINDOWS) {
@@ -138,6 +145,17 @@ if (!function_exists('correct_path')) {
//define function gs_cmd //define function gs_cmd
if (!function_exists('gs_cmd')) { if (!function_exists('gs_cmd')) {
/**
* Generates a command to execute Ghostscript.
*
* The command is constructed based on the value of $IS_WINDOWS, which indicates
* whether the script is running under Windows. If it is, the command includes
* the 'gswin32c' executable, otherwise it uses 'gs'.
*
* @param string $args Command line arguments to be passed to Ghostscript.
*
* @return string The constructed command as a string.
*/
function gs_cmd($args) { function gs_cmd($args) {
global $IS_WINDOWS; global $IS_WINDOWS;
if ($IS_WINDOWS) { if ($IS_WINDOWS) {
@@ -149,7 +167,17 @@ if (!function_exists('gs_cmd')) {
//define function fax_split dtmf //define function fax_split dtmf
if (!function_exists('fax_split_dtmf')) { if (!function_exists('fax_split_dtmf')) {
function fax_split_dtmf(&$fax_number, &$fax_dtmf){ /**
* Splits a fax number string into its numeric and DTMF (Dual-Tone Multi-Frequency) parts.
*
* If the input fax number is in the format '12345678 (DTMF_digits)', this function
* extracts the numeric part and stores it in $fax_number, while storing the DTMF digits
* in $fax_dtmf.
*
* @param string &$fax_number The fax number to be split. Modified to contain only the numeric part.
* @param string &$fax_dtmf The extracted DTMF digits from the input fax number.
*/
function fax_split_dtmf(&$fax_number, &$fax_dtmf) {
$tmp = array(); $tmp = array();
$fax_dtmf = ''; $fax_dtmf = '';
if (preg_match('/^\s*(.*?)\s*\((.*)\)\s*$/', $fax_number, $tmp)){ if (preg_match('/^\s*(.*?)\s*\((.*)\)\s*$/', $fax_number, $tmp)){

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,12 @@
<?php <?php
/**
* Recursively converts an object or array to a multi-dimensional array.
*
* @param mixed $obj The object or array to be converted. If the value is neither an object nor an array, it will be returned as is.
*
* @return array A multi-dimensional array representation of the input object or array.
*/
function object_to_array($obj) { function object_to_array($obj) {
if (!is_object($obj) && !is_array($obj)) { return $obj; } if (!is_object($obj) && !is_array($obj)) { return $obj; }
if (is_object($obj)) { $obj = get_object_vars($obj); } if (is_object($obj)) { $obj = get_object_vars($obj); }

View File

@@ -1,5 +1,16 @@
<?php <?php
/**
* Parse attachments from a given email message.
*
* @param imap connection object $connection The IMAP connection to use for fetching the email message.
* @param int $message_number The number of the email message to parse attachments from.
* @param string $option Optional flag to pass to the imap_fetchstructure function.
*
* @return array An array of attachment details, where each element is an associative array containing
* 'filename', 'name', and 'attachment' keys. The return value will be a reindexed array,
* with keys starting from 0.
*/
function parse_attachments($connection, $message_number, $option = '') { function parse_attachments($connection, $message_number, $option = '') {
$attachments = array(); $attachments = array();
$structure = imap_fetchstructure($connection, $message_number, $option); $structure = imap_fetchstructure($connection, $message_number, $option);

View File

@@ -1,5 +1,15 @@
<?php <?php
/**
* Parse a message from the email connection.
*
* @param resource $connection IMAP connection to the mailbox
* @param int $message_number The message number of the message to parse
* @param string|null $option Optional argument for imap_fetchstructure()
* @param string $to_charset Charset to decode messages into, default is 'UTF-8'
*
* @return array An array containing two keys: 'messages' and 'attachments'. Each key contains an array of parsed messages or attachments.
*/
function parse_message($connection, $message_number, $option = null, $to_charset = 'UTF-8') { function parse_message($connection, $message_number, $option = null, $to_charset = 'UTF-8') {
$result = Array('messages'=>Array(),'attachments'=>Array()); $result = Array('messages'=>Array(),'attachments'=>Array());
$structure = imap_fetchstructure($connection, $message_number, $option); $structure = imap_fetchstructure($connection, $message_number, $option);
@@ -33,6 +43,18 @@ function parse_message($connection, $message_number, $option = null, $to_charset
return $result; return $result;
} }
/**
* Decode the text part of a message from the email connection.
*
* @param resource $connection IMAP connection to the mailbox
* @param array &$part The text part of the message, retrieved using imap_fetchstructure()
* @param int $message_number The message number of the message to parse
* @param int $id Unique identifier for this part of the message
* @param string|null $option Optional argument for imap_fetchbody()
* @param string $to_charset Charset to decode messages into, default is 'UTF-8'
*
* @return array An array containing three keys: 'data', 'type', and 'size'. The 'data' key contains the decoded message text.
*/
function parse_message_decode_text($connection, &$part, $message_number, $id, $option, $to_charset){ function parse_message_decode_text($connection, &$part, $message_number, $id, $option, $to_charset){
$msg = parse_message_fetch_body($connection, $part, $message_number, $id, $option); $msg = parse_message_fetch_body($connection, $part, $message_number, $id, $option);
@@ -63,6 +85,17 @@ function parse_message_decode_text($connection, &$part, $message_number, $id, $o
); );
} }
/**
* Parse an attachment from the email connection.
*
* @param resource $connection IMAP connection to the mailbox
* @param object &$part The email part to parse
* @param int $message_number The message number of the message containing the attachment
* @param string $id The internal ID of the attachment in the message
* @param string|null $option Optional argument for imap_fetchbody()
*
* @return array|false An array containing information about the parsed attachment, or false if no valid filename is found.
*/
function parse_message_decode_attach($connection, &$part, $message_number, $id, $option){ function parse_message_decode_attach($connection, &$part, $message_number, $id, $option){
$filename = false; $filename = false;
@@ -99,6 +132,17 @@ function parse_message_decode_attach($connection, &$part, $message_number, $id,
); );
} }
/**
* Retrieves and decodes the body of a message from an email server.
*
* @param resource $connection IMAP connection to the email server
* @param object & $part Part of the email being processed
* @param int $message_number The number of the message to retrieve
* @param string $id Unique identifier for the part
* @param int $option Option flag (default value is not documented)
*
* @return string The decoded body of the message
*/
function parse_message_fetch_body($connection, &$part, $message_number, $id, $option){ function parse_message_fetch_body($connection, &$part, $message_number, $id, $option){
$body = imap_fetchbody($connection, $message_number, $id, $option); $body = imap_fetchbody($connection, $message_number, $id, $option);
if($part->encoding == ENCBASE64){ if($part->encoding == ENCBASE64){
@@ -110,6 +154,13 @@ function parse_message_fetch_body($connection, &$part, $message_number, $id, $op
return $body; return $body;
} }
/**
* Returns the type and subtype of a message part.
*
* @param object $part Message part object containing type and subtype information.
*
* @return string Type and subtype of the message part, separated by a slash. (e.g., "message/plain")
*/
function parse_message_get_type(&$part){ function parse_message_get_type(&$part){
$types = Array( $types = Array(
TYPEMESSAGE => 'message', TYPEMESSAGE => 'message',
@@ -126,6 +177,17 @@ function parse_message_get_type(&$part){
return $types[$part->type] . '/' . strtolower($part->subtype); return $types[$part->type] . '/' . strtolower($part->subtype);
} }
/**
* Recursively flattens a hierarchical message structure into a single-level array.
*
* @param object $structure Message structure containing nested parts and subparts.
* @param array &$result Resulting flattened array of message parts.
* @param string $prefix Prefix for each part in the result array (optional).
* @param int $index Index of the current part (used for generating prefixes, optional).
* @param bool $fullPrefix Whether to include the index in the prefix or not (optional).
*
* @return array Flattened message structure.
*/
function parse_message_flatten(&$structure, &$result = array(), $prefix = '', $index = 1, $fullPrefix = true) { function parse_message_flatten(&$structure, &$result = array(), $prefix = '', $index = 1, $fullPrefix = true) {
foreach ($structure as $part) { foreach ($structure as $part) {
if(isset($part->parts)) { if(isset($part->parts)) {

View File

@@ -27,316 +27,348 @@
/** /**
* fax_queue class * fax_queue class
*/ */
class fax_queue { class fax_queue {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'fax_queue'; const app_name = 'fax_queue';
const app_uuid = '3656287f-4b22-4cf1-91f6-00386bf488f4'; const app_uuid = '3656287f-4b22-4cf1-91f6-00386bf488f4';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $location; private $location;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
* @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign the variables //assign the variables
$this->name = 'fax_queue'; $this->name = 'fax_queue';
$this->table = 'fax_queue'; $this->table = 'fax_queue';
$this->toggle_field = ''; $this->toggle_field = '';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
$this->location = 'fax_queue.php'; $this->location = 'fax_queue.php';
} }
/** /**
* delete rows from the database * Deletes one or more records.
*/ *
public function delete($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->name.'_delete')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function delete($records) {
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$array[$this->table][$x]['fax_queue_uuid'] = $record['fax_queue_uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
} }
//delete multiple records //increment the id
if (is_array($records) && @sizeof($records) != 0) { $x++;
//build the delete array }
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$array[$this->table][$x]['fax_queue_uuid'] = $record['fax_queue_uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
//increment the id //delete the checked rows
$x++; if (is_array($array) && @sizeof($array) != 0) {
} //execute delete
$this->database->delete($array);
unset($array);
//delete the checked rows //set message
if (is_array($array) && @sizeof($array) != 0) { message::add($text['message-delete']);
//execute delete }
$this->database->delete($array); unset($records);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
} }
} }
}
/** /**
* resend selected faxes in the fax queue * Resend multiple faxes.
*/ *
public function resend($records) { * @param array $records Array of records to resend, where each record contains a 'checked' and 'fax_queue_uuid' key.
if (permission_exists($this->name.'_edit')) { *
* @return void
*/
public function resend($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//resend multiple faxes
if (is_array($records) && @sizeof($records) != 0) {
//build the fax array
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$array[$this->table][$x][$this->name . '_uuid'] = $record['fax_queue_uuid'];
$array[$this->table][$x]['fax_status'] = 'waiting';
$array[$this->table][$x]['fax_retry_date'] = null;
$array[$this->table][$x]['fax_notify_date'] = null;
$array[$this->table][$x]['fax_retry_count'] = '0';
} }
//resend multiple faxes //increment the id
if (is_array($records) && @sizeof($records) != 0) { $x++;
//build the fax array }
$x = 0;
foreach ($records as $record) {
//add to the array
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$array[$this->table][$x][$this->name.'_uuid'] = $record['fax_queue_uuid'];
$array[$this->table][$x]['fax_status'] = 'waiting';
$array[$this->table][$x]['fax_retry_date'] = null;
$array[$this->table][$x]['fax_notify_date'] = null;
$array[$this->table][$x]['fax_retry_count'] = '0';
}
//increment the id //save the changes
$x++; if (is_array($array) && @sizeof($array) != 0) {
} //save the array
//save the changes $this->database->save($array);
if (is_array($array) && @sizeof($array) != 0) { unset($array);
//save the array
$this->database->save($array); //set message
unset($array); message::add($text['message-resending_faxes']);
}
unset($records);
}
//set message }
message::add($text['message-resending_faxes']); }
}
unset($records); /**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$uuids[] = "'" . $record['fax_queue_uuid'] . "'";
} }
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
} }
} }
}
/** /**
* toggle a field between two values * Copies one or more records
*/ *
public function toggle($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->name.'_edit')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->name . '_add')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->location); header('Location: ' . $this->location);
exit; exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$uuids[] = "'".$record['fax_queue_uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
} }
}
/** //copy the checked records
* copy rows from the database if (is_array($records) && @sizeof($records) != 0) {
*/
public function copy($records) {
if (permission_exists($this->name.'_add')) {
//add multi-lingual support //get checked records
$language = new text; foreach ($records as $record) {
$text = $language->get(); if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) {
$uuids[] = "'" . $record['fax_queue_uuid'] . "'";
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
} }
}
//copy the checked records //create the array from existing data
if (is_array($records) && @sizeof($records) != 0) { if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
//get checked records $sql .= "where fax_queue_uuid in (" . implode(', ', $uuids) . ") ";
foreach($records as $record) { $sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
if ($record['checked'] == 'true' && is_uuid($record['fax_queue_uuid'])) { $parameters['domain_uuid'] = $this->domain_uuid;
$uuids[] = "'".$record['fax_queue_uuid']."'"; $rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
} }
} }
//create the array from existing data //copy data
if (is_array($uuids) && @sizeof($uuids) != 0) { $array[$this->table][$x] = $row;
$sql = "select * from v_".$this->table." ";
$sql .= "where fax_queue_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data //add copy to the description
$array[$this->table][$x] = $row; $array[$this->table][$x][$this->name . '_uuid'] = uuid();
//add copy to the description //increment the id
$array[$this->table][$x][$this->name.'_uuid'] = uuid(); $x++;
}
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
} }
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
} }
} }
}
/** /**
* Removes records from the v_fax_files and v_fax_logs tables. Called by the maintenance application. * Removes records from the v_fax_files and v_fax_logs tables. Called by the maintenance application.
* @param settings $settings Settings object *
* @return void * @param settings $settings Settings object
*/ *
public static function database_maintenance(settings $settings): void { * @return void
$database = $settings->database(); */
$domains = maintenance_service::get_domains($database); public static function database_maintenance(settings $settings): void {
foreach ($domains as $domain_uuid => $domain_name) { $database = $settings->database();
$domain_settings = new settings(['database'=>$database, 'domain_uuid'=>$domain_uuid]); $domains = maintenance_service::get_domains($database);
$retention_days = $domain_settings->get('fax_queue', 'database_retention_days', ''); foreach ($domains as $domain_uuid => $domain_name) {
//delete from v_fax_queue where fax_status = 'sent' and fax_date < NOW() - INTERVAL '$days_keep_fax_queue days' $domain_settings = new settings(['database' => $database, 'domain_uuid' => $domain_uuid]);
if (!empty($retention_days) && is_numeric($retention_days)) { $retention_days = $domain_settings->get('fax_queue', 'database_retention_days', '');
$sql = "delete from v_fax_queue where fax_status = 'sent' and fax_date < NOW() - INTERVAL '$retention_days days'"; //delete from v_fax_queue where fax_status = 'sent' and fax_date < NOW() - INTERVAL '$days_keep_fax_queue days'
$sql .= " and domain_uuid = '$domain_uuid'"; if (!empty($retention_days) && is_numeric($retention_days)) {
$database->execute($sql); $sql = "delete from v_fax_queue where fax_status = 'sent' and fax_date < NOW() - INTERVAL '$retention_days days'";
$code = $database->message['code'] ?? 0; $sql .= " and domain_uuid = '$domain_uuid'";
if ($code == 200) { $database->execute($sql);
maintenance_service::log_write(self::class, "Successfully removed entries older than $retention_days", $domain_uuid); $code = $database->message['code'] ?? 0;
} else { if ($code == 200) {
$message = $database->message['message'] ?? "An unknown error has occurred"; maintenance_service::log_write(self::class, "Successfully removed entries older than $retention_days", $domain_uuid);
maintenance_service::log_write(self::class, "Unable to remove old database records. Error message: $message ($code)", $domain_uuid, maintenance_service::LOG_ERROR); } else {
} $message = $database->message['message'] ?? "An unknown error has occurred";
maintenance_service::log_write(self::class, "Unable to remove old database records. Error message: $message ($code)", $domain_uuid, maintenance_service::LOG_ERROR);
} }
} }
} }
} }
}

View File

@@ -34,6 +34,13 @@
//echo "pid_file: ".$pid_file."\n"; //echo "pid_file: ".$pid_file."\n";
//function to check if the process exists //function to check if the process exists
/**
* Checks if a process is running.
*
* @param string $file The path to the file containing the process ID, or false for no check.
*
* @return bool True if the process is running, false otherwise.
*/
function process_exists($file = false) { function process_exists($file = false) {
//set the default exists to false //set the default exists to false

View File

@@ -40,7 +40,17 @@
//extract dtmf from the fax number //extract dtmf from the fax number
if (!function_exists('fax_split_dtmf')) { if (!function_exists('fax_split_dtmf')) {
function fax_split_dtmf(&$fax_number, &$fax_dtmf){ /**
* Splits the fax number and DTMF tone string.
*
* This function takes a fax number with an optional DTMF tone string as input,
* extracts the fax number and the DTMF tone string, and stores them separately in
* the provided references.
*
* @param string &$fax_number The fax number to split. May contain an embedded DTMF tone string.
* @param string &$fax_dtmf The extracted DTMF tone string.
*/
function fax_split_dtmf(&$fax_number, &$fax_dtmf) {
$tmp = array(); $tmp = array();
$fax_dtmf = ''; $fax_dtmf = '';
if (preg_match('/^\s*(.*?)\s*\((.*)\)\s*$/', $fax_number, $tmp)){ if (preg_match('/^\s*(.*?)\s*\((.*)\)\s*$/', $fax_number, $tmp)){
@@ -62,6 +72,16 @@
} }
//shutdown call back function //shutdown call back function
/**
* Performs a clean shutdown of the system.
*
* This function prepares for graceful termination by updating the fax queue status
* and removing the pid file. It is intended to be called when the application needs
* to shut down cleanly.
*
* @return void
* @see \register_shutdown_function()
*/
function shutdown() { function shutdown() {
//add global variables //add global variables
global $database, $fax_queue_uuid; global $database, $fax_queue_uuid;
@@ -89,6 +109,16 @@
//echo "pid_file: ".$pid_file."\n"; //echo "pid_file: ".$pid_file."\n";
//function to check if the process exists //function to check if the process exists
/**
* Checks if a process exists.
*
* This function checks the existence of a file containing a valid process ID,
* then verifies that the corresponding process is running using the `ps` command.
*
* @param string $file The path to the file containing the process ID. Defaults to an empty string, which means the function will return false.
*
* @return bool True if the process exists and is running, false otherwise.
*/
function process_exists($file = '') { function process_exists($file = '') {
//check if the file exists return false if not found //check if the file exists return false if not found
if (!file_exists($file)) { if (!file_exists($file)) {
@@ -112,6 +142,15 @@
} }
//remove single quote //remove single quote
/**
* Escapes single quotes in a string.
*
* This function removes all occurrences of single quotes from the input value.
*
* @param string $value The value to remove single quotes from. May be empty.
*
* @return boolean|string True if the value was not empty, otherwise false.
*/
function escape_quote($value) { function escape_quote($value) {
if (!empty($value)) { if (!empty($value)) {
return str_replace("'", "", $value); return str_replace("'", "", $value);

View File

@@ -37,6 +37,16 @@
//echo "pid_file: ".$pid_file."\n"; //echo "pid_file: ".$pid_file."\n";
//function to check if the process exists //function to check if the process exists
/**
* Checks if a process exists.
*
* This function checks if a process with the specified PID file exists, and returns true if it does,
* or false otherwise. If no PID file is provided, the function defaults to returning false.
*
* @param string|false $file The path to the PID file of the process to check for, or false to default to not checking any process.
*
* @return bool True if a process with the specified PID exists, false otherwise.
*/
function process_exists($file = false) { function process_exists($file = false) {
//set the default exists to false //set the default exists to false

View File

@@ -3,289 +3,305 @@
/** /**
* fifo class * fifo class
*/ */
class fifo { class fifo {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'fifo'; const app_name = 'fifo';
const app_uuid = '16589224-c876-aeb3-f59f-523a1c0801f7'; const app_uuid = '16589224-c876-aeb3-f59f-523a1c0801f7';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare the variables * declare the variables
*/ */
private $name; private $name;
private $table; private $table;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $description_field; private $description_field;
private $location; private $location;
private $uuid_prefix; private $uuid_prefix;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
* @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign the variables
$this->name = 'fifo';
$this->table = 'fifo';
$this->uuid_prefix = 'fifo_';
$this->toggle_field = 'fifo_enabled';
$this->toggle_values = ['true','false'];
$this->description_field = 'fifo_description';
$this->location = 'fifo.php';
}
/**
* called when there are no references to a particular object
* unset the variables used in the class
*/
public function __destruct() {
foreach ($this as $key => $value) {
unset($this->$key);
}
}
/**
* delete rows from the database
*/
public function delete($records) {
if (permission_exists($this->name.'_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked queues, build where clause for below
$uuids = [];
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && !empty($record['uuid']) && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//get necessary fifo queue details
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, dialplan_uuid from v_".$this->table." ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$fifos[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
$x = 0;
foreach ($fifos as $fifo_uuid => $fifo) {
//add to the array
$array[$this->table][$x][$this->name.'_uuid'] = $fifo_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['fifo_members'][$x]['fifo_uuid'] = $fifo_uuid;
$array['fifo_members'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplans'][$x]['dialplan_uuid'] = $fifo['dialplan_uuid'];
$array['dialplans'][$x]['domain_uuid'] = $this->domain_uuid;
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('fifo_member_delete', 'temp');
$p->add('dialplan_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('fifo_member_delete', 'temp');
$p->delete('dialplan_delete', 'temp');
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle a field between two values
*/
public function toggle($records) {
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && !empty($record['uuid']) && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy rows from the database
*/
public function copy($records) {
if (permission_exists($this->name.'_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name.'_uuid'] = uuid();
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field]).' ('.$text['label-copy'].')';
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('fifo_member_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('fifo_member_add', 'temp');
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign the variables
$this->name = 'fifo';
$this->table = 'fifo';
$this->uuid_prefix = 'fifo_';
$this->toggle_field = 'fifo_enabled';
$this->toggle_values = ['true', 'false'];
$this->description_field = 'fifo_description';
$this->location = 'fifo.php';
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked queues, build where clause for below
$uuids = [];
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && !empty($record['uuid']) && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//get necessary fifo queue details
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, dialplan_uuid from v_" . $this->table . " ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$fifos[$row['uuid']]['dialplan_uuid'] = $row['dialplan_uuid'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
$x = 0;
foreach ($fifos as $fifo_uuid => $fifo) {
//add to the array
$array[$this->table][$x][$this->name . '_uuid'] = $fifo_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['fifo_members'][$x]['fifo_uuid'] = $fifo_uuid;
$array['fifo_members'][$x]['domain_uuid'] = $this->domain_uuid;
$array['dialplans'][$x]['dialplan_uuid'] = $fifo['dialplan_uuid'];
$array['dialplans'][$x]['domain_uuid'] = $this->domain_uuid;
//increment the id
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('fifo_member_delete', 'temp');
$p->add('dialplan_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('fifo_member_delete', 'temp');
$p->delete('dialplan_delete', 'temp');
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && !empty($record['uuid']) && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->name . '_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create the array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name . '_uuid'] = uuid();
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field]) . ' (' . $text['label-copy'] . ')';
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('fifo_member_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('fifo_member_add', 'temp');
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -91,6 +91,18 @@
//gateway status function //gateway status function
if (!function_exists('switch_gateway_status')) { if (!function_exists('switch_gateway_status')) {
/**
* Switches the status of a gateway.
*
* This function sends an API request to retrieve the status of a gateway.
* If the first request fails, it attempts to send the same request with the
* gateway UUID in uppercase.
*
* @param string $gateway_uuid The unique identifier of the gateway.
* @param string $result_type The type of response expected (default: 'xml').
*
* @return string The status of the gateway, or an error message if the request fails.
*/
function switch_gateway_status($gateway_uuid, $result_type = 'xml') { function switch_gateway_status($gateway_uuid, $result_type = 'xml') {
global $esl; global $esl;
if ($esl->is_connected()) { if ($esl->is_connected()) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -25,8 +25,16 @@
*/ */
if (!function_exists('save_ivr_menu_xml')) { if (!function_exists('save_ivr_menu_xml')) {
/**
* Saves IVR menu XML configuration files.
*
* This function deletes all existing dialplan .xml files in the ivr_menus directory,
* then creates new IVR menu XML files based on the database records for the current domain.
*
* @return void
*/
function save_ivr_menu_xml() { function save_ivr_menu_xml() {
global $domain_uuid; global $domain_uuid, $settings;
//prepare for dialplan .xml files to be written. delete all dialplan files that are prefixed with dialplan_ and have a file extension of .xml //prepare for dialplan .xml files to be written. delete all dialplan files that are prefixed with dialplan_ and have a file extension of .xml
if (count($_SESSION["domains"]) > 1) { if (count($_SESSION["domains"]) > 1) {

View File

@@ -167,6 +167,11 @@
echo "<div class='card'>\n"; echo "<div class='card'>\n";
echo "<table class='list'>\n"; echo "<table class='list'>\n";
/**
* Writes the header for a list of modules.
*
* @param string $modifier The modifier to use in the checkbox ID and other attributes.
*/
function write_header($modifier) { function write_header($modifier) {
global $text, $modules, $list_row_edit_button; global $text, $modules, $list_row_edit_button;
$modifier = str_replace('/', '', $modifier); $modifier = str_replace('/', '', $modifier);

File diff suppressed because it is too large Load Diff

View File

@@ -612,6 +612,16 @@
require_once "resources/footer.php"; require_once "resources/footer.php";
//define the download function (helps safari play audio sources) //define the download function (helps safari play audio sources)
/**
* Downloads a file in chunks as requested by the client.
*
* This function is used to handle byte-range requests, allowing clients
* to request specific parts of the file.
*
* @param string $file The path to the file being downloaded.
*
* @return void
*/
function range_download($file) { function range_download($file) {
$fp = @fopen($file, 'rb'); $fp = @fopen($file, 'rb');
@@ -640,7 +650,7 @@
$c_start = $start; $c_start = $start;
$c_end = $end; $c_end = $end;
// Extract the range string // Extract the range string
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); [, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2);
// Make sure the client hasn't sent us a multibyte range // Make sure the client hasn't sent us a multibyte range
if (strpos($range, ',') !== false) { if (strpos($range, ',') !== false) {
// (?) Shoud this be issued here, or should the first // (?) Shoud this be issued here, or should the first

View File

@@ -27,419 +27,464 @@
*/ */
//define the switch_music_on_hold class //define the switch_music_on_hold class
class switch_music_on_hold { class switch_music_on_hold {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'music_on_hold'; const app_name = 'music_on_hold';
const app_uuid = '1dafe0f8-c08a-289b-0312-15baf4f20f81'; const app_uuid = '1dafe0f8-c08a-289b-0312-15baf4f20f81';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $this->settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $this->settings_array associative array or
* @var string * set in the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Username set in the constructor. This can be passed in through the $this->settings_array associative array or set in the session global array * Username set in the constructor. This can be passed in through the $this->settings_array associative array or
* @var string * set in the session global array
*/ *
private $username; * @var string
*/
private $username;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $this->settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $this->settings_array associative array or
* @var string * set in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $this->settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $this->settings_array associative array or
* @var string * set in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $xml; private $xml;
private $app_name; private $app_name;
private $app_uuid; private $app_uuid;
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; * @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
//assign private variables //assign private variables
$this->permission_prefix = 'music_on_hold_'; $this->permission_prefix = 'music_on_hold_';
$this->list_page = 'music_on_hold.php'; $this->list_page = 'music_on_hold.php';
$this->table = 'music_on_hold'; $this->table = 'music_on_hold';
$this->uuid_prefix = 'music_on_hold_'; $this->uuid_prefix = 'music_on_hold_';
}
/**
* Generates a HTML select element.
*
* @param string $name The name of the select field.
* @param string $selected The currently selected value.
* @param array $options Additional options to include in the select.
*
* @return string A HTML select element as a string.
*/
public function select($name, $selected, $options) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//start the select
$select = "<select class='formfld' name='" . $name . "' id='" . $name . "' style='width: auto;'>\n";
//music on hold
$music_list = $this->get();
if (count($music_list) > 0) {
$select .= " <option value=''>\n";
$select .= " <optgroup label='" . $text['label-music_on_hold'] . "'>\n";
$previous_name = '';
foreach ($music_list as $row) {
if ($previous_name != $row['music_on_hold_name']) {
$name = '';
if (!empty($row['domain_uuid'])) {
$name = $row['domain_name'] . '/';
}
$name .= $row['music_on_hold_name'];
$select .= " <option value='local_stream://" . $name . "' " . (($selected == "local_stream://" . $name) ? 'selected="selected"' : null) . ">" . $row['music_on_hold_name'] . "</option>\n";
}
$previous_name = $row['music_on_hold_name'];
}
$select .= " </optgroup>\n";
} }
//recordings
public function select($name, $selected, $options) { if (is_dir($_SERVER["PROJECT_ROOT"] . '/app/recordings')) {
//add multi-lingual support $recordings_c = new switch_recordings;
$language = new text; $recordings = $recordings_c->list_recordings();
$text = $language->get(); if (is_array($recordings) && sizeof($recordings) > 0) {
$select .= " <optgroup label='" . $text['label-recordings'] . "'>";
//start the select foreach ($recordings as $recording_value => $recording_name) {
$select = "<select class='formfld' name='".$name."' id='".$name."' style='width: auto;'>\n"; $select .= " <option value='" . $recording_value . "' " . (($selected == $recording_value) ? 'selected="selected"' : null) . ">" . $recording_name . "</option>\n";
//music on hold
$music_list = $this->get();
if (count($music_list) > 0) {
$select .= " <option value=''>\n";
$select .= " <optgroup label='".$text['label-music_on_hold']."'>\n";
$previous_name = '';
foreach($music_list as $row) {
if ($previous_name != $row['music_on_hold_name']) {
$name = '';
if (!empty($row['domain_uuid'])) {
$name = $row['domain_name'].'/';
}
$name .= $row['music_on_hold_name'];
$select .= " <option value='local_stream://".$name."' ".(($selected == "local_stream://".$name) ? 'selected="selected"' : null).">".$row['music_on_hold_name']."</option>\n";
}
$previous_name = $row['music_on_hold_name'];
}
$select .= " </optgroup>\n";
}
//recordings
if (is_dir($_SERVER["PROJECT_ROOT"].'/app/recordings')) {
$recordings_c = new switch_recordings;
$recordings = $recordings_c->list_recordings();
if (is_array($recordings) && sizeof($recordings) > 0) {
$select .= " <optgroup label='".$text['label-recordings']."'>";
foreach($recordings as $recording_value => $recording_name){
$select .= " <option value='".$recording_value."' ".(($selected == $recording_value) ? 'selected="selected"' : null).">".$recording_name."</option>\n";
}
$select .= " </optgroup>\n";
}
}
//streams
if (is_dir($_SERVER["PROJECT_ROOT"].'/app/streams')) {
$sql = "select * from v_streams ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and stream_enabled = 'true' ";
$sql .= "order by stream_name asc ";
$parameters['domain_uuid'] = $this->domain_uuid;
$streams = $this->database->select($sql, $parameters, 'all');
if (is_array($streams) && @sizeof($streams) != 0) {
$select .= " <optgroup label='".$text['label-streams']."'>";
foreach($streams as $row){
$select .= " <option value='".$row['stream_location']."' ".(($selected == $row['stream_location']) ? 'selected="selected"' : null).">".$row['stream_name']."</option>\n";
}
$select .= " </optgroup>\n";
}
unset($sql, $parameters, $streams, $row);
}
//add additional options
$select .= " <optgroup label='".$text['label-others']."'>";
$select .= " <option value='silence' ".($selected == "silence" ? 'selected="selected"' : null).">".$text['label-none']."</option>\n";
if (is_array($options) && sizeof($options) > 0) {
$select .= $options;
} }
$select .= " </optgroup>\n"; $select .= " </optgroup>\n";
//end the select and return it }
$select .= "</select>\n";
return $select;
} }
//streams
public function get() { if (is_dir($_SERVER["PROJECT_ROOT"] . '/app/streams')) {
//get moh records, build array $sql = "select * from v_streams ";
$sql = "select "; $sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "d.domain_name, "; $sql .= "and stream_enabled = 'true' ";
$sql .= "m.* "; $sql .= "order by stream_name asc ";
$sql .= "from v_music_on_hold as m ";
$sql .= "left join v_domains as d on d.domain_uuid = m.domain_uuid ";
$sql .= "where (m.domain_uuid = :domain_uuid or m.domain_uuid is null) ";
$sql .= "order by m.domain_uuid desc, music_on_hold_name asc, music_on_hold_rate asc ";
$parameters['domain_uuid'] = $this->domain_uuid; $parameters['domain_uuid'] = $this->domain_uuid;
return $this->database->select($sql, $parameters, 'all'); $streams = $this->database->select($sql, $parameters, 'all');
if (is_array($streams) && @sizeof($streams) != 0) {
$select .= " <optgroup label='" . $text['label-streams'] . "'>";
foreach ($streams as $row) {
$select .= " <option value='" . $row['stream_location'] . "' " . (($selected == $row['stream_location']) ? 'selected="selected"' : null) . ">" . $row['stream_name'] . "</option>\n";
}
$select .= " </optgroup>\n";
}
unset($sql, $parameters, $streams, $row);
}
//add additional options
$select .= " <optgroup label='" . $text['label-others'] . "'>";
$select .= " <option value='silence' " . ($selected == "silence" ? 'selected="selected"' : null) . ">" . $text['label-none'] . "</option>\n";
if (is_array($options) && sizeof($options) > 0) {
$select .= $options;
}
$select .= " </optgroup>\n";
//end the select and return it
$select .= "</select>\n";
return $select;
}
/**
* Retrieves moh records and builds an array.
*
* @return array|false An array of moh records.
*/
public function get() {
//get moh records, build array
$sql = "select ";
$sql .= "d.domain_name, ";
$sql .= "m.* ";
$sql .= "from v_music_on_hold as m ";
$sql .= "left join v_domains as d on d.domain_uuid = m.domain_uuid ";
$sql .= "where (m.domain_uuid = :domain_uuid or m.domain_uuid is null) ";
$sql .= "order by m.domain_uuid desc, music_on_hold_name asc, music_on_hold_rate asc ";
$parameters['domain_uuid'] = $this->domain_uuid;
return $this->database->select($sql, $parameters, 'all');
}
/**
* Reloads the module and establishes a connection to the Event Socket.
*/
public function reload() {
//add multi-lingual support
$language = new text;
$text = $language->get();
//if the handle does not exist create it
$esl = event_socket::create();
//if the handle still does not exist show an error message
if (!$esl->is_connected()) {
$msg = "<div align='center'>" . $text['message-event-socket'] . "<br /></div>";
} }
public function reload() { //send the api command to check if the module exists
if ($esl->is_connected()) {
$cmd = "reload mod_local_stream";
$switch_result = event_socket::api($cmd);
unset($cmd);
}
}
/**
* Saves the music on hold configuration.
*
* This method retrieves the contents of the template, replaces variables,
* and writes the updated XML config file to disk. The XML is then reloaded.
*/
public function save() {
//get the contents of the template
if (file_exists('/usr/share/examples/fusionpbx')) {
$file_contents = file_get_contents("/usr/share/examples/fusionpbx/resources/templates/conf/autoload_configs/local_stream.conf.xml");
} else {
$file_contents = file_get_contents($_SERVER["PROJECT_ROOT"] . "/app/switch/resources/conf/autoload_configs/local_stream.conf.xml");
}
//check where the default music is stored
$default_moh_prefix = 'music/default';
if (file_exists($this->settings->get('switch', 'sounds') . '/music/8000')) {
$default_moh_prefix = 'music';
}
//replace the variables
$file_contents = preg_replace("/music\/default/", $default_moh_prefix, $file_contents);
$file_contents = preg_replace("/[\t ]*(?:<!--)?{v_moh_categories}(?:-->)?/", $this->xml, $file_contents);
//write the XML config file
$fout = fopen($this->settings->get('switch', 'conf') . "/autoload_configs/local_stream.conf.xml", "w");
fwrite($fout, $file_contents);
fclose($fout);
//reload the XML
$this->reload();
}
/**
* Imports music on hold records.
*
* Retrieves domain and music on hold data, builds an array of sound files,
* and saves the data to the database.
*/
public function import() {
//get the domains
$sql = "select * from v_domains ";
$domains = $this->database->select($sql, null, 'all');
unset($sql);
//get the music_on_hold array
$sql = "select * from v_music_on_hold ";
$sql .= "order by domain_uuid desc, music_on_hold_name asc, music_on_hold_rate asc";
$music_on_hold = $this->database->select($sql, null, 'all');
unset($sql);
//build an array of the sound files
$music_directory = $this->settings->get('switch', 'sounds') . '/music';
if (file_exists($music_directory)) {
$files = array_merge(glob($music_directory . '/*/*/*.wav'), glob($music_directory . '/*/*/*/*.wav'));
}
//build a new file array
foreach ($files as $file) {
$path = substr($file, strlen($music_directory . '/'));
$path = str_replace("\\", "/", $path);
$path_array = explode("/", $path);
$file_array[$path_array[0]][$path_array[1]][$path_array[2]] = dirname($file);
//echo "domain_name ".$path_array[0]."<br />\n";
//echo "category_name ".$path_array[1]."<br />\n";
}
//view_array($file_array);
//prepare the data
$i = 0;
foreach ($file_array as $domain_name => $a1) {
foreach ($a1 as $category_name => $a2) {
foreach ($a2 as $sample_rate => $file_path) {
//echo "domain_name ".$domain_name."<br />\n";
//echo "category_name ".$category_name."<br />\n";
foreach ($domains as $field) {
if ($field['domain_name'] === $domain_name) {
$domain_uuid = $field['domain_uuid'];
//echo "domain_uuid ".$domain_uuid."<br />\n";
}
}
if ($domain_name == 'global' || $domain_name == 'default') {
$domain_uuid = null;
}
$array['music_on_hold'][$i]['music_on_hold_uuid'] = uuid();
$array['music_on_hold'][$i]['domain_uuid'] = $domain_uuid;
$array['music_on_hold'][$i]['music_on_hold_name'] = $category_name;
$array['music_on_hold'][$i]['music_on_hold_path'] = $file_path;
$array['music_on_hold'][$i]['music_on_hold_rate'] = strlen($sample_rate) != 0 ? $sample_rate : null;
$array['music_on_hold'][$i]['music_on_hold_shuffle'] = 'false';
$array['music_on_hold'][$i]['music_on_hold_channels'] = 1;
$array['music_on_hold'][$i]['music_on_hold_interval'] = 20;
$array['music_on_hold'][$i]['music_on_hold_timer_name'] = 'soft';
$array['music_on_hold'][$i]['music_on_hold_chime_list'] = null;
$array['music_on_hold'][$i]['music_on_hold_chime_freq'] = null;
$array['music_on_hold'][$i]['music_on_hold_chime_max'] = null;
$i++;
}
}
}
//view_array($array, false);
//save the data
$p = permissions::new();
$p->add('music_on_hold_add', 'temp');
$this->database->app_name = 'music_on_hold';
$this->database->app_uuid = '1dafe0f8-c08a-289b-0312-15baf4f20f81';
$this->database->save($array);
//echo $this->database->message;
unset($array);
$p->delete('music_on_hold_add', 'temp');
}
/**
* Deletes one or more records/files.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//if the handle does not exist create it //validate the token
$esl = event_socket::create(); $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//if the handle still does not exist show an error message //delete multiple records
if (!$esl->is_connected()) { if (is_array($records) && @sizeof($records) != 0) {
$msg = "<div align='center'>".$text['message-event-socket']."<br /></div>";
}
//send the api command to check if the module exists //filter checked records
if ($esl->is_connected()) { foreach ($records as $music_on_hold_uuid => $record) {
$cmd = "reload mod_local_stream"; if (is_uuid($music_on_hold_uuid)) {
$switch_result = event_socket::api($cmd); if ($record['checked'] == 'true') {
unset($cmd); $moh[$music_on_hold_uuid]['delete'] = true;
} }
} foreach ($record as $key => $array) {
if (is_numeric($key) && is_array($array) && @sizeof($array) != 0 && !empty($array['checked']) && $array['checked'] == 'true') {
public function save() { $moh[$music_on_hold_uuid][] = $array['file_name'];
//get the contents of the template
if (file_exists('/usr/share/examples/fusionpbx')) {
$file_contents = file_get_contents("/usr/share/examples/fusionpbx/resources/templates/conf/autoload_configs/local_stream.conf.xml");
}
else {
$file_contents = file_get_contents($_SERVER["PROJECT_ROOT"]."/app/switch/resources/conf/autoload_configs/local_stream.conf.xml");
}
//check where the default music is stored
$default_moh_prefix = 'music/default';
if(file_exists($this->settings->get('switch', 'sounds').'/music/8000')) {
$default_moh_prefix = 'music';
}
//replace the variables
$file_contents = preg_replace("/music\/default/", $default_moh_prefix, $file_contents);
$file_contents = preg_replace("/[\t ]*(?:<!--)?{v_moh_categories}(?:-->)?/", $this->xml, $file_contents);
//write the XML config file
$fout = fopen($this->settings->get('switch', 'conf')."/autoload_configs/local_stream.conf.xml","w");
fwrite($fout, $file_contents);
fclose($fout);
//reload the XML
$this->reload();
}
/**
* read the music files to add the music on hold into the database
*/
public function import() {
//get the domains
$sql = "select * from v_domains ";
$domains = $this->database->select($sql, null, 'all');
unset($sql);
//get the music_on_hold array
$sql = "select * from v_music_on_hold ";
$sql .= "order by domain_uuid desc, music_on_hold_name asc, music_on_hold_rate asc";
$music_on_hold = $this->database->select($sql, null, 'all');
unset($sql);
//build an array of the sound files
$music_directory = $this->settings->get('switch', 'sounds').'/music';
if (file_exists($music_directory)) {
$files = array_merge(glob($music_directory.'/*/*/*.wav'), glob($music_directory.'/*/*/*/*.wav'));
}
//build a new file array
foreach($files as $file) {
$path = substr($file, strlen($music_directory.'/'));
$path = str_replace("\\", "/", $path);
$path_array = explode("/", $path);
$file_array[$path_array[0]][$path_array[1]][$path_array[2]] = dirname($file);
//echo "domain_name ".$path_array[0]."<br />\n";
//echo "category_name ".$path_array[1]."<br />\n";
}
//view_array($file_array);
//prepare the data
$i = 0;
foreach($file_array as $domain_name => $a1) {
foreach($a1 as $category_name => $a2) {
foreach($a2 as $sample_rate => $file_path) {
//echo "domain_name ".$domain_name."<br />\n";
//echo "category_name ".$category_name."<br />\n";
foreach($domains as $field) {
if ($field['domain_name'] === $domain_name) {
$domain_uuid = $field['domain_uuid'];
//echo "domain_uuid ".$domain_uuid."<br />\n";
}
} }
if ($domain_name == 'global' || $domain_name == 'default') {
$domain_uuid = null;
}
$array['music_on_hold'][$i]['music_on_hold_uuid'] = uuid();
$array['music_on_hold'][$i]['domain_uuid'] = $domain_uuid;
$array['music_on_hold'][$i]['music_on_hold_name'] = $category_name;
$array['music_on_hold'][$i]['music_on_hold_path'] = $file_path;
$array['music_on_hold'][$i]['music_on_hold_rate'] = strlen($sample_rate) != 0 ? $sample_rate : null;
$array['music_on_hold'][$i]['music_on_hold_shuffle'] = 'false';
$array['music_on_hold'][$i]['music_on_hold_channels'] = 1;
$array['music_on_hold'][$i]['music_on_hold_interval'] = 20;
$array['music_on_hold'][$i]['music_on_hold_timer_name'] = 'soft';
$array['music_on_hold'][$i]['music_on_hold_chime_list'] = null;
$array['music_on_hold'][$i]['music_on_hold_chime_freq'] = null;
$array['music_on_hold'][$i]['music_on_hold_chime_max'] = null;
$i++;
} }
} }
} }
//view_array($array, false);
//save the data
$p = permissions::new();
$p->add('music_on_hold_add', 'temp');
$this->database->app_name = 'music_on_hold';
$this->database->app_uuid = '1dafe0f8-c08a-289b-0312-15baf4f20f81';
$this->database->save($array);
//echo $this->database->message;
unset($array); unset($array);
$p->delete('music_on_hold_add', 'temp'); //loop checked records
} $files_deleted = 0;
if (is_array($moh) && @sizeof($moh) != 0) {
/** //get music on hold details
* delete records/files $sql = "select * from v_music_on_hold ";
*/ $sql .= "where (domain_uuid = :domain_uuid " . (!permission_exists('music_on_hold_domain') ? "" : "or domain_uuid is null ") . ") ";
public function delete($records) { $sql .= "and music_on_hold_uuid in ('" . implode("','", array_keys($moh)) . "') ";
if (permission_exists($this->permission_prefix.'delete')) { $parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
//add multi-lingual support if (is_array($rows) && @sizeof($rows) != 0) {
$language = new text; foreach ($rows as $row) {
$text = $language->get(); $streams[$row['music_on_hold_uuid']] = $row;
}
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
} }
unset($sql, $parameters, $rows, $row);
//delete multiple records //delete files, folders, build delete array
if (is_array($records) && @sizeof($records) != 0) { $x = 0;
foreach ($moh as $music_on_hold_uuid => $row) {
//filter checked records //prepare path
foreach ($records as $music_on_hold_uuid => $record) { $stream_path = $streams[$music_on_hold_uuid]['music_on_hold_path'];
if (is_uuid($music_on_hold_uuid)) { $stream_path = str_replace('$${sounds_dir}', $this->settings->get('switch', 'sounds'), $stream_path);
if ($record['checked'] == 'true') {
$moh[$music_on_hold_uuid]['delete'] = true; //delete checked files
} foreach ($row as $key => $stream_file) {
foreach ($record as $key => $array) { if (is_numeric($key)) {
if (is_numeric($key) && is_array($array) && @sizeof($array) != 0 && !empty($array['checked']) && $array['checked'] == 'true') { $stream_file_path = str_replace('../', '', path_join($stream_path, $stream_file));
$moh[$music_on_hold_uuid][] = $array['file_name']; if (@unlink($stream_file_path)) {
} $files_deleted++;
}
} }
} }
unset($array); }
//loop checked records //delete name rate
$files_deleted = 0; if (!empty($row['delete']) && $row['delete'] == true) {
if (is_array($moh) && @sizeof($moh) != 0) {
//get music on hold details
$sql = "select * from v_music_on_hold ";
$sql .= "where (domain_uuid = :domain_uuid ".(!permission_exists('music_on_hold_domain') ? "": "or domain_uuid is null ").") ";
$sql .= "and music_on_hold_uuid in ('".implode("','", array_keys($moh))."') ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$streams[$row['music_on_hold_uuid']] = $row;
}
}
unset($sql, $parameters, $rows, $row);
//delete files, folders, build delete array
$x = 0;
foreach ($moh as $music_on_hold_uuid => $row) {
//prepare path
$stream_path = $streams[$music_on_hold_uuid]['music_on_hold_path'];
$stream_path = str_replace('$${sounds_dir}', $this->settings->get('switch', 'sounds'), $stream_path);
//delete checked files
foreach ($row as $key => $stream_file) {
if (is_numeric($key)) {
$stream_file_path = str_replace('../', '', path_join($stream_path, $stream_file));
if (@unlink($stream_file_path)) {
$files_deleted++;
}
}
}
//delete name rate
if (!empty($row['delete']) && $row['delete'] == true) {
//build delete array
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $music_on_hold_uuid;
if (!permission_exists('music_on_hold_domain')) {
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
$x++;
//delete rate folder
@rmdir($stream_path);
//delete name (category) folder, if empty
$name_path = dirname($stream_path);
if (@sizeof(scandir($name_path)) == 2) { //empty (only /.. and /. remaining)
@rmdir($name_path);
}
}
}
//build delete array
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $music_on_hold_uuid;
if (!permission_exists('music_on_hold_domain')) {
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
} }
$x++;
//delete the moh records //delete rate folder
if (!empty($array) && is_array($array) && @sizeof($array) != 0) { @rmdir($stream_path);
//execute delete
$this->database->delete($array);
unset($array);
//set flag
$moh_deleted = true;
//delete name (category) folder, if empty
$name_path = dirname($stream_path);
if (@sizeof(scandir($name_path)) == 2) { //empty (only /.. and /. remaining)
@rmdir($name_path);
} }
unset($records, $moh); }
//post delete
if ((!empty($moh_deleted) && $moh_deleted == true) || $files_deleted != 0) {
//clear the cache
$cache = new cache;
$cache->delete("configuration:local_stream.conf");
//reload moh
$this->reload();
//set message
message::add($text['message-delete']);
}
} }
}
//delete the moh records
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set flag
$moh_deleted = true;
}
unset($records, $moh);
//post delete
if ((!empty($moh_deleted) && $moh_deleted == true) || $files_deleted != 0) {
//clear the cache
$cache = new cache;
$cache->delete("configuration:local_stream.conf");
//reload moh
$this->reload();
//set message
message::add($text['message-delete']);
}
} }
} //method
} //class }
} //method
} //class
//build and save the XML //build and save the XML
//$moh = new switch_music_on_hold; //$moh = new switch_music_on_hold;
//$moh->xml(); //$moh->xml();
//$moh->save(); //$moh->save();

View File

@@ -25,400 +25,434 @@
*/ */
//define the number translations class //define the number translations class
class number_translations { class number_translations {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'number_translations'; const app_name = 'number_translations';
const app_uuid = '6ad54de6-4909-11e7-a919-92ebcb67fe33'; const app_uuid = '6ad54de6-4909-11e7-a919-92ebcb67fe33';
/** /**
* declare public variables * declare public variables
*/ */
public $number_translation_uuid; public $number_translation_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $database; private $database;
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $json; private $json;
private $xml; private $xml;
private $display_type; private $display_type;
/**
* Initializes the object with setting array.
*
* @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
* an empty array.
*
* @return void
*/
public function __construct(array $setting_array = []) {
//set objects
$this->database = $setting_array['database'] ?? database::new();
/** //assign private variables
* called when the object is created $this->permission_prefix = 'number_translation_';
*/ $this->list_page = 'number_translations.php';
public function __construct(array $setting_array = []) { $this->table = 'number_translations';
//set objects $this->uuid_prefix = 'number_translation_';
$this->database = $setting_array['database'] ?? database::new(); $this->toggle_field = 'number_translation_enabled';
$this->toggle_values = ['true', 'false'];
}
//assign private variables /**
$this->permission_prefix = 'number_translation_'; * Checks if a given name exists as a number translation.
$this->list_page = 'number_translations.php'; *
$this->table = 'number_translations'; * @param string $name The name to check for existence.
$this->uuid_prefix = 'number_translation_'; *
$this->toggle_field = 'number_translation_enabled'; * @return bool True if the number translation exists, false otherwise.
$this->toggle_values = ['true','false']; */
public function number_translation_exists($name) {
$sql = "select count(*) from v_number_translations ";
$sql .= "where number_translation_name = :number_translation_name ";
$parameters['number_translation_name'] = $name;
return $this->database->select($sql, $parameters, 'column') != 0 ? true : false;
}
/**
* Imports a number translation from either XML or JSON format.
*
* @return void
*/
public function import() {
//get the xml from the number templates
if (!empty($this->xml)) {
//convert the xml string to an xml object
$xml = simplexml_load_string($this->xml);
//convert to json
$json = json_encode($xml);
//convert to an array
$number_translation = json_decode($json, true);
} elseif (!empty($this->json)) {
//convert to an array
$number_translation = json_decode($this->json, true);
} else {
throw new Exception("require either json or xml to import");
} }
//check if the number_translation exists
/** if (!$this->number_translation_exists($number_translation['@attributes']['name'])) {
* Check to see if the number translation already exists //begin insert array
*/ $x = 0;
public function number_translation_exists($name) { $array['number_translations'][$x]['number_translation_name'] = $number_translation['@attributes']['name'];
$sql = "select count(*) from v_number_translations "; $array['number_translations'][$x]['number_translation_enabled'] = "true";
$sql .= "where number_translation_name = :number_translation_name "; if (!empty($number_translation['@attributes']['enabled'])) {
$parameters['number_translation_name'] = $name; $array['number_translations'][$x]['number_translation_enabled'] = $number_translation['@attributes']['enabled'];
return $this->database->select($sql, $parameters, 'column') != 0 ? true : false; }
$array['number_translations'][$x]['number_translation_description'] = $number_translation['@attributes']['description'];
//loop through the condition array
$order = 5;
if (isset($number_translation['rule'])) {
foreach ($number_translation['rule'] as $row) {
if (array_key_exists('@attributes', $row)) {
$row = $row['@attributes'];
}
$array['number_translations'][$x]['number_translation_details'][$order]['number_translation_detail_regex'] = $row['regex'];
$array['number_translations'][$x]['number_translation_details'][$order]['number_translation_detail_replace'] = $row['replace'];
$array['number_translations'][$x]['number_translation_details'][$order]['number_translation_detail_order'] = $order;
$order = $order + 5;
}
}
//grant temporary permissions
$p = permissions::new();
$p->add('number_translation_add', 'temp');
$p->add('number_translation_detail_add', 'temp');
//execute insert
$this->database->app_name = 'number_translations';
$this->database->app_uuid = '6ad54de6-4909-11e7-a919-92ebcb67fe33';
$this->database->save($array);
unset($array);
if (!empty($this->display_type) && $this->display_type == "text") {
if ($this->database->message['code'] != '200') {
echo "number_translation:" . $number_translation['@attributes']['name'] . ": failed: " . $this->database->message['message'] . "\n";
} else {
echo "number_translation:" . $number_translation['@attributes']['name'] . ": added with " . (($order / 5) - 1) . " entries\n";
}
}
//revoke temporary permissions
$p->delete('number_translation_add', 'temp');
$p->delete('number_translation_detail_add', 'temp');
} }
unset ($this->xml, $this->json);
}
/** /**
* Import the number translation rules from the resources directory * Deletes one or more records.
*/ *
public function import() { * @param array $records An array of record IDs to delete, where each ID is an associative array
//get the xml from the number templates * containing 'uuid' and 'checked' keys. The 'checked' value indicates
if (!empty($this->xml)) { * whether the corresponding checkbox was checked for deletion.
//convert the xml string to an xml object *
$xml = simplexml_load_string($this->xml); * @return void No return value; this method modifies the database state and sets a message.
//convert to json */
$json = json_encode($xml); public function delete($records) {
//convert to an array if (permission_exists($this->permission_prefix . 'delete')) {
$number_translation = json_decode($json, true);
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array['number_translation_details'][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
}
} }
else if (!empty($this->json)) {
//convert to an array //delete the checked rows
$number_translation = json_decode($this->json, true); if (is_array($array) && @sizeof($array) != 0) {
}
else {
throw new Exception("require either json or xml to import");
}
//check if the number_translation exists
if (!$this->number_translation_exists($number_translation['@attributes']['name'])) {
//begin insert array
$x = 0;
$array['number_translations'][$x]['number_translation_name'] = $number_translation['@attributes']['name'];
$array['number_translations'][$x]['number_translation_enabled'] = "true";
if (!empty($number_translation['@attributes']['enabled'])) {
$array['number_translations'][$x]['number_translation_enabled'] = $number_translation['@attributes']['enabled'];
}
$array['number_translations'][$x]['number_translation_description'] = $number_translation['@attributes']['description'];
//loop through the condition array
$order = 5;
if (isset($number_translation['rule'])) {
foreach ($number_translation['rule'] as $row) {
if (array_key_exists('@attributes', $row)) {
$row = $row['@attributes'];
}
$array['number_translations'][$x]['number_translation_details'][$order]['number_translation_detail_regex'] = $row['regex'];
$array['number_translations'][$x]['number_translation_details'][$order]['number_translation_detail_replace'] = $row['replace'];
$array['number_translations'][$x]['number_translation_details'][$order]['number_translation_detail_order'] = $order;
$order = $order + 5;
}
}
//grant temporary permissions //grant temporary permissions
$p = permissions::new(); $p = permissions::new();
$p->add('number_translation_add', 'temp'); $p->add('number_translation_detail_delete', 'temp');
$p->add('number_translation_detail_add', 'temp');
//execute insert //execute delete
$this->database->app_name = 'number_translations'; $this->database->delete($array);
$this->database->app_uuid = '6ad54de6-4909-11e7-a919-92ebcb67fe33'; unset($array);
$this->database->save($array);
unset($array);
if (!empty($this->display_type) && $this->display_type == "text") {
if ($this->database->message['code'] != '200') {
echo "number_translation:".$number_translation['@attributes']['name'].": failed: ".$this->database->message['message']."\n";
}
else {
echo "number_translation:".$number_translation['@attributes']['name'].": added with ".(($order/5)-1)." entries\n";
}
}
//revoke temporary permissions //revoke temporary permissions
$p->delete('number_translation_add', 'temp'); $p->delete('number_translation_detail_delete', 'temp');
$p->delete('number_translation_detail_add', 'temp');
//set message
message::add($text['message-delete']);
} }
unset ($this->xml, $this->json); unset($records);
}
/**
* delete records
*/
public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array['number_translation_details'][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('number_translation_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('number_translation_detail_delete', 'temp');
//set message
message::add($text['message-delete']);
}
unset($records);
}
} }
} }
}
public function delete_details($records) { /**
* Deletes multiple records from the number_translation_details table.
*
* @param array $records An array of records to be deleted, where each record is an associative array containing 'checked' and 'uuid' keys.
* The 'checked' key should contain a boolean value indicating whether the record should be deleted,
* while the 'uuid' key contains the unique identifier of the record.
*
* @return void
*/
public function delete_details($records) {
//assign private variables //assign private variables
$this->permission_prefix = 'number_translation_detail_'; $this->permission_prefix = 'number_translation_detail_';
$this->table = 'number_translation_details'; $this->table = 'number_translation_details';
$this->uuid_prefix = 'number_translation_detail_'; $this->uuid_prefix = 'number_translation_detail_';
if (permission_exists($this->permission_prefix.'delete')) { if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['number_translation_uuid'] = $this->number_translation_uuid;
} }
}
//delete multiple records //delete the checked rows
if (is_array($records) && @sizeof($records) != 0) { if (is_array($array) && @sizeof($array) != 0) {
//build the delete array //execute delete
foreach ($records as $x => $record) { $this->database->delete($array);
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) { unset($array);
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['number_translation_uuid'] = $this->number_translation_uuid;
}
}
//delete the checked rows }
if (is_array($array) && @sizeof($array) != 0) { unset($records);
//execute delete
$this->database->delete($array);
unset($array);
}
unset($records);
}
} }
} }
}
/** /**
* toggle records * Toggles the state of one or more records.
*/ *
public function toggle($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'edit')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
} }
}
/** //toggle the checked records
* copy records if (is_array($records) && @sizeof($records) != 0) {
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support //get current toggle state
$language = new text; foreach ($records as $x => $record) {
$text = $language->get(); if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
} }
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//copy the checked records //build update array
if (is_array($records) && @sizeof($records) != 0) { $x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//get checked records //save the changes
foreach($records as $x => $record) { if (is_array($array) && @sizeof($array) != 0) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'"; //save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
} }
} }
//create insert array from existing data //copy data
if (is_array($uuids) && @sizeof($uuids) != 0) { $array[$this->table][$x] = $row;
//primary table //overwrite
$sql = "select * from v_".$this->table." "; $array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $primary_uuid;
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") "; $array[$this->table][$x]['number_translation_description'] = trim($row['number_translation_description'] . ' (' . $text['label-copy'] . ')');
$rows = $this->database->select($sql, null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string //nodes sub table
foreach($row as $key => $value) { $sql_2 = "select * from v_number_translation_details where number_translation_uuid = :number_translation_uuid";
if (gettype($value) == 'boolean') { $parameters_2['number_translation_uuid'] = $row['number_translation_uuid'];
$value = $value ? 'true' : 'false'; $rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
$row[$key] = $value; if (is_array($rows_2) && @sizeof($rows_2) != 0) {
} foreach ($rows_2 as $row_2) {
} //convert boolean values to a string
foreach ($row_2 as $key => $value) {
//copy data if (gettype($value) == 'boolean') {
$array[$this->table][$x] = $row; $value = $value ? 'true' : 'false';
$row_2[$key] = $value;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $primary_uuid;
$array[$this->table][$x]['number_translation_description'] = trim($row['number_translation_description'].' ('.$text['label-copy'].')');
//nodes sub table
$sql_2 = "select * from v_number_translation_details where number_translation_uuid = :number_translation_uuid";
$parameters_2['number_translation_uuid'] = $row['number_translation_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
}
//copy data
$array['number_translation_details'][$y] = $row_2;
//overwrite
$array['number_translation_details'][$y]['number_translation_detail_uuid'] = uuid();
$array['number_translation_details'][$y]['number_translation_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
} }
} }
unset($sql, $parameters, $rows, $row);
//copy data
$array['number_translation_details'][$y] = $row_2;
//overwrite
$array['number_translation_details'][$y]['number_translation_detail_uuid'] = uuid();
$array['number_translation_details'][$y]['number_translation_uuid'] = $primary_uuid;
//increment
$y++;
}
} }
unset($sql_2, $parameters_2, $rows_2, $row_2);
//save the changes and set the message }
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('number_translation_detail_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('number_translation_detail_add', 'temp');
//set message
message::add($text['message-copy']);
}
unset($records);
} }
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('number_translation_detail_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('number_translation_detail_add', 'temp');
//set message
message::add($text['message-copy']);
}
unset($records);
} }
} //method
} //class }
} //method
} //class
/* /*
$obj = new number_translations; $obj = new number_translations;

View File

@@ -25,427 +25,462 @@
*/ */
//define the phrases class //define the phrases class
class phrases { class phrases {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'phrases'; const app_name = 'phrases';
const app_uuid = '5c6f597c-9b78-11e4-89d3-123b93f75cba'; const app_uuid = '5c6f597c-9b78-11e4-89d3-123b93f75cba';
/** /**
* declare public variables * declare public variables
*/ */
public $phrase_uuid; public $phrase_uuid;
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
* @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign private variables //assign private variables
$this->permission_prefix = 'phrase_'; $this->permission_prefix = 'phrase_';
$this->list_page = 'phrases.php'; $this->list_page = 'phrases.php';
$this->table = 'phrases'; $this->table = 'phrases';
$this->uuid_prefix = 'phrase_'; $this->uuid_prefix = 'phrase_';
$this->toggle_field = 'phrase_enabled'; $this->toggle_field = 'phrase_enabled';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
} }
/** /**
* delete records * Deletes one or more records.
*/ *
public function delete($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'delete')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked phrases, build where clause for below
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//get phrase languages
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, phrase_language as lang from v_" . $this->table . " ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$phrase_languages[$row['uuid']] = $row['lang'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
if (is_array($phrase_languages) && @sizeof($phrase_languages) != 0) {
$x = 0;
foreach ($phrase_languages as $phrase_uuid => $phrase_language) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $phrase_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['phrase_details'][$x][$this->uuid_prefix . 'uuid'] = $phrase_uuid;
$array['phrase_details'][$x]['domain_uuid'] = $this->domain_uuid;
$x++;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('phrase_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('phrase_detail_delete', 'temp');
//clear the cache
$phrase_languages = array_unique($phrase_languages);
$cache = new cache;
foreach ($phrase_languages as $phrase_language) {
$cache->delete("languages:" . $phrase_language);
} }
//delete multiple records //clear the destinations session array
if (is_array($records) && @sizeof($records) != 0) { if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
//filter out unchecked phrases, build where clause for below
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//get phrase languages
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, phrase_language as lang from v_".$this->table." ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$phrase_languages[$row['uuid']] = $row['lang'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build the delete array
if (is_array($phrase_languages) && @sizeof($phrase_languages) != 0) {
$x = 0;
foreach ($phrase_languages as $phrase_uuid => $phrase_language) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $phrase_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$array['phrase_details'][$x][$this->uuid_prefix.'uuid'] = $phrase_uuid;
$array['phrase_details'][$x]['domain_uuid'] = $this->domain_uuid;
$x++;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('phrase_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('phrase_detail_delete', 'temp');
//clear the cache
$phrase_languages = array_unique($phrase_languages);
$cache = new cache;
foreach ($phrase_languages as $phrase_language) {
$cache->delete("languages:".$phrase_language);
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete']);
}
unset($records, $phrase_languages);
} }
//set message
message::add($text['message-delete']);
}
unset($records, $phrase_languages);
} }
} }
}
public function delete_details($records) { /**
//assign private variables * Delete multiple details records.
$this->permission_prefix = 'phrase_'; *
$this->list_page = 'phrase_edit.php?id='.$this->phrase_uuid; * @param array $records An array of record IDs to delete, where each ID is an associative array containing
$this->table = 'phrase_details'; * the 'uuid' and optionally a 'checked' field. The 'checked' field should be set to true if the record
$this->uuid_prefix = 'phrase_detail_'; * should be deleted.
*
* @return void
*/
public function delete_details($records) {
//assign private variables
$this->permission_prefix = 'phrase_';
$this->list_page = 'phrase_edit.php?id=' . $this->phrase_uuid;
$this->table = 'phrase_details';
$this->uuid_prefix = 'phrase_detail_';
if (permission_exists($this->permission_prefix.'edit')) { if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked phrases, build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['phrase_uuid'] = $this->phrase_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//get phrase languages
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
$sql = "select phrase_language as lang from v_phrases ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and phrase_uuid = :phrase_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['phrase_uuid'] = $this->phrase_uuid;
$phrase_language = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters, $rows, $row);
}
//delete the checked rows
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('phrase_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('phrase_detail_delete', 'temp');
//clear the cache
if ($phrase_language != '') {
$cache = new cache;
$cache->delete("languages:" . $phrase_language);
} }
//delete multiple records }
if (is_array($records) && @sizeof($records) != 0) { unset($records, $phrase_language);
//filter out unchecked phrases, build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['phrase_uuid'] = $this->phrase_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//get phrase languages
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
$sql = "select phrase_language as lang from v_phrases ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and phrase_uuid = :phrase_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['phrase_uuid'] = $this->phrase_uuid;
$phrase_language = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters, $rows, $row);
}
//delete the checked rows
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('phrase_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('phrase_detail_delete', 'temp');
//clear the cache
if ($phrase_language != '') {
$cache = new cache;
$cache->delete("languages:".$phrase_language);
}
}
unset($records, $phrase_language);
}
} }
} }
}
/** /**
* toggle records * Toggles the state of one or more records.
*/ *
public function toggle($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'edit')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state and language
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle, phrase_language as lang from v_" . $this->table . " ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
$phrase_languages[] = $row['lang'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//clear the cache
if (!empty($phrase_languages) && is_array($phrase_languages) && @sizeof($phrase_languages) != 0) {
$phrase_languages = array_unique($phrase_languages);
$cache = new cache;
foreach ($phrase_languages as $phrase_language) {
$cache->delete("languages:" . $phrase_language);
}
} }
//toggle the checked records //clear the destinations session array
if (is_array($records) && @sizeof($records) != 0) { if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//get current toggle state and language //set message
foreach ($records as $x => $record) { message::add($text['message-toggle']);
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) { }
$uuids[] = "'".$record['uuid']."'"; unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
} }
} }
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, phrase_language as lang from v_".$this->table." ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
$phrase_languages[] = $row['lang'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array //copy data
$x = 0; $array[$this->table][$x] = $row;
foreach($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes //overwrite
if (is_array($array) && @sizeof($array) != 0) { $array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $primary_uuid;
$array[$this->table][$x]['phrase_description'] = trim($row['phrase_description'] . ' (' . $text['label-copy'] . ')');
//save the array //details sub table
$sql_2 = "select * from v_phrase_details where phrase_uuid = :phrase_uuid";
$parameters_2['phrase_uuid'] = $row['phrase_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
$this->database->save($array); //convert boolean values to a string
unset($array); foreach ($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
//clear the cache $value = $value ? 'true' : 'false';
if (!empty($phrase_languages) && is_array($phrase_languages) && @sizeof($phrase_languages) != 0) { $row_2[$key] = $value;
$phrase_languages = array_unique($phrase_languages);
$cache = new cache;
foreach ($phrase_languages as $phrase_language) {
$cache->delete("languages:".$phrase_language);
} }
} }
//clear the destinations session array //copy data
if (isset($_SESSION['destinations']['array'])) { $array['phrase_details'][$y] = $row_2;
unset($_SESSION['destinations']['array']);
}
//set message //overwrite
message::add($text['message-toggle']); $array['phrase_details'][$y]['phrase_detail_uuid'] = uuid();
} $array['phrase_details'][$y]['phrase_uuid'] = $primary_uuid;
unset($records, $states);
}
} //increment
} $y++;
/**
* copy records
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
} }
} }
unset($sql_2, $parameters_2, $rows_2, $row_2);
//create insert array from existing data //create array of languages
if (is_array($uuids) && @sizeof($uuids) != 0) { if (!empty($row['phrase_languages'])) {
$phrase_languages[] = $row['phrase_languages'];
//primary table
$sql = "select * from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $primary_uuid;
$array[$this->table][$x]['phrase_description'] = trim($row['phrase_description'].' ('.$text['label-copy'].')');
//details sub table
$sql_2 = "select * from v_phrase_details where phrase_uuid = :phrase_uuid";
$parameters_2['phrase_uuid'] = $row['phrase_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
}
//copy data
$array['phrase_details'][$y] = $row_2;
//overwrite
$array['phrase_details'][$y]['phrase_detail_uuid'] = uuid();
$array['phrase_details'][$y]['phrase_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
//create array of languages
if (!empty($row['phrase_languages'])) {
$phrase_languages[] = $row['phrase_languages'];
}
}
}
unset($sql, $parameters, $rows, $row);
} }
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message //save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) { if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions //grant temporary permissions
$p = permissions::new(); $p = permissions::new();
$p->add('phrase_detail_add', 'temp'); $p->add('phrase_detail_add', 'temp');
//save the array //save the array
$this->database->save($array); $this->database->save($array);
unset($array); unset($array);
//revoke temporary permissions //revoke temporary permissions
$p->delete('phrase_detail_add', 'temp'); $p->delete('phrase_detail_add', 'temp');
//clear the cache //clear the cache
if (!empty($phrase_languages) && is_array($phrase_languages) && @sizeof($phrase_languages) != 0) { if (!empty($phrase_languages) && is_array($phrase_languages) && @sizeof($phrase_languages) != 0) {
$phrase_languages = array_unique($phrase_languages); $phrase_languages = array_unique($phrase_languages);
$cache = new cache; $cache = new cache;
foreach ($phrase_languages as $phrase_language) { foreach ($phrase_languages as $phrase_language) {
$cache->delete("languages:".$phrase_language); $cache->delete("languages:" . $phrase_language);
} }
}
//set message
message::add($text['message-copy']);
}
unset($records);
} }
} //set message
} //method message::add($text['message-copy']);
} //class }
unset($records);
}
}
} //method
} //class

View File

@@ -51,6 +51,13 @@
$available_columns[] = 'description'; $available_columns[] = 'description';
//define the functions //define the functions
/**
* Converts a multi-dimensional PHP array into a CSV string.
*
* @param array &$array The input data to be converted. It is expected to have at least one row and one column.
*
* @return string|null The CSV representation of the input data, or null if the input array is empty.
*/
function array2csv(array &$array) { function array2csv(array &$array) {
if (count($array) == 0) { if (count($array) == 0) {
return null; return null;
@@ -65,6 +72,13 @@
return ob_get_clean(); return ob_get_clean();
} }
/**
* Sends HTTP headers for a file download.
*
* @param string $filename The name of the file to be downloaded.
*
* @return void
*/
function download_send_headers($filename) { function download_send_headers($filename) {
// disable caching // disable caching
$now = gmdate("D, d M Y H:i:s"); $now = gmdate("D, d M Y H:i:s");

View File

@@ -25,245 +25,272 @@
*/ */
//define the pin numbers class //define the pin numbers class
class pin_numbers { class pin_numbers {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'pin_numbers'; const app_name = 'pin_numbers';
const app_uuid = '4b88ccfb-cb98-40e1-a5e5-33389e14a388'; const app_uuid = '4b88ccfb-cb98-40e1-a5e5-33389e14a388';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
* @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign private variables
$this->permission_prefix = 'pin_number_';
$this->list_page = 'pin_numbers.php';
$this->table = 'pin_numbers';
$this->uuid_prefix = 'pin_number_';
$this->toggle_field = 'enabled';
$this->toggle_values = ['true','false'];
}
/**
* delete records
*/
public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle records
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy records
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = uuid();
$array[$this->table][$x]['description'] = trim($row['description'].' ('.$text['label-copy'].')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign private variables
$this->permission_prefix = 'pin_number_';
$this->list_page = 'pin_numbers.php';
$this->table = 'pin_numbers';
$this->uuid_prefix = 'pin_number_';
$this->toggle_field = 'enabled';
$this->toggle_values = ['true', 'false'];
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = uuid();
$array[$this->table][$x]['description'] = trim($row['description'] . ' (' . $text['label-copy'] . ')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -72,6 +72,13 @@
} }
//send http error //send http error
/**
* Displays a custom HTTP error page with the specified error code and message.
*
* @param int $error The HTTP error code (e.g., 400, 401, etc.)
*
* @return void The script exits after displaying the error page
*/
function http_error($error) { function http_error($error) {
//$error_int_val = intval($error); //$error_int_val = intval($error);
$http_errors = [ $http_errors = [
@@ -272,6 +279,13 @@
if (!empty($provision["http_auth_username"]) && empty($provision["http_auth_type"])) { $provision["http_auth_type"] = "digest"; } if (!empty($provision["http_auth_username"]) && empty($provision["http_auth_type"])) { $provision["http_auth_type"] = "digest"; }
if (!empty($provision["http_auth_username"]) && $provision["http_auth_type"] === "digest" && !empty($provision["http_auth_enabled"]) && $provision["http_auth_enabled"]) { if (!empty($provision["http_auth_username"]) && $provision["http_auth_type"] === "digest" && !empty($provision["http_auth_enabled"]) && $provision["http_auth_enabled"]) {
//function to parse the http auth header //function to parse the http auth header
/**
* Parses the specified HTTP Digest authentication text and extracts relevant data.
*
* @param string $txt The HTTP Digest authentication text to parse
*
* @return array|false An array of extracted data if successful, or false if data is incomplete
*/
function http_digest_parse($txt) { function http_digest_parse($txt) {
//protect against missing data //protect against missing data
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
@@ -286,6 +300,13 @@
} }
//function to request digest authentication //function to request digest authentication
/**
* Sends an HTTP Digest authentication request with the specified realm.
*
* @param string $realm The name of the protected resource's realm
*
* @return void The script exits after sending the authentication request
*/
function http_digest_request($realm) { function http_digest_request($realm) {
header('HTTP/1.1 401 Authorization Required'); header('HTTP/1.1 401 Authorization Required');
header('WWW-Authenticate: Digest realm="'.$realm.'", qop="auth", nonce="'.uniqid().'", opaque="'.md5($realm).'"'); header('WWW-Authenticate: Digest realm="'.$realm.'", qop="auth", nonce="'.uniqid().'", opaque="'.md5($realm).'"');
@@ -447,8 +468,8 @@
$file_size = strlen($file_contents); $file_size = strlen($file_contents);
if (isset($_SERVER['HTTP_RANGE'])) { if (isset($_SERVER['HTTP_RANGE'])) {
$ranges = $_SERVER['HTTP_RANGE']; $ranges = $_SERVER['HTTP_RANGE'];
list($unit, $range) = explode('=', $ranges, 2); [$unit, $range] = explode('=', $ranges, 2);
list($start, $end) = explode('-', $range, 2); [$start, $end] = explode('-', $range, 2);
$start = empty($start) ? 0 : (int)$start; $start = empty($start) ? 0 : (int)$start;
$end = empty($end) ? $file_size - 1 : min((int)$end, $file_size - 1); $end = empty($end) ? $file_size - 1 : min((int)$end, $file_size - 1);

File diff suppressed because it is too large Load Diff

View File

@@ -328,8 +328,8 @@
} }
$param .= "&order_by=".$order_by."&order=".$order; $param .= "&order_by=".$order_by."&order=".$order;
$page = isset($_GET['page']) ? $_GET['page'] : 0; $page = isset($_GET['page']) ? $_GET['page'] : 0;
list($paging_controls, $rows_per_page) = paging($num_rows, $param, $rows_per_page); [$paging_controls, $rows_per_page] = paging($num_rows, $param, $rows_per_page);
list($paging_controls_mini, $rows_per_page) = paging($num_rows, $param, $rows_per_page, true); [$paging_controls_mini, $rows_per_page] = paging($num_rows, $param, $rows_per_page, true);
$offset = $rows_per_page * $page; $offset = $rows_per_page * $page;
//set the time zone //set the time zone
@@ -622,6 +622,13 @@
require_once "resources/footer.php"; require_once "resources/footer.php";
//define the download function (helps safari play audio sources) //define the download function (helps safari play audio sources)
/**
* Downloads a file in range mode, allowing the client to request specific byte ranges.
*
* @param string $file Path to the file being downloaded
*
* @return void
*/
function range_download($file) { function range_download($file) {
$fp = @fopen($file, 'rb'); $fp = @fopen($file, 'rb');
@@ -650,7 +657,7 @@
$c_start = $start; $c_start = $start;
$c_end = $end; $c_end = $end;
// Extract the range string // Extract the range string
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); [, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2);
// Make sure the client hasn't sent us a multibyte range // Make sure the client hasn't sent us a multibyte range
if (strpos($range, ',') !== false) { if (strpos($range, ',') !== false) {
// (?) Shoud this be issued here, or should the first // (?) Shoud this be issued here, or should the first

View File

@@ -26,164 +26,189 @@
*/ */
//define the switch_recordings class //define the switch_recordings class
class switch_recordings { class switch_recordings {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'recordings'; const app_name = 'recordings';
const app_uuid = '83913217-c7a2-9e90-925d-a866eb40b60e'; const app_uuid = '83913217-c7a2-9e90-925d-a866eb40b60e';
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
public $domain_uuid; * @var string
*/
public $domain_uuid;
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; * @return void
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; */
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
//assign private variables //assign private variables
$this->permission_prefix = 'recording_'; $this->permission_prefix = 'recording_';
$this->list_page = 'recordings.php'; $this->list_page = 'recordings.php';
$this->table = 'recordings'; $this->table = 'recordings';
$this->uuid_prefix = 'recording_'; $this->uuid_prefix = 'recording_';
}
/**
* Retrieves a list of recordings.
*
* This method queries the database for recordings associated with the current domain UUID
* and populates an array with the recording filenames. The array keys are constructed using
* the directory path specified in the 'switch' settings, relative to the domain name.
*
* @return array|false An array of recording filenames where the keys represent the file paths on disk,
* or false if no recordings were found.
*/
public function list_recordings() {
$sql = "select recording_uuid, recording_filename ";
$sql .= "from v_recordings ";
$sql .= "where domain_uuid = :domain_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$result = $this->database->select($sql, $parameters, 'all');
if (!empty($result)) {
$switch_recordings_domain_dir = $this->settings->get('switch', 'recordings') . '/' . $this->domain_name;
foreach ($result as $row) {
$recordings[$switch_recordings_domain_dir . "/" . $row['recording_filename']] = $row['recording_filename'];
}
} else {
$recordings = false;
} }
unset($sql, $parameters, $result, $row);
return $recordings;
}
/** /**
* list recordings * Deletes one or more records.
*/ *
public function list_recordings() { * @param array $records An array of record IDs to delete, where each ID is an associative array
$sql = "select recording_uuid, recording_filename "; * containing 'uuid' and 'checked' keys. The 'checked' value indicates
$sql .= "from v_recordings "; * whether the corresponding checkbox was checked for deletion.
$sql .= "where domain_uuid = :domain_uuid "; *
$parameters['domain_uuid'] = $this->domain_uuid; * @return void No return value; this method modifies the database state and sets a message.
$result = $this->database->select($sql, $parameters, 'all'); */
if (!empty($result)) { public function delete($records) {
$switch_recordings_domain_dir = $this->settings->get('switch', 'recordings').'/'.$this->domain_name; if (permission_exists($this->permission_prefix . 'delete')) {
foreach ($result as $row) {
$recordings[$switch_recordings_domain_dir."/".$row['recording_filename']] = $row['recording_filename']; //add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//get recording filename, build delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && !empty($record['uuid'])) {
//get filename
$sql = "select recording_filename from v_recordings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and recording_uuid = :recording_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['recording_uuid'] = $record['uuid'];
$filenames[] = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//build delete array
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
} }
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//delete recording files
if (is_array($filenames) && @sizeof($filenames) != 0) {
$switch_recordings_domain_dir = $this->settings->get('switch', 'recordings') . "/" . $this->domain_name;
foreach ($filenames as $filename) {
if (!empty($filename) && file_exists($switch_recordings_domain_dir . "/" . $filename)) {
@unlink($switch_recordings_domain_dir . "/" . $filename);
}
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete']);
}
unset($records);
} }
else {
$recordings = false;
}
unset($sql, $parameters, $result, $row);
return $recordings;
} }
} //method
/** } //class
* delete records
*/
public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//get recording filename, build delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && !empty($record['uuid'])) {
//get filename
$sql = "select recording_filename from v_recordings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and recording_uuid = :recording_uuid ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['recording_uuid'] = $record['uuid'];
$filenames[] = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//build delete array
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//delete recording files
if (is_array($filenames) && @sizeof($filenames) != 0) {
$switch_recordings_domain_dir = $this->settings->get('switch', 'recordings')."/".$this->domain_name;
foreach ($filenames as $filename) {
if (!empty($filename) && file_exists($switch_recordings_domain_dir."/".$filename)) {
@unlink($switch_recordings_domain_dir."/".$filename);
}
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
} //method
} //class

View File

@@ -24,413 +24,445 @@
Mark J Crane <markjcrane@fusionpbx.com> Mark J Crane <markjcrane@fusionpbx.com>
*/ */
class registrations { class registrations {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'registrations'; const app_name = 'registrations';
const app_uuid = '5d9e7cd7-629e-3553-4cf5-f26e39fefa39'; const app_uuid = '5d9e7cd7-629e-3553-4cf5-f26e39fefa39';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* Set in the constructor. Must be an event_socket object and cannot be null. * Set in the constructor. Must be an event_socket object and cannot be null.
* @var event_socket Event Socket Connection Object *
*/ * @var event_socket Event Socket Connection Object
private $event_socket; */
private $event_socket;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
public $show; public $show;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; * @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
$this->event_socket = $setting_array['event_socket'] ?? event_socket::create(); $this->event_socket = $setting_array['event_socket'] ?? event_socket::create();
//trap passing an invalid connection object for communicating to the switch //trap passing an invalid connection object for communicating to the switch
if (!($this->event_socket instanceof event_socket)) { if (!($this->event_socket instanceof event_socket)) {
//should never happen but will trap it here just in case //should never happen but will trap it here just in case
throw new \InvalidArgumentException('Event socket object passed in the constructor is not a valid event_socket object'); throw new \InvalidArgumentException('Event socket object passed in the constructor is not a valid event_socket object');
}
//assign private variables
$this->permission_prefix = 'registration_';
$this->list_page = 'registrations.php';
$this->show = 'local';
}
/**
* Retrieves the registration list for a given SIP profile.
*
* @param string|null $profile The name of the SIP profile to retrieve. Defaults to 'all'.
*
* @return array|null The registration list, or null if no profiles are found.
*/
public function get($profile = 'all') {
//add multi-lingual support
$language = new text;
$text = $language->get(null, '/app/registrations');
//initialize the id used in the registrations array
$id = 0;
//create the event socket connection
$event_socket = $this->event_socket;
//make sure the event socket is connected
if (!$event_socket->is_connected()) {
//connect to event socket
$event_socket->connect();
//check again and throw an error if it can't connect
if (!$event_socket->is_connected()) {
message::add($text['error-event-socket'], 'negative', 5000);
return null;
} }
//assign private variables
$this->permission_prefix = 'registration_';
$this->list_page = 'registrations.php';
$this->show = 'local';
} }
/** //get the default settings
* get the registrations $sql = "select sip_profile_name from v_sip_profiles ";
*/ $sql .= "where true ";
public function get($profile = 'all') { if (!empty($profile) && $profile != 'all') {
$sql .= "and sip_profile_name = :sip_profile_name ";
$parameters['sip_profile_name'] = $profile;
}
$sql .= "and sip_profile_enabled = true ";
$sip_profiles = $this->database->select($sql, $parameters ?? null, 'all');
//add multi-lingual support if (!empty($sip_profiles)) {
$language = new text;
$text = $language->get(null, '/app/registrations');
//initialize the id used in the registrations array //use a while loop to ensure the event socket stays connected while communicating
$id = 0; $count = count($sip_profiles);
$i = 0;
while ($event_socket->is_connected() && $i < $count) {
$field = $sip_profiles[$i++];
//create the event socket connection //get sofia status profile information including registrations
$event_socket = $this->event_socket; $cmd = "api sofia xmlstatus profile '" . $field['sip_profile_name'] . "' reg";
$xml_response = trim($event_socket->request($cmd));
//make sure the event socket is connected //show an error message
if (!$event_socket->is_connected()) { if ($xml_response == "Invalid Profile!") {
//connect to event socket //show the error message
$event_socket->connect(); $xml_response = "<error_msg>" . escape($text['label-message']) . "</error_msg>";
//check again and throw an error if it can't connect
if (!$event_socket->is_connected()) {
message::add($text['error-event-socket'], 'negative', 5000);
return null;
}
} }
//get the default settings //sanitize the XML
$sql = "select sip_profile_name from v_sip_profiles "; if (function_exists('iconv')) {
$sql .= "where true "; $xml_response = iconv("utf-8", "utf-8//IGNORE", $xml_response);
if (!empty($profile) && $profile != 'all') {
$sql .= "and sip_profile_name = :sip_profile_name ";
$parameters['sip_profile_name'] = $profile;
} }
$sql .= "and sip_profile_enabled = true "; $xml_response = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $xml_response);
$sip_profiles = $this->database->select($sql, $parameters ?? null, 'all'); $xml_response = str_replace("<profile-info>", "<profile_info>", $xml_response);
$xml_response = str_replace("</profile-info>", "</profile_info>", $xml_response);
if (!empty($sip_profiles)) { $xml_response = str_replace("&lt;", "", $xml_response);
$xml_response = str_replace("&gt;", "", $xml_response);
//use a while loop to ensure the event socket stays connected while communicating if (strlen($xml_response) > 101) {
$count = count($sip_profiles); try {
$i = 0; $xml = new SimpleXMLElement($xml_response);
while ($event_socket->is_connected() && $i < $count) { } catch (Exception $e) {
$field = $sip_profiles[$i++]; echo basename(__FILE__) . "<br />\n";
echo "line: " . __line__ . "<br />\n";
//get sofia status profile information including registrations echo "error: " . $e->getMessage() . "<br />\n";
$cmd = "api sofia xmlstatus profile '".$field['sip_profile_name']."' reg"; //echo $xml_response;
$xml_response = trim($event_socket->request($cmd));
//show an error message
if ($xml_response == "Invalid Profile!") {
//show the error message
$xml_response = "<error_msg>".escape($text['label-message'])."</error_msg>";
}
//sanitize the XML
if (function_exists('iconv')) { $xml_response = iconv("utf-8", "utf-8//IGNORE", $xml_response); }
$xml_response = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $xml_response);
$xml_response = str_replace("<profile-info>", "<profile_info>", $xml_response);
$xml_response = str_replace("</profile-info>", "</profile_info>", $xml_response);
$xml_response = str_replace("&lt;", "", $xml_response);
$xml_response = str_replace("&gt;", "", $xml_response);
if (strlen($xml_response) > 101) {
try {
$xml = new SimpleXMLElement($xml_response);
}
catch(Exception $e) {
echo basename(__FILE__)."<br />\n";
echo "line: ".__line__."<br />\n";
echo "error: ".$e->getMessage()."<br />\n";
//echo $xml_response;
exit;
}
$array = json_decode(json_encode($xml), true);
}
//normalize the array
if (!empty($array) && is_array($array) && (!isset($array['registrations']['registration'][0]) || !is_array($array['registrations']['registration'][0]))) {
$row = $array['registrations']['registration'];
unset($array['registrations']['registration']);
$array['registrations']['registration'][0] = $row;
}
//set the registrations array
if (!empty($array) && is_array($array)) {
foreach ($array['registrations']['registration'] as $row) {
//build the registrations array
//$registrations[0] = $row;
$user_array = explode('@', $row['user'] ?? '');
$registrations[$id]['user'] = $row['user'] ?? '';
$registrations[$id]['call-id'] = $row['call-id'] ?? '';
$registrations[$id]['contact'] = $row['contact'] ?? '';
$registrations[$id]['sip-auth-user'] = $row['sip-auth-user'] ?? '';
$registrations[$id]['agent'] = $row['agent'] ?? '';
$registrations[$id]['host'] = $row['host'] ?? '';
$registrations[$id]['network-ip'] = $row['network-ip'] ?? '';
$registrations[$id]['network-port'] = $row['network-port'] ?? '';
$registrations[$id]['sip-auth-user'] = $row['sip-auth-user'] ?? '';
$registrations[$id]['sip-auth-realm'] = $row['sip-auth-realm'] ?? '';
$registrations[$id]['mwi-account'] = $row['mwi-account'] ?? '';
$registrations[$id]['status'] = $row['status'] ?? '';
$registrations[$id]['ping-time'] = $row['ping-time'] ?? '';
$registrations[$id]['ping-status'] = $row['ping-status'] ?? '';
$registrations[$id]['sip_profile_name'] = $field['sip_profile_name'];
//get network-ip to url or blank
if (isset($row['network-ip'])) {
$registrations[$id]['network-ip'] = $row['network-ip'];
}
else {
$registrations[$id]['network-ip'] = '';
}
//get the LAN IP address if it exists replace the external ip
$call_id_array = explode('@', $row['call-id'] ?? '');
if (isset($call_id_array[1])) {
$agent = $row['agent'];
$lan_ip = $call_id_array[1];
if (!empty($agent) && (false !== stripos($agent, 'grandstream') || false !== stripos($agent, 'ooma'))) {
$lan_ip = str_ireplace(
array('A','B','C','D','E','F','G','H','I','J'),
array('0','1','2','3','4','5','6','7','8','9'),
$lan_ip);
}
elseif (!empty($agent) && 1 === preg_match('/\ACL750A/', $agent)) {
//required for GIGASET Sculpture CL750A puts _ in it's lan ip account
$lan_ip = preg_replace('/_/', '.', $lan_ip);
}
$registrations[$id]['lan-ip'] = $lan_ip;
}
else if (preg_match('/real=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $row['contact'] ?? '', $ip_match)) {
//get ip address for snom phones
$lan_ip = str_replace('real=', '', $ip_match[0]);
$registrations[$id]['lan-ip'] = $lan_ip;
}
else if (preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $row['contact'] ?? '', $ip_match)) {
$lan_ip = preg_replace('/_/', '.', $ip_match[0]);
$registrations[$id]['lan-ip'] = $lan_ip;
}
else {
$registrations[$id]['lan-ip'] = '';
}
//remove unrelated domains
if (!permission_exists('registration_all') || $this->show != 'all') {
if ($registrations[$id]['sip-auth-realm'] == $this->domain_name) {}
else if ($user_array[1] == $this->domain_name) {}
else {
unset($registrations[$id]);
}
}
//increment the array id
$id++;
}
unset($array);
}
}
}
//return the registrations array
return $registrations ?? null;
}
/**
* get the registration count
*/
public function count($profile = 'all') {
//use get the registrations to count
$registrations = $this->get($profile);
//set the count
$count = !empty($registrations) ? @sizeof($registrations) : 0;
//return the registrations count
return $count;
}
/**
* unregister registrations
*/
public function unregister($registrations) {
$this->switch_api('unregister', $registrations);
}
/**
* provision registrations
*/
public function provision($registrations) {
$this->switch_api('provision', $registrations);
}
/**
* reboot registrations
*/
public function reboot($registrations) {
$this->switch_api('reboot', $registrations);
}
/**
* switch api calls
*/
private function switch_api($action, $records) {
if (permission_exists($this->permission_prefix.'domain') || permission_exists($this->permission_prefix.'all') || if_group('superadmin')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit; exit;
} }
$array = json_decode(json_encode($xml), true);
}
//filter out unchecked registrations //normalize the array
if (is_array($records) && @sizeof($records) != 0) { if (!empty($array) && is_array($array) && (!isset($array['registrations']['registration'][0]) || !is_array($array['registrations']['registration'][0]))) {
foreach($records as $record) { $row = $array['registrations']['registration'];
if ($record['checked'] == 'true' && !empty($record['user']) && !empty($record['profile'])) { unset($array['registrations']['registration']);
$registrations[] = $record; $array['registrations']['registration'][0] = $row;
}
//set the registrations array
if (!empty($array) && is_array($array)) {
foreach ($array['registrations']['registration'] as $row) {
//build the registrations array
//$registrations[0] = $row;
$user_array = explode('@', $row['user'] ?? '');
$registrations[$id]['user'] = $row['user'] ?? '';
$registrations[$id]['call-id'] = $row['call-id'] ?? '';
$registrations[$id]['contact'] = $row['contact'] ?? '';
$registrations[$id]['sip-auth-user'] = $row['sip-auth-user'] ?? '';
$registrations[$id]['agent'] = $row['agent'] ?? '';
$registrations[$id]['host'] = $row['host'] ?? '';
$registrations[$id]['network-ip'] = $row['network-ip'] ?? '';
$registrations[$id]['network-port'] = $row['network-port'] ?? '';
$registrations[$id]['sip-auth-user'] = $row['sip-auth-user'] ?? '';
$registrations[$id]['sip-auth-realm'] = $row['sip-auth-realm'] ?? '';
$registrations[$id]['mwi-account'] = $row['mwi-account'] ?? '';
$registrations[$id]['status'] = $row['status'] ?? '';
$registrations[$id]['ping-time'] = $row['ping-time'] ?? '';
$registrations[$id]['ping-status'] = $row['ping-status'] ?? '';
$registrations[$id]['sip_profile_name'] = $field['sip_profile_name'];
//get network-ip to url or blank
if (isset($row['network-ip'])) {
$registrations[$id]['network-ip'] = $row['network-ip'];
} else {
$registrations[$id]['network-ip'] = '';
}
//get the LAN IP address if it exists replace the external ip
$call_id_array = explode('@', $row['call-id'] ?? '');
if (isset($call_id_array[1])) {
$agent = $row['agent'];
$lan_ip = $call_id_array[1];
if (!empty($agent) && (false !== stripos($agent, 'grandstream') || false !== stripos($agent, 'ooma'))) {
$lan_ip = str_ireplace(
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
$lan_ip);
} elseif (!empty($agent) && 1 === preg_match('/\ACL750A/', $agent)) {
//required for GIGASET Sculpture CL750A puts _ in it's lan ip account
$lan_ip = preg_replace('/_/', '.', $lan_ip);
}
$registrations[$id]['lan-ip'] = $lan_ip;
} elseif (preg_match('/real=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $row['contact'] ?? '', $ip_match)) {
//get ip address for snom phones
$lan_ip = str_replace('real=', '', $ip_match[0]);
$registrations[$id]['lan-ip'] = $lan_ip;
} elseif (preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $row['contact'] ?? '', $ip_match)) {
$lan_ip = preg_replace('/_/', '.', $ip_match[0]);
$registrations[$id]['lan-ip'] = $lan_ip;
} else {
$registrations[$id]['lan-ip'] = '';
}
//remove unrelated domains
if (!permission_exists('registration_all') || $this->show != 'all') {
if ($registrations[$id]['sip-auth-realm'] == $this->domain_name) {
} elseif ($user_array[1] == $this->domain_name) {
} else {
unset($registrations[$id]);
}
}
//increment the array id
$id++;
}
unset($array);
}
}
}
//return the registrations array
return $registrations ?? null;
}
/**
* Retrieves the registration count for a given SIP profile.
*
* @param string|null $profile The name of the SIP profile to retrieve. Defaults to 'all'.
*
* @return int The registration count, or 0 if no profiles are found.
*/
public function count($profile = 'all') {
//use get the registrations to count
$registrations = $this->get($profile);
//set the count
$count = !empty($registrations) ? @sizeof($registrations) : 0;
//return the registrations count
return $count;
}
/**
* Unregisters a list of registrations from a given SIP profile or all profiles if no profile is specified.
*
* @param array $registrations The list of registrations to unregister, keyed by SIP URI.
*
* @return void This method does not return any value.
*/
public function unregister($registrations) {
$this->switch_api('unregister', $registrations);
}
/**
* Provision a set of SIP registrations.
*
* @param array $registrations The list of registrations to provision.
*
* @returnvoid This method does not return any value.
*/
public function provision($registrations) {
$this->switch_api('provision', $registrations);
}
/**
* Initiates a system reboot with the specified registrations.
*
* @param array $registrations The list of registrations to persist before rebooting.
*
* @return void This method does not return any value.
*/
public function reboot($registrations) {
$this->switch_api('reboot', $registrations);
}
/**
* Processes API commands for a list of registered devices.
*
* This will cause execution to exit.
*
* @param string $action The action to perform (unregister, provision, reboot).
* @param array $records The list of registered devices.
*
* @return void
*/
private function switch_api($action, $records) {
if (permission_exists($this->permission_prefix . 'domain') || permission_exists($this->permission_prefix . 'all') || if_group('superadmin')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//filter out unchecked registrations
if (is_array($records) && @sizeof($records) != 0) {
foreach ($records as $record) {
if ($record['checked'] == 'true' && !empty($record['user']) && !empty($record['profile'])) {
$registrations[] = $record;
}
}
}
//process checked registrations
if (is_array($registrations) && @sizeof($registrations) != 0) {
//retrieve sip profiles list
$sql = "select sip_profile_name as name from v_sip_profiles ";
$sip_profiles = $this->database->select($sql, null, 'all');
unset($sql);
//create the event socket connection
$event_socket = $this->event_socket;
//loop through registrations
if ($event_socket->is_connected()) {
//check if registrations exist
if (is_array($registrations)) {
foreach ($registrations as $registration) {
//validate the submitted profile
if (!empty($registration['profile']) && is_array($sip_profiles) && @sizeof($sip_profiles) != 0) {
foreach ($sip_profiles as $field) {
if ($field['name'] == $registration['profile']) {
$profile = $registration['profile'];
break;
}
}
} else {
header('Location: ' . $this->list_page);
exit;
}
//validate the submitted user
if (!empty($registration['user'])) {
$user = preg_replace('#[^a-zA-Z0-9_\-\.\@]#', '', $registration['user']);
}
//validate the submitted host
if (!empty($registration['host'])) {
$host = preg_replace('#[^a-zA-Z0-9_\-\.]#', '', $registration['host']);
}
//lookup vendor by agent
if (!empty($registration['agent'])) {
$vendor = device::get_vendor_by_agent($registration['agent']);
}
//prepare the api command
if (!empty($profile) && $user) {
switch ($action) {
case 'unregister':
$command = "sofia profile " . $profile . " flush_inbound_reg " . $user . " reboot";
$response_message = $text['message-registrations_unregistered'];
break;
case 'provision':
if ($vendor && $host) {
$command = "lua app.lua event_notify " . $profile . " check_sync " . $user . " " . $vendor . " " . $host;
$response_message = $text['message-registrations_provisioned'];
}
break;
case 'reboot':
if ($vendor && $host) {
$command = "lua app.lua event_notify " . $profile . " reboot " . $user . " " . $vendor . " " . $host;
$response_message = $text['message-registrations_rebooted'];
}
break;
default:
header('Location: ' . $this->list_page);
exit;
}
}
//send the api command
if (!empty($command) && $event_socket->is_connected()) {
$response = $event_socket->request('api ' . $command);
$response_api[$user]['command'] = $command;
$response_api[$user]['log'] = $response;
} }
} }
} }
//process checked registrations //set message
if (is_array($registrations) && @sizeof($registrations) != 0) { if (is_array($response_api)) {
$message = '';
//retrieve sip profiles list foreach ($response_api as $registration_user => $response) {
$sql = "select sip_profile_name as name from v_sip_profiles "; if (is_array($response['command'])) {
$sip_profiles = $this->database->select($sql, null, 'all'); foreach ($response['command'] as $command) {
unset($sql); $command = trim($command ?? '');
if ($command !== '-ERR no reply') {
//create the event socket connection $message .= "<br>\n<strong>" . escape($registration_user) . "</strong>: " . escape($response_message);
$event_socket = $this->event_socket;
//loop through registrations
if ($event_socket->is_connected()) {
//check if registrations exist
if (is_array($registrations)) {
foreach ($registrations as $registration) {
//validate the submitted profile
if (!empty($registration['profile']) && is_array($sip_profiles) && @sizeof($sip_profiles) != 0) {
foreach ($sip_profiles as $field) {
if ($field['name'] == $registration['profile']) {
$profile = $registration['profile'];
break;
}
}
}
else {
header('Location: '.$this->list_page);
exit;
}
//validate the submitted user
if (!empty($registration['user'])) {
$user = preg_replace('#[^a-zA-Z0-9_\-\.\@]#', '', $registration['user']);
}
//validate the submitted host
if (!empty($registration['host'])) {
$host = preg_replace('#[^a-zA-Z0-9_\-\.]#', '', $registration['host']);
}
//lookup vendor by agent
if (!empty($registration['agent'])) {
$vendor = device::get_vendor_by_agent($registration['agent']);
}
//prepare the api command
if (!empty($profile) && $user) {
switch ($action) {
case 'unregister':
$command = "sofia profile ".$profile." flush_inbound_reg ".$user." reboot";
$response_message = $text['message-registrations_unregistered'];
break;
case 'provision':
if ($vendor && $host) {
$command = "lua app.lua event_notify ".$profile." check_sync ".$user." ".$vendor." ".$host;
$response_message = $text['message-registrations_provisioned'];
}
break;
case 'reboot':
if ($vendor && $host) {
$command = "lua app.lua event_notify ".$profile." reboot ".$user." ".$vendor." ".$host;
$response_message = $text['message-registrations_rebooted'];
}
break;
default:
header('Location: '.$this->list_page);
exit;
}
}
//send the api command
if (!empty($command) && $event_socket->is_connected()) {
$response = $event_socket->request('api ' . $command);
$response_api[$user]['command'] = $command;
$response_api[$user]['log'] = $response;
}
} }
} }
} else {
//set message if (!empty($response['command']) && $response['command'] !== '-ERR no reply') {
if (is_array($response_api)) { $message .= "<br>\n<strong>" . escape($registration_user) . "</strong>: " . escape($response_message);
$message = ''; }
foreach ($response_api as $registration_user => $response) {
if (is_array($response['command'])) {
foreach($response['command'] as $command) {
$command = trim($command ?? '');
if ($command !== '-ERR no reply') {
$message .= "<br>\n<strong>".escape($registration_user)."</strong>: ".escape($response_message);
}
}
}
else {
if (!empty($response['command']) && $response['command'] !== '-ERR no reply') {
$message .= "<br>\n<strong>".escape($registration_user)."</strong>: ".escape($response_message);
}
}
}
message::add($message, 'positive', '7000');
}
} }
else { }
message::add($text['error-event-socket'], 'negative', 5000); message::add($message, 'positive', '7000');
}
} }
} else {
message::add($text['error-event-socket'], 'negative', 5000);
}
} }
} //method
} //class }
} //method
} //class

File diff suppressed because it is too large Load Diff

View File

@@ -25,420 +25,456 @@
*/ */
//define the sip profiles class //define the sip profiles class
class sip_profiles { class sip_profiles {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'sip_profiles'; const app_name = 'sip_profiles';
const app_uuid = 'a6a7c4c5-340a-43ce-bcbc-2ed9bab8659d'; const app_uuid = 'a6a7c4c5-340a-43ce-bcbc-2ed9bab8659d';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/**
* Settings object set in the constructor. Must be a settings object and cannot be null. /**
* @var settings Settings Object * Settings object set in the constructor. Must be a settings object and cannot be null.
*/ *
private $settings; * @var settings Settings Object
*/
/** private $settings;
* User 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 /**
*/ * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
private $user_uuid; * the session global array
*
/** * @var string
* 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 $user_uuid;
*/
private $domain_uuid; /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
/** * in the session global array
* declare private variables *
*/ * @var string
private $permission_prefix; */
private $list_page; private $domain_uuid;
private $table;
private $uuid_prefix; /**
private $toggle_field; * declare private variables
private $toggle_values; */
private $permission_prefix;
/** private $list_page;
* declare public variables private $table;
*/ private $uuid_prefix;
public $sip_profile_uuid; private $toggle_field;
private $toggle_values;
/**
* called when the object is created /**
*/ * declare public variables
public function __construct(array $setting_array = []) { */
//set domain and user UUIDs public $sip_profile_uuid;
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; /**
* Initializes the object with setting array.
//set objects *
$this->database = $setting_array['database'] ?? database::new(); * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); * an empty array.
*
//assign private variables * @return void
$this->permission_prefix = 'sip_profile_'; */
$this->list_page = 'sip_profiles.php'; public function __construct(array $setting_array = []) {
$this->table = 'sip_profiles'; //set domain and user UUIDs
$this->uuid_prefix = 'sip_profile_'; $this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->toggle_field = 'sip_profile_enabled'; $this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
$this->toggle_values = ['true','false'];
} //set objects
$this->database = $setting_array['database'] ?? database::new();
/** $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
* delete records
*/ //assign private variables
public function delete($records) { $this->permission_prefix = 'sip_profile_';
if (permission_exists($this->permission_prefix.'delete')) { $this->list_page = 'sip_profiles.php';
$this->table = 'sip_profiles';
//add multi-lingual support $this->uuid_prefix = 'sip_profile_';
$language = new text; $this->toggle_field = 'sip_profile_enabled';
$text = $language->get(); $this->toggle_values = ['true', 'false'];
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked sip profiles, build where clause for below
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//get necessary sip profile details
$sql = "select ".$this->uuid_prefix."uuid as uuid, sip_profile_name, sip_profile_hostname from v_".$this->table." ";
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$sip_profiles[$row['uuid']]['name'] = $row['sip_profile_name'];
$sip_profiles[$row['uuid']]['hostname'] = $row['sip_profile_hostname'];
}
}
unset($sql, $parameters, $rows, $row);
//build the delete array
$x = 0;
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $sip_profile_uuid;
$array['sip_profile_domains'][$x][$this->uuid_prefix.'uuid'] = $sip_profile_uuid;
$array['sip_profile_settings'][$x][$this->uuid_prefix.'uuid'] = $sip_profile_uuid;
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('sip_profile_domain_delete', 'temp');
$p->add('sip_profile_setting_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('sip_profile_domain_delete', 'temp');
$p->delete('sip_profile_setting_delete', 'temp');
//delete the xml sip profile and directory
$switch_conf_dir = $this->settings->get('switch', 'conf');
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
@unlink($switch_conf_dir."/sip_profiles/".$sip_profile['name'].".xml");
@unlink($switch_conf_dir."/sip_profiles/".$sip_profile['name']);
}
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//determine hostnames, get system hostname if necessary
$empty_hostname = false;
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
if ($sip_profile['hostname'] != '') {
$hostnames[] = $sip_profile['hostname'];
}
else {
$empty_hostname = true;
}
}
if ($empty_hostname) {
$hostnames[] = gethostname();
}
//clear the cache
if (is_array($hostnames) && @sizeof($hostnames) != 0) {
$hostnames = array_unique($hostnames);
$cache = new cache;
foreach ($hostnames as $hostname) {
$cache->delete($hostname.":configuration:sofia.conf");
}
}
//set message
message::add($text['message-delete']);
}
unset($records, $sip_profiles);
}
}
}
public function delete_domains($records) {
//assign private variables
$this->permission_prefix = 'sip_profile_domain_';
$this->list_page = 'sip_profile_edit.php?id='.$this->sip_profile_uuid;
$this->table = 'sip_profile_domains';
$this->uuid_prefix = 'sip_profile_domain_';
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked sip profiles, build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['sip_profile_uuid'] = $this->sip_profile_uuid;
}
}
//get necessary sip profile details
if (!empty($this->sip_profile_uuid) && is_uuid($this->sip_profile_uuid)) {
$sql = "select sip_profile_hostname from v_sip_profiles ";
$sql .= "where sip_profile_uuid = :sip_profile_uuid ";
$parameters['sip_profile_uuid'] = $this->sip_profile_uuid;
$sip_profile_hostname = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
}
//delete the checked rows
if (!empty($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//get system hostname if necessary
if (empty($sip_profile_hostname)) {
$sip_profile_hostname = gethostname();
}
//clear the cache
if (!empty($sip_profile_hostname)) {
$cache = new cache;
$cache->delete($sip_profile_hostname.":configuration:sofia.conf");
}
}
unset($records);
}
}
}
public function delete_settings($records) {
//assign private variables
$this->permission_prefix = 'sip_profile_setting_';
$this->list_page = 'sip_profile_edit.php?id='.$this->sip_profile_uuid;
$this->table = 'sip_profile_settings';
$this->uuid_prefix = 'sip_profile_setting_';
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (!empty($records) && @sizeof($records) != 0) {
//filter out unchecked sip profiles, build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array[$this->table][$x]['sip_profile_uuid'] = $this->sip_profile_uuid;
}
}
//get necessary sip profile details
if (!empty($this->sip_profile_uuid) && is_uuid($this->sip_profile_uuid)) {
$sql = "select sip_profile_hostname from v_sip_profiles ";
$sql .= "where sip_profile_uuid = :sip_profile_uuid ";
$parameters['sip_profile_uuid'] = $this->sip_profile_uuid;
$sip_profile_hostname = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
}
//delete the checked rows
if (!empty($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//get system hostname if necessary
if (empty($sip_profile_hostname)) {
$sip_profile_hostname = gethostname();
}
//clear the cache
if (!empty($sip_profile_hostname)) {
$cache = new cache;
$cache->delete($sip_profile_hostname.":configuration:sofia.conf");
}
}
unset($records);
}
}
}
/**
* toggle records
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (!empty($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, sip_profile_hostname from v_".$this->table." ";
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$sip_profiles[$row['uuid']]['state'] = $row['toggle'];
$sip_profiles[$row['uuid']]['hostname'] = $row['sip_profile_hostname'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($sip_profiles as $uuid => $sip_profile) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $sip_profile['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (!empty($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//determine hostnames, get system hostname if necessary
$empty_hostname = false;
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
if ($sip_profile['hostname'] != '') {
$hostnames[] = $sip_profile['hostname'];
}
else {
$empty_hostname = true;
}
}
if ($empty_hostname) {
$esl = event_socket::create();
if ($esl->is_connected()) {
$hostnames[] = gethostname();
}
}
//clear the cache
if (!empty($hostnames) && @sizeof($hostnames) != 0) {
$hostnames = array_unique($hostnames);
$cache = new cache;
foreach ($hostnames as $hostname) {
$cache->delete($hostname.":configuration:sofia.conf");
}
}
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked sip profiles, build where clause for below
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//get necessary sip profile details
$sql = "select " . $this->uuid_prefix . "uuid as uuid, sip_profile_name, sip_profile_hostname from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$sip_profiles[$row['uuid']]['name'] = $row['sip_profile_name'];
$sip_profiles[$row['uuid']]['hostname'] = $row['sip_profile_hostname'];
}
}
unset($sql, $parameters, $rows, $row);
//build the delete array
$x = 0;
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $sip_profile_uuid;
$array['sip_profile_domains'][$x][$this->uuid_prefix . 'uuid'] = $sip_profile_uuid;
$array['sip_profile_settings'][$x][$this->uuid_prefix . 'uuid'] = $sip_profile_uuid;
$x++;
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('sip_profile_domain_delete', 'temp');
$p->add('sip_profile_setting_delete', 'temp');
//execute delete
$this->database->delete($array);
unset($array);
//revoke temporary permissions
$p->delete('sip_profile_domain_delete', 'temp');
$p->delete('sip_profile_setting_delete', 'temp');
//delete the xml sip profile and directory
$switch_conf_dir = $this->settings->get('switch', 'conf');
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
@unlink($switch_conf_dir . "/sip_profiles/" . $sip_profile['name'] . ".xml");
@unlink($switch_conf_dir . "/sip_profiles/" . $sip_profile['name']);
}
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//determine hostnames, get system hostname if necessary
$empty_hostname = false;
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
if ($sip_profile['hostname'] != '') {
$hostnames[] = $sip_profile['hostname'];
} else {
$empty_hostname = true;
}
}
if ($empty_hostname) {
$hostnames[] = gethostname();
}
//clear the cache
if (is_array($hostnames) && @sizeof($hostnames) != 0) {
$hostnames = array_unique($hostnames);
$cache = new cache;
foreach ($hostnames as $hostname) {
$cache->delete($hostname . ":configuration:sofia.conf");
}
}
//set message
message::add($text['message-delete']);
}
unset($records, $sip_profiles);
}
}
}
/**
* Deletes specified domains from the system.
*
* @param array $records An array of records to be deleted, each containing 'checked' and 'uuid' keys.
*
* @return void
*/
public function delete_domains($records) {
//assign private variables
$this->permission_prefix = 'sip_profile_domain_';
$this->list_page = 'sip_profile_edit.php?id=' . $this->sip_profile_uuid;
$this->table = 'sip_profile_domains';
$this->uuid_prefix = 'sip_profile_domain_';
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked sip profiles, build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['sip_profile_uuid'] = $this->sip_profile_uuid;
}
}
//get necessary sip profile details
if (!empty($this->sip_profile_uuid) && is_uuid($this->sip_profile_uuid)) {
$sql = "select sip_profile_hostname from v_sip_profiles ";
$sql .= "where sip_profile_uuid = :sip_profile_uuid ";
$parameters['sip_profile_uuid'] = $this->sip_profile_uuid;
$sip_profile_hostname = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
}
//delete the checked rows
if (!empty($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//get system hostname if necessary
if (empty($sip_profile_hostname)) {
$sip_profile_hostname = gethostname();
}
//clear the cache
if (!empty($sip_profile_hostname)) {
$cache = new cache;
$cache->delete($sip_profile_hostname . ":configuration:sofia.conf");
}
}
unset($records);
}
}
}
/**
* Deletes settings for one or more sip profiles.
*
* @param array $records An associative array containing the records to delete, where each record is an associative array
* with 'uuid' and optionally 'checked' keys. Defaults to an empty array.
*
* @return void
*/
public function delete_settings($records) {
//assign private variables
$this->permission_prefix = 'sip_profile_setting_';
$this->list_page = 'sip_profile_edit.php?id=' . $this->sip_profile_uuid;
$this->table = 'sip_profile_settings';
$this->uuid_prefix = 'sip_profile_setting_';
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (!empty($records) && @sizeof($records) != 0) {
//filter out unchecked sip profiles, build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
$array[$this->table][$x]['sip_profile_uuid'] = $this->sip_profile_uuid;
}
}
//get necessary sip profile details
if (!empty($this->sip_profile_uuid) && is_uuid($this->sip_profile_uuid)) {
$sql = "select sip_profile_hostname from v_sip_profiles ";
$sql .= "where sip_profile_uuid = :sip_profile_uuid ";
$parameters['sip_profile_uuid'] = $this->sip_profile_uuid;
$sip_profile_hostname = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
}
//delete the checked rows
if (!empty($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//get system hostname if necessary
if (empty($sip_profile_hostname)) {
$sip_profile_hostname = gethostname();
}
//clear the cache
if (!empty($sip_profile_hostname)) {
$cache = new cache;
$cache->delete($sip_profile_hostname . ":configuration:sofia.conf");
}
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (!empty($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle, sip_profile_hostname from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$sip_profiles[$row['uuid']]['state'] = $row['toggle'];
$sip_profiles[$row['uuid']]['hostname'] = $row['sip_profile_hostname'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($sip_profiles as $uuid => $sip_profile) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $sip_profile['state'] == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (!empty($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//determine hostnames, get system hostname if necessary
$empty_hostname = false;
foreach ($sip_profiles as $sip_profile_uuid => $sip_profile) {
if ($sip_profile['hostname'] != '') {
$hostnames[] = $sip_profile['hostname'];
} else {
$empty_hostname = true;
}
}
if ($empty_hostname) {
$esl = event_socket::create();
if ($esl->is_connected()) {
$hostnames[] = gethostname();
}
}
//clear the cache
if (!empty($hostnames) && @sizeof($hostnames) != 0) {
$hostnames = array_unique($hostnames);
$cache = new cache;
foreach ($hostnames as $hostname) {
$cache->delete($hostname . ":configuration:sofia.conf");
}
}
//save the sip profile xml
save_sip_profile_xml();
//apply settings reminder
$_SESSION["reload_xml"] = true;
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
}

View File

@@ -88,6 +88,14 @@
} }
//sort the array //sort the array
/**
* Compares two XML elements based on their names and sorts them in a natural order.
*
* @param object $a The first XML element to compare.
* @param object $b The second XML element to compare.
*
* @return int A negative integer, zero, or a positive integer if $a's name is less than, equal to, or greater than $b's name respectively.
*/
function sort_xml($a, $b) { function sort_xml($a, $b) {
return strnatcmp($a->name, $b->name); return strnatcmp($a->name, $b->name);
} }

View File

@@ -27,216 +27,239 @@
/** /**
* sofia_global_settings class * sofia_global_settings class
*/ */
class sofia_global_settings { class sofia_global_settings {
/**
* declare constant variables
*/
const app_name = 'sofia_global_settings';
const app_uuid = '240c25a3-a2cf-44ea-a300-0626eca5b945';
/**
* declare the variables
*/
private $database;
private $name;
private $table;
private $toggle_field;
private $toggle_values;
private $description_field;
private $location;
/** /**
* called when the object is created * declare constant variables
*/ */
public function __construct(array $setting_array = []) { const app_name = 'sofia_global_settings';
//set objects const app_uuid = '240c25a3-a2cf-44ea-a300-0626eca5b945';
$this->database = $setting_array['database'] ?? database::new();
//assign the variables /**
$this->name = 'sofia_global_setting'; * declare the variables
$this->table = 'sofia_global_settings'; */
$this->toggle_field = 'global_setting_enabled'; private $database;
$this->toggle_values = ['true','false'];
$this->description_field = 'global_setting_description';
$this->location = 'sofia_global_settings.php';
}
/** private $name;
* delete rows from the database private $table;
*/ private $toggle_field;
public function delete($records) { private $toggle_values;
if (permission_exists($this->name.'_delete')) { private $description_field;
private $location;
//add multi-lingual support /**
$language = new text; * Initializes the object with setting array.
$text = $language->get(); *
* @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//validate the token * an empty array.
$token = new token; *
if (!$token->validate($_SERVER['PHP_SELF'])) { * @return void
message::add($text['message-invalid_token'],'negative'); */
header('Location: '.$this->location); public function __construct(array $setting_array = []) {
exit; //set objects
} $this->database = $setting_array['database'] ?? database::new();
//delete multiple records
if (!empty($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['sofia_global_setting_uuid'])) {
$array[$this->table][$x]['sofia_global_setting_uuid'] = $record['sofia_global_setting_uuid'];
}
//increment the id
$x++;
}
//delete the checked rows
if (!empty($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle a field between two values
*/
public function toggle($records) {
if (permission_exists($this->name.'_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//toggle the checked records
if (!empty($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['sofia_global_setting_uuid'])) {
$uuids[] = "'".$record['sofia_global_setting_uuid']."'";
}
}
if (!empty($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, null, 'all');
if (!empty($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (!empty($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy rows from the database
*/
public function copy($records) {
if (permission_exists($this->name.'_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//copy the checked records
if (!empty($records) && @sizeof($records) != 0) {
//get checked records
foreach($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['sofia_global_setting_uuid'])) {
$uuids[] = "'".$record['sofia_global_setting_uuid']."'";
}
}
//create the array from existing data
if (!empty($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where sofia_global_setting_uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, null, 'all');
if (!empty($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name.'_uuid'] = uuid();
$array[$this->table][$x]['global_setting_enabled'] = $row['global_setting_enabled'] === true ? 'true' : 'false';
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '').trim(' ('.$text['label-copy'].')');
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (!empty($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign the variables
$this->name = 'sofia_global_setting';
$this->table = 'sofia_global_settings';
$this->toggle_field = 'global_setting_enabled';
$this->toggle_values = ['true', 'false'];
$this->description_field = 'global_setting_description';
$this->location = 'sofia_global_settings.php';
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->name . '_delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//delete multiple records
if (!empty($records) && @sizeof($records) != 0) {
//build the delete array
$x = 0;
foreach ($records as $record) {
//add to the array
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['sofia_global_setting_uuid'])) {
$array[$this->table][$x]['sofia_global_setting_uuid'] = $record['sofia_global_setting_uuid'];
}
//increment the id
$x++;
}
//delete the checked rows
if (!empty($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->name . '_edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//toggle the checked records
if (!empty($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['sofia_global_setting_uuid'])) {
$uuids[] = "'" . $record['sofia_global_setting_uuid'] . "'";
}
}
if (!empty($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (!empty($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
//create the array
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
//increment the id
$x++;
}
//save the changes
if (!empty($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->name . '_add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->location);
exit;
}
//copy the checked records
if (!empty($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['sofia_global_setting_uuid'])) {
$uuids[] = "'" . $record['sofia_global_setting_uuid'] . "'";
}
}
//create the array from existing data
if (!empty($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where sofia_global_setting_uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, null, 'all');
if (!empty($rows) && @sizeof($rows) != 0) {
$x = 0;
foreach ($rows as $row) {
//copy data
$array[$this->table][$x] = $row;
//add copy to the description
$array[$this->table][$x][$this->name . '_uuid'] = uuid();
$array[$this->table][$x]['global_setting_enabled'] = $row['global_setting_enabled'] === true ? 'true' : 'false';
$array[$this->table][$x][$this->description_field] = trim($row[$this->description_field] ?? '') . trim(' (' . $text['label-copy'] . ')');
//increment the id
$x++;
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (!empty($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -25,262 +25,295 @@
*/ */
//define the streams class //define the streams class
class streams { class streams {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'streams'; const app_name = 'streams';
const app_uuid = 'ffde6287-aa18-41fc-9a38-076d292e0a38'; const app_uuid = 'ffde6287-aa18-41fc-9a38-076d292e0a38';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Username set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Username set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $username; * @var string
*/
private $username;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
* @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//assign private variables
$this->permission_prefix = 'stream_';
$this->list_page = 'streams.php';
$this->table = 'streams';
$this->uuid_prefix = 'stream_';
$this->toggle_field = 'stream_enabled';
$this->toggle_values = ['true','false'];
}
/**
* delete records
*/
public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* toggle records
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* copy records
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = uuid();
$array[$this->table][$x]['stream_description'] = trim($row['stream_description'].' ('.$text['label-copy'].')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
//assign private variables
$this->permission_prefix = 'stream_';
$this->list_page = 'streams.php';
$this->table = 'streams';
$this->uuid_prefix = 'stream_';
$this->toggle_field = 'stream_enabled';
$this->toggle_values = ['true', 'false'];
} }
/**
* Deletes 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 delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//build the delete array
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
}
}
/**
* Copies one or more records
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//copy the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select * from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $x => $row) {
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = uuid();
$array[$this->table][$x]['stream_description'] = trim($row['stream_description'] . ' (' . $text['label-copy'] . ')');
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//save the array
$this->database->save($array);
unset($array);
//set message
message::add($text['message-copy']);
}
unset($records);
}
}
}
}

View File

@@ -24,77 +24,87 @@
/** /**
* presence class * presence class
*/ */
class presence { class presence {
/** /**
* active presence * Check if presence is active
* @var string $presence_id *
*/ * @param string $presence_id Presence ID to check for activity
public function active($presence_id) { *
$json = event_socket::api('show calls as json'); * @return bool True if presence is active, False otherwise
$call_array = json_decode($json, true); */
if (isset($call_array['rows'])) { public function active($presence_id) {
$x = 0; $json = event_socket::api('show calls as json');
foreach ($call_array['rows'] as $row) { $call_array = json_decode($json, true);
if ($row['presence_id'] == $presence_id) { if (isset($call_array['rows'])) {
$x = 0;
foreach ($call_array['rows'] as $row) {
if ($row['presence_id'] == $presence_id) {
return true;
}
if (isset($row['b_presence_id']) && $row['b_presence_id'] != 0) {
if ($row['b_presence_id'] == $presence_id) {
return true; return true;
} }
if (isset($row['b_presence_id']) && $row['b_presence_id'] != 0) {
if ($row['b_presence_id'] == $presence_id) {
return true;
}
$x++;
}
$x++; $x++;
} }
$x++;
} }
return false;
}
/**
* show presence
*/
public function show() {
$array = [];
$json = event_socket::api('show calls as json');
$call_array = json_decode($json, true);
if (isset($call_array['rows'])) {
$x = 0;
foreach ($call_array['rows'] as $row) {
$array[$x]['presence_id'] = $row['presence_id'];
$array[$x]['presence_user'] = explode('@', $row['presence_id'])[0];
$array[$x]['domain_name'] = explode('@', $row['presence_id'])[1];
if (isset($row['b_presence_id']) && $row['b_presence_id'] != 0) {
$x++;
$array[$x]['presence_id'] = $row['b_presence_id'];
$array[$x]['presence_user'] = explode('@', $row['b_presence_id'])[0];
$array[$x]['domain_name'] = explode('@', $row['b_presence_id'])[1];
}
$x++;
}
}
return $array;
} }
return false;
} }
/**
* Retrieves and processes data from the event socket API.
*
* This method sends a 'show calls as json' request to the event socket API,
* decodes the response, and returns an array containing presence information
* for each user. The array is indexed by the index of the row in the original
* JSON response, with keys for presence_id, presence_user, and domain_name.
*
* @return array An array of arrays containing presence information.
*/
public function show() {
$array = [];
$json = event_socket::api('show calls as json');
$call_array = json_decode($json, true);
if (isset($call_array['rows'])) {
$x = 0;
foreach ($call_array['rows'] as $row) {
$array[$x]['presence_id'] = $row['presence_id'];
$array[$x]['presence_user'] = explode('@', $row['presence_id'])[0];
$array[$x]['domain_name'] = explode('@', $row['presence_id'])[1];
if (isset($row['b_presence_id']) && $row['b_presence_id'] != 0) {
$x++;
$array[$x]['presence_id'] = $row['b_presence_id'];
$array[$x]['presence_user'] = explode('@', $row['b_presence_id'])[0];
$array[$x]['domain_name'] = explode('@', $row['b_presence_id'])[1];
}
$x++;
}
}
return $array;
}
}
//examples //examples
/* /*
//check if presence is active //check if presence is active
$presence_id = '103@'.$_SESSION['domain_name']; $presence_id = '103@'.$_SESSION['domain_name'];
$presence = new presence; $presence = new presence;
$result = $presence->active($presence_id); $result = $presence->active($presence_id);
echo "presence_id $presence_id<br />\n"; echo "presence_id $presence_id<br />\n";
if ($result) { if ($result) {
echo "active: true\n"; echo "active: true\n";
} }
else { else {
echo "active: false\n"; echo "active: false\n";
} }
//show active the presence //show active the presence
$presence = new presence; $presence = new presence;
$array = $presence->show(); $array = $presence->show();
*/ */

View File

@@ -25,258 +25,287 @@
Matthew Vale <github@mafoo.org> Matthew Vale <github@mafoo.org>
*/ */
class ringbacks { class ringbacks {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'ringbacks'; const app_name = 'ringbacks';
const app_uuid = 'b63db353-e1c6-4401-8f10-101a6ee73b74'; const app_uuid = 'b63db353-e1c6-4401-8f10-101a6ee73b74';
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
public $domain_uuid; * @var string
*/
public $domain_uuid;
/** /**
* declare public variables * declare public variables
*/ */
public $ringtones_list; public $ringtones_list;
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Username set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Username set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $username; * @var string
*/
private $username;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $tones_list; private $tones_list;
private $music_list; private $music_list;
private $recordings_list; private $recordings_list;
private $default_ringback_label; private $default_ringback_label;
private $streams; private $streams;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; * @return void
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; */
$this->username = $setting_array['username'] ?? $_SESSION['username'] ?? ''; public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
$this->username = $setting_array['username'] ?? $_SESSION['username'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//get the ringtones //get the ringtones
$sql = "select * from v_vars "; $sql = "select * from v_vars ";
$sql .= "where var_category = 'Ringtones' "; $sql .= "where var_category = 'Ringtones' ";
$sql .= "order by var_name asc "; $sql .= "order by var_name asc ";
$ringtones = $this->database->select($sql, null, 'all'); $ringtones = $this->database->select($sql, null, 'all');
if (!empty($ringtones)) { if (!empty($ringtones)) {
foreach ($ringtones as $ringtone) { foreach ($ringtones as $ringtone) {
$ringtone = $ringtone['var_name']; $ringtone = $ringtone['var_name'];
if (isset($text['label-'.$ringtone])) { if (isset($text['label-' . $ringtone])) {
$label = $text['label-'.$ringtone]; $label = $text['label-' . $ringtone];
} } else {
else { $label = $ringtone;
$label = $ringtone;
}
$ringtones_list[$ringtone] = $label;
} }
} $ringtones_list[$ringtone] = $label;
$this->ringtones_list = $ringtones_list ?? '';
unset($sql, $ringtones, $ringtone, $ringtones_list);
//get the default_ringback label
/*
$sql = "select * from v_vars where var_name = 'ringback' ";
$row = $this->database->select($sql, null, 'row');
unset($sql);
$default_ringback = (string) $row['var_value'];
$default_ringback = preg_replace('/\A\$\${/',"",$default_ringback);
$default_ringback = preg_replace('/}\z/',"",$default_ringback);
#$label = $text['label-'.$default_ringback];
#if($label == "") {
$label = $default_ringback;
#}
$this->default_ringback_label = $label;
unset($results, $default_ringback, $label);
*/
//get the tones
$tones = new tones;
$this->tones_list = $tones->tones_list();
//get music on hold and recordings
if (is_dir($_SERVER["PROJECT_ROOT"].'/app/music_on_hold')) {
$music = new switch_music_on_hold;
$this->music_list = $music->get();
}
if (is_dir($_SERVER["PROJECT_ROOT"].'/app/recordings')) {
$recordings = new switch_recordings;
$this->recordings_list = $recordings->list_recordings();
}
if (is_dir($_SERVER["PROJECT_ROOT"].'/app/streams')) {
$sql = "select * from v_streams ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and stream_enabled = 'true' ";
$sql .= "order by stream_name asc ";
$parameters['domain_uuid'] = $this->domain_uuid;
$streams = $this->database->select($sql, $parameters, 'all');
$this->streams = $streams;
unset($sql, $parameters, $streams, $row);
} }
} }
$this->ringtones_list = $ringtones_list ?? '';
unset($sql, $ringtones, $ringtone, $ringtones_list);
public function valid($value) { //get the default_ringback label
foreach($this->ringtones_list as $ringtone_value => $ringtone_name) { /*
if ($value == "\${".$ringtone_value."}") { $sql = "select * from v_vars where var_name = 'ringback' ";
return true; $row = $this->database->select($sql, null, 'row');
} unset($sql);
} $default_ringback = (string) $row['var_value'];
$default_ringback = preg_replace('/\A\$\${/',"",$default_ringback);
$default_ringback = preg_replace('/}\z/',"",$default_ringback);
#$label = $text['label-'.$default_ringback];
#if($label == "") {
$label = $default_ringback;
#}
$this->default_ringback_label = $label;
unset($results, $default_ringback, $label);
*/
foreach($this->tones_list as $tone_value => $tone_name) { //get the tones
if ($value == "\${".$tone_value."}") { $tones = new tones;
return true; $this->tones_list = $tones->tones_list();
}
}
foreach($this->music_list as $row) { //get music on hold and recordings
$name = ''; if (is_dir($_SERVER["PROJECT_ROOT"] . '/app/music_on_hold')) {
if (!empty($row['domain_uuid'])) { $music = new switch_music_on_hold;
$name = $row['domain_name'].'/'; $this->music_list = $music->get();
} }
$name .= $row['music_on_hold_name']; if (is_dir($_SERVER["PROJECT_ROOT"] . '/app/recordings')) {
if ($value == "local_stream://".$name) { $recordings = new switch_recordings;
return true; $this->recordings_list = $recordings->list_recordings();
}
}
foreach($this->recordings_list as $recording_value => $recording_name) {
if ($value == $recording_value) {
return true;
}
}
foreach($this->streams as $row) {
if ($value == $row['stream_location']) {
return true;
}
}
return false;
} }
public function select($name, $selected) { if (is_dir($_SERVER["PROJECT_ROOT"] . '/app/streams')) {
//add multi-lingual support $sql = "select * from v_streams ";
$language = new text; $sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$text = $language->get(); $sql .= "and stream_enabled = 'true' ";
$sql .= "order by stream_name asc ";
//start the select $parameters['domain_uuid'] = $this->domain_uuid;
$select = "<select class='formfld' name='".$name."' id='".$name."' style='width: auto;'>\n"; $streams = $this->database->select($sql, $parameters, 'all');
$select .= " <option value=''></option>\n"; $this->streams = $streams;
unset($sql, $parameters, $streams, $row);
//music list
if (!empty($this->music_list)) {
$select .= " <optgroup label='".$text['label-music_on_hold']."'>\n";
$previous_name = '';
foreach ($this->music_list as $row) {
if ($previous_name != $row['music_on_hold_name']) {
$name = '';
if (!empty($row['domain_uuid'])) {
$name = $row['domain_name'].'/';
}
$name .= $row['music_on_hold_name'];
$select .= " <option value='local_stream://".$name."' ".(($selected == "local_stream://".$name) ? 'selected="selected"' : null).">".$row['music_on_hold_name']."</option>\n";
}
$previous_name = $row['music_on_hold_name'];
}
$select .= " </optgroup>\n";
}
//recordings
if (!empty($this->recordings_list)) {
$select .= " <optgroup label='".$text['label-recordings']."'>";
foreach ($this->recordings_list as $recording_value => $recording_name) {
$select .= " <option value='".$recording_value."' ".(($selected == $recording_value) ? 'selected="selected"' : null).">".$recording_name."</option>\n";
}
$select .= " </optgroup>\n";
}
//streams
if (!empty($this->streams)) {
$select .= " <optgroup label='".$text['label-streams']."'>";
foreach ($this->streams as $row) {
$select .= " <option value='".$row['stream_location']."' ".(($selected == $row['stream_location']) ? 'selected="selected"' : null).">".$row['stream_name']."</option>\n";
}
$select .= " </optgroup>\n";
}
//ringtones
if (!empty($this->ringtones_list)) {
$selected_ringtone = $selected;
$selected_ringtone = preg_replace('/\A\${/',"",$selected_ringtone ?? '');
$selected_ringtone = preg_replace('/}\z/',"",$selected_ringtone);
$select .= " <optgroup label='".$text['label-ringtones']."'>";
//$select .= " <option value='default_ringtones'".(($selected == "default_ringback") ? ' selected="selected"' : '').">".$text['label-default']." (".$this->default_ringtone_label.")</option>\n";
foreach ($this->ringtones_list as $ringtone_value => $ringtone_name) {
$select .= " <option value='\${".$ringtone_value."}'".(($selected_ringtone == $ringtone_value) ? ' selected="selected"' : null).">".$ringtone_name."</option>\n";
}
//add silence option
$select .= " <option value='silence'>Silence</option>\n";
$select .= " </optgroup>\n";
unset($selected_ringtone);
}
//tones
if (!empty($this->tones_list)) {
$selected_tone = $selected;
$selected_tone = preg_replace('/\A\${/',"",$selected_tone ?? '');
$selected_tone = preg_replace('/}\z/',"",$selected_tone);
$select .= " <optgroup label='".$text['label-tones']."'>";
foreach($this->tones_list as $tone_value => $tone_name) {
$select .= " <option value='\${".$tone_value."}'".(($selected_tone == $tone_value) ? ' selected="selected"' : null).">".$tone_name."</option>\n";
}
$select .= " </optgroup>\n";
unset($selected_tone);
}
//end the select and return it
$select .= "</select>\n";
return $select;
} }
} }
/**
* Checks if a given value is valid.
*
* @param mixed $value The value to check for validity
*
* @return bool True if the value is valid, false otherwise
*/
public function valid($value) {
foreach ($this->ringtones_list as $ringtone_value => $ringtone_name) {
if ($value == "\${" . $ringtone_value . "}") {
return true;
}
}
foreach ($this->tones_list as $tone_value => $tone_name) {
if ($value == "\${" . $tone_value . "}") {
return true;
}
}
foreach ($this->music_list as $row) {
$name = '';
if (!empty($row['domain_uuid'])) {
$name = $row['domain_name'] . '/';
}
$name .= $row['music_on_hold_name'];
if ($value == "local_stream://" . $name) {
return true;
}
}
foreach ($this->recordings_list as $recording_value => $recording_name) {
if ($value == $recording_value) {
return true;
}
}
foreach ($this->streams as $row) {
if ($value == $row['stream_location']) {
return true;
}
}
return false;
}
/**
* Generates a HTML <select> element based on given name and selected value.
*
* @param string $name The name of the select element
* @param mixed $selected The currently selected value for the select element
*
* @return string A fully formed HTML <select> element with options populated from various lists (music, recordings, streams, ringtones, tones)
*/
public function select($name, $selected) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//start the select
$select = "<select class='formfld' name='" . $name . "' id='" . $name . "' style='width: auto;'>\n";
$select .= " <option value=''></option>\n";
//music list
if (!empty($this->music_list)) {
$select .= " <optgroup label='" . $text['label-music_on_hold'] . "'>\n";
$previous_name = '';
foreach ($this->music_list as $row) {
if ($previous_name != $row['music_on_hold_name']) {
$name = '';
if (!empty($row['domain_uuid'])) {
$name = $row['domain_name'] . '/';
}
$name .= $row['music_on_hold_name'];
$select .= " <option value='local_stream://" . $name . "' " . (($selected == "local_stream://" . $name) ? 'selected="selected"' : null) . ">" . $row['music_on_hold_name'] . "</option>\n";
}
$previous_name = $row['music_on_hold_name'];
}
$select .= " </optgroup>\n";
}
//recordings
if (!empty($this->recordings_list)) {
$select .= " <optgroup label='" . $text['label-recordings'] . "'>";
foreach ($this->recordings_list as $recording_value => $recording_name) {
$select .= " <option value='" . $recording_value . "' " . (($selected == $recording_value) ? 'selected="selected"' : null) . ">" . $recording_name . "</option>\n";
}
$select .= " </optgroup>\n";
}
//streams
if (!empty($this->streams)) {
$select .= " <optgroup label='" . $text['label-streams'] . "'>";
foreach ($this->streams as $row) {
$select .= " <option value='" . $row['stream_location'] . "' " . (($selected == $row['stream_location']) ? 'selected="selected"' : null) . ">" . $row['stream_name'] . "</option>\n";
}
$select .= " </optgroup>\n";
}
//ringtones
if (!empty($this->ringtones_list)) {
$selected_ringtone = $selected;
$selected_ringtone = preg_replace('/\A\${/', "", $selected_ringtone ?? '');
$selected_ringtone = preg_replace('/}\z/', "", $selected_ringtone);
$select .= " <optgroup label='" . $text['label-ringtones'] . "'>";
//$select .= " <option value='default_ringtones'".(($selected == "default_ringback") ? ' selected="selected"' : '').">".$text['label-default']." (".$this->default_ringtone_label.")</option>\n";
foreach ($this->ringtones_list as $ringtone_value => $ringtone_name) {
$select .= " <option value='\${" . $ringtone_value . "}'" . (($selected_ringtone == $ringtone_value) ? ' selected="selected"' : null) . ">" . $ringtone_name . "</option>\n";
}
//add silence option
$select .= " <option value='silence'>Silence</option>\n";
$select .= " </optgroup>\n";
unset($selected_ringtone);
}
//tones
if (!empty($this->tones_list)) {
$selected_tone = $selected;
$selected_tone = preg_replace('/\A\${/', "", $selected_tone ?? '');
$selected_tone = preg_replace('/}\z/', "", $selected_tone);
$select .= " <optgroup label='" . $text['label-tones'] . "'>";
foreach ($this->tones_list as $tone_value => $tone_name) {
$select .= " <option value='\${" . $tone_value . "}'" . (($selected_tone == $tone_value) ? ' selected="selected"' : null) . ">" . $tone_name . "</option>\n";
}
$select .= " </optgroup>\n";
unset($selected_tone);
}
//end the select and return it
$select .= "</select>\n";
return $select;
}
}

View File

@@ -27,130 +27,137 @@
/** /**
* switch class provides methods for copying switch_files * switch class provides methods for copying switch_files
*/ */
class switch_files { class switch_files {
private $config; private $config;
/** /**
* Called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set objects * an empty array.
$this->config = $setting_array['config'] ?? config::load(); *
* @return void
*/
public function __construct(array $setting_array = []) {
//set objects
$this->config = $setting_array['config'] ?? config::load();
}
/**
* Converts the given path to a platform-agnostic format.
*
* @param string $path The path to be converted.
*
* @return string The converted path. If running on Windows, backslashes are replaced with forward slashes.
*/
private function correct_path($path) {
global $IS_WINDOWS;
if ($IS_WINDOWS == null) {
if (stristr(PHP_OS, 'WIN')) {
$IS_WINDOWS = true;
} else {
$IS_WINDOWS = false;
}
}
if ($IS_WINDOWS) {
return str_replace('\\', '/', $path);
}
return $path;
}
/**
* Copy the switch scripts to the switch directory
*
* The function attempts to find the source and destination directories by checking various system locations. If
* neither is found, it throws an exception.
*
* @return void
*/
public function copy_scripts() {
//get the source directory
if (file_exists('/usr/share/examples/fusionpbx/scripts')) {
$source_directory = '/usr/share/examples/fusionpbx/scripts';
} elseif (file_exists('/usr/local/www/fusionpbx/app/switch/resources/scripts')) {
$source_directory = '/usr/local/www/fusionpbx/app/switch/resources/scripts';
} elseif (file_exists('/var/www/fusionpbx/app/switch/resources/scripts')) {
$source_directory = '/var/www/fusionpbx/app/switch/resources/scripts';
} else {
$source_directory = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/app/switch/resources/scripts';
} }
/** //get the destination directory
* Corrects the path for specifically for windows if (file_exists($this->config->get('switch.scripts.dir'))) {
*/ $destination_directory = $this->config->get('switch.scripts.dir');
private function correct_path($path) { } elseif (file_exists('/etc/freeswitch/scripts')) {
global $IS_WINDOWS; $destination_directory = '/etc/freeswitch/scripts';
if ($IS_WINDOWS == null) { } elseif (file_exists('/usr/local/freeswitch/scripts')) {
if (stristr(PHP_OS, 'WIN')) { $IS_WINDOWS = true; } else { $IS_WINDOWS = false; } $destination_directory = '/usr/local/freeswitch/scripts';
}
if ($IS_WINDOWS) {
return str_replace('\\', '/', $path);
}
return $path;
} }
/** //copy the scripts directory
* Copy the switch scripts to the switch directory if (!empty($source_directory) && is_readable($source_directory)) {
*/ //copy the main scripts
public function copy_scripts() { recursive_copy($source_directory, $destination_directory);
unset($source_directory);
//get the source directory //copy the app/*/resource/install/scripts
if (file_exists('/usr/share/examples/fusionpbx/scripts')) { $app_scripts = glob($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . 'app/*/resource/scripts');
$source_directory = '/usr/share/examples/fusionpbx/scripts'; foreach ($app_scripts as $app_script) {
recursive_copy($app_script, $destination_directory);
} }
elseif (file_exists('/usr/local/www/fusionpbx/app/switch/resources/scripts')) { unset($app_scripts);
$source_directory = '/usr/local/www/fusionpbx/app/switch/resources/scripts'; } else {
} throw new Exception("Cannot read from '$source_directory' to get the scripts");
elseif (file_exists('/var/www/fusionpbx/app/switch/resources/scripts')) {
$source_directory = '/var/www/fusionpbx/app/switch/resources/scripts';
}
else {
$source_directory = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/app/switch/resources/scripts';
}
//get the destination directory
if (file_exists($this->config->get('switch.scripts.dir'))) {
$destination_directory = $this->config->get('switch.scripts.dir');
}
elseif (file_exists('/etc/freeswitch/scripts')) {
$destination_directory = '/etc/freeswitch/scripts';
}
elseif (file_exists('/usr/local/freeswitch/scripts')) {
$destination_directory = '/usr/local/freeswitch/scripts';
}
//copy the scripts directory
if (!empty($source_directory) && is_readable($source_directory)) {
//copy the main scripts
recursive_copy($source_directory, $destination_directory);
unset($source_directory);
//copy the app/*/resource/install/scripts
$app_scripts = glob($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'app/*/resource/scripts');
foreach ($app_scripts as $app_script) {
recursive_copy($app_script, $destination_directory);
}
unset($app_scripts);
}
else {
throw new Exception("Cannot read from '$source_directory' to get the scripts");
}
chmod($destination_directory, 0775);
unset($destination_directory);
}
/**
* Copy the switch languages to the switch directory
*/
public function copy_languages() {
//get the source directory
if (file_exists('/usr/share/examples/freeswitch/conf/languages')) {
$source_directory = '/usr/share/examples/fusionpbx/conf/languages';
}
elseif (file_exists('/usr/local/www/fusionpbx/app/switch/resources/conf/languages')) {
$source_directory = '/usr/local/www/fusionpbx/app/switch/resources/conf/languages';
}
elseif (file_exists('/var/www/fusionpbx/app/switch/resources/conf/languages')) {
$source_directory = '/var/www/fusionpbx/app/switch/resources/conf/languages';
}
else {
$source_directory = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/app/switch/resources/conf/languages';
}
//get the destination directory
if (file_exists($this->config->get('switch.conf.dir').'/languages')) {
$destination_directory = $this->config->get('switch.conf.dir').'/languages';
}
elseif (file_exists('/etc/freeswitch/languages')) {
$destination_directory = '/usr/local/share/freeswitch/languages';
}
elseif (file_exists('/usr/local/freeswitch/conf/languages')) {
$destination_directory = '/usr/local/freeswitch/conf/languages';
}
//copy the languages directory
if (!empty($source_directory) && is_readable($source_directory)) {
//copy the main languages
recursive_copy($source_directory, $destination_directory);
unset($source_directory);
}
else {
throw new Exception("Cannot read from '$source_directory' to get the scripts");
}
chmod($destination_directory, 0775);
unset($destination_directory);
} }
chmod($destination_directory, 0775);
unset($destination_directory);
} }
/**
* Copy the switch languages to the switch directory
*
* @return void
*/
public function copy_languages() {
//get the source directory
if (file_exists('/usr/share/examples/freeswitch/conf/languages')) {
$source_directory = '/usr/share/examples/fusionpbx/conf/languages';
} elseif (file_exists('/usr/local/www/fusionpbx/app/switch/resources/conf/languages')) {
$source_directory = '/usr/local/www/fusionpbx/app/switch/resources/conf/languages';
} elseif (file_exists('/var/www/fusionpbx/app/switch/resources/conf/languages')) {
$source_directory = '/var/www/fusionpbx/app/switch/resources/conf/languages';
} else {
$source_directory = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/app/switch/resources/conf/languages';
}
//get the destination directory
if (file_exists($this->config->get('switch.conf.dir') . '/languages')) {
$destination_directory = $this->config->get('switch.conf.dir') . '/languages';
} elseif (file_exists('/etc/freeswitch/languages')) {
$destination_directory = '/usr/local/share/freeswitch/languages';
} elseif (file_exists('/usr/local/freeswitch/conf/languages')) {
$destination_directory = '/usr/local/freeswitch/conf/languages';
}
//copy the languages directory
if (!empty($source_directory) && is_readable($source_directory)) {
//copy the main languages
recursive_copy($source_directory, $destination_directory);
unset($source_directory);
} else {
throw new Exception("Cannot read from '$source_directory' to get the scripts");
}
chmod($destination_directory, 0775);
unset($destination_directory);
}
}
/* /*
//example use //example use

View File

@@ -95,6 +95,13 @@
} }
//define the download function (helps safari play audio sources) //define the download function (helps safari play audio sources)
/**
* Downloads a specified range of bytes from the given file.
*
* @param string $file The path to the file to download.
*
* @return void
*/
function range_download($file) { function range_download($file) {
$fp = @fopen($file, 'rb'); $fp = @fopen($file, 'rb');
@@ -123,7 +130,7 @@
$c_start = $start; $c_start = $start;
$c_end = $end; $c_end = $end;
// Extract the range string // Extract the range string
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); [, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2);
// Make sure the client hasn't sent us a multibyte range // Make sure the client hasn't sent us a multibyte range
if (strpos($range, ',') !== false) { if (strpos($range, ',') !== false) {
// (?) Shoud this be issued here, or should the first // (?) Shoud this be issued here, or should the first

View File

@@ -31,6 +31,11 @@
*/ */
class bsd_system_information extends system_information { class bsd_system_information extends system_information {
/**
* Returns the number of CPU cores available on the system.
*
* @return int The number of CPU cores.
*/
public function get_cpu_cores(): int { public function get_cpu_cores(): int {
$result = shell_exec("dmesg | grep -i --max-count 1 CPUs | sed 's/[^0-9]*//g'"); $result = shell_exec("dmesg | grep -i --max-count 1 CPUs | sed 's/[^0-9]*//g'");
$cpu_cores = trim($result); $cpu_cores = trim($result);
@@ -38,6 +43,12 @@ class bsd_system_information extends system_information {
} }
//get the CPU details //get the CPU details
/**
* Returns the current CPU usage percentage.
*
* @return float The current CPU usage percentage.
*/
public function get_cpu_percent(): float { public function get_cpu_percent(): float {
$result = shell_exec('ps -A -o pcpu'); $result = shell_exec('ps -A -o pcpu');
$percent_cpu = 0; $percent_cpu = 0;
@@ -49,10 +60,20 @@ class bsd_system_information extends system_information {
return $percent_cpu; return $percent_cpu;
} }
/**
* Returns the system uptime in seconds.
*
* @return string The system uptime in seconds.
*/
public function get_uptime() { public function get_uptime() {
return shell_exec('uptime'); return shell_exec('uptime');
} }
/**
* Returns the current CPU usage percentage per core.
*
* @return array An associative array where keys are core indices and values are their respective CPU usage percentages.
*/
public function get_cpu_percent_per_core(): array { public function get_cpu_percent_per_core(): array {
static $last = []; static $last = [];
$results = []; $results = [];
@@ -94,11 +115,11 @@ class bsd_system_information extends system_information {
} }
/** /**
* Returns the current network speed for a given interface.
* *
* @staticvar array $last * @param string $interface The network interface to query (default: 'em0')
* @param string $interface *
* @return array * @return array An array containing the current receive and transmit speeds in bytes per second.
* @depends FreeBSD Version 12
*/ */
public function get_network_speed(string $interface = 'em0'): array { public function get_network_speed(string $interface = 'em0'): array {
static $last = []; static $last = [];

View File

@@ -31,6 +31,13 @@
*/ */
class linux_system_information extends system_information { class linux_system_information extends system_information {
/**
* Returns the number of CPU cores available on the system.
*
* This method executes a shell command to parse the /proc/cpuinfo file and counts the number of processor entries found.
*
* @return int The total number of CPU cores
*/
public function get_cpu_cores(): int { public function get_cpu_cores(): int {
$result = @trim(shell_exec("grep -P '^processor' /proc/cpuinfo")); $result = @trim(shell_exec("grep -P '^processor' /proc/cpuinfo"));
$cpu_cores = count(explode("\n", $result)); $cpu_cores = count(explode("\n", $result));
@@ -38,6 +45,16 @@ class linux_system_information extends system_information {
} }
//get the CPU details //get the CPU details
/**
* Returns the current CPU usage as a percentage.
*
* This method reads the CPU statistics from /proc/stat and calculates
* the CPU usage by comparing the total and idle time of each core.
* The result is rounded to two decimal places.
*
* @return float The current CPU usage in percent.
*/
public function get_cpu_percent(): float { public function get_cpu_percent(): float {
$stat1 = file_get_contents('/proc/stat'); $stat1 = file_get_contents('/proc/stat');
usleep(500000); usleep(500000);
@@ -73,10 +90,27 @@ class linux_system_information extends system_information {
return round($percent_cpu / $core_count, 2); return round($percent_cpu / $core_count, 2);
} }
/**
* Returns the current system uptime as reported by the 'uptime' command.
*
* This method executes the 'uptime' command and returns its output.
*
* @return string The current system uptime.
*/
public function get_uptime() { public function get_uptime() {
return shell_exec('uptime'); return shell_exec('uptime');
} }
/**
* Returns the current CPU usage as a percentage per core.
*
* This method reads the CPU statistics from /proc/stat and calculates
* the CPU usage by comparing the total and idle time of each core.
* The result is rounded to two decimal places.
*
* @return array An array where the keys are the core numbers (starting at 0)
* and the values are the current CPU usage for each core in percent.
*/
public function get_cpu_percent_per_core(): array { public function get_cpu_percent_per_core(): array {
static $last = []; static $last = [];
@@ -107,6 +141,16 @@ class linux_system_information extends system_information {
return $results; return $results;
} }
/**
* Returns the current network speed for the specified interface.
*
* This method reads the network statistics from /proc/net/dev and calculates
* the network speed by comparing the received and transmitted bytes between two measurements.
*
* @param string $interface The network interface to read stats from. Defaults to 'eth0'.
*
* @return array An array containing the current receive (rx_bps) and transmit (tx_bps) speeds in bits per second.
*/
public function get_network_speed(string $interface = 'eth0'): array { public function get_network_speed(string $interface = 'eth0'): array {
static $last = []; static $last = [];

View File

@@ -35,7 +35,9 @@ class session {
/** /**
* Removes old php session files. Called by the maintenance application. * Removes old php session files. Called by the maintenance application.
*
* @param settings $settings A settings object * @param settings $settings A settings object
*
* @return void * @return void
*/ */
public static function filesystem_maintenance(settings $settings): void { public static function filesystem_maintenance(settings $settings): void {

View File

@@ -38,6 +38,11 @@ class system_dashboard_service extends base_websocket_system_service {
private $network_status_refresh_interval; private $network_status_refresh_interval;
private $network_interface; private $network_interface;
/**
* Reloads settings from database, config file and websocket server.
*
* @return void
*/
protected function reload_settings(): void { protected function reload_settings(): void {
static::set_system_information(); static::set_system_information();
@@ -64,8 +69,12 @@ class system_dashboard_service extends base_websocket_system_service {
} }
/** /**
* Executes once * Registers topics for broadcasting system information.
* @return void *
* This method is responsible for setting up the system information object,
* registering callback functions for cpu and network status requests, and
* configuring timer callbacks to refresh these statuses at regular intervals.
* It is only called once during initial startup.
*/ */
protected function register_topics(): void { protected function register_topics(): void {
@@ -90,6 +99,17 @@ class system_dashboard_service extends base_websocket_system_service {
$this->info("Broadcasting Network Status every {$this->network_status_refresh_interval}s"); $this->info("Broadcasting Network Status every {$this->network_status_refresh_interval}s");
} }
/**
* Handles the network status request.
*
* This method retrieves the current network interface and speeds, constructs a response message,
* logs the request for debugging purposes, and attempts to send the broadcast. If the Websocket server
* is disconnected, it waits until reconnection before attempting to send again.
*
* @param string|null $message The original message that triggered this response (optional).
*
* @return int The refresh interval for network status in seconds.
*/
public function on_network_status($message = null): int { public function on_network_status($message = null): int {
// Get RX (receive) and TX (transmit) bps // Get RX (receive) and TX (transmit) bps
$network_rates = self::$system_information->get_network_speed($this->network_interface); $network_rates = self::$system_information->get_network_speed($this->network_interface);
@@ -134,6 +154,15 @@ class system_dashboard_service extends base_websocket_system_service {
return $this->network_status_refresh_interval; return $this->network_status_refresh_interval;
} }
/**
* Handles the selection of a network interface from a message.
*
* This method checks if the message is an instance of WebSocketMessage and if it contains
* a 'network_interface' payload. If both conditions are true, it sets the network interface
* property to the value of the payload.
*
* @param websocket_message|null $message The message containing the selected network interface.
*/
public function on_network_interface_select($message = null): void { public function on_network_interface_select($message = null): void {
if ($message !== null && $message instanceof websocket_message) { if ($message !== null && $message instanceof websocket_message) {
$payload = $message->payload(); $payload = $message->payload();
@@ -143,6 +172,17 @@ class system_dashboard_service extends base_websocket_system_service {
} }
} }
/**
* Handles cpu status requests.
*
* This method is called to respond to incoming requests for the current CPU usage,
* both total and per-core. It prepares a response message with the requested data
* and sends it to all connected clients.
*
* @param null|websocket_message $message The request message, if responding to a specific request.
*
* @return int The interval at which this method should be called again to refresh the cpu status.
*/
public function on_cpu_status($message = null): int { public function on_cpu_status($message = null): int {
// Get total and per-core CPU usage // Get total and per-core CPU usage
$cpu_percent_total = self::$system_information->get_cpu_percent(); $cpu_percent_total = self::$system_information->get_cpu_percent();
@@ -192,10 +232,27 @@ class system_dashboard_service extends base_websocket_system_service {
return $this->cpu_status_refresh_interval; return $this->cpu_status_refresh_interval;
} }
/**
* Returns the service name for system information.
*
* This method provides a unique identifier for the dashboard system information service.
*
* @return string The service name as a string, in this case "dashboard.system.information".
*/
public static function get_service_name(): string { public static function get_service_name(): string {
return "dashboard.system.information"; return "dashboard.system.information";
} }
/**
* Creates a filter chain for broadcasting system information.
*
* This method generates a filter based on the subscriber's permissions,
* allowing them to receive only relevant system view information.
*
* @param subscriber $subscriber The subscriber object with permission data.
*
* @return ?filter A filter chain that matches the subscriber's permissions, or null if no match is found.
*/
public static function create_filter_chain_for(subscriber $subscriber): ?filter { public static function create_filter_chain_for(subscriber $subscriber): ?filter {
// Get the subscriber permissions // Get the subscriber permissions
$permissions = $subscriber->get_permissions(); $permissions = $subscriber->get_permissions();
@@ -216,6 +273,15 @@ class system_dashboard_service extends base_websocket_system_service {
return $filter; return $filter;
} }
/**
* Sets the system information object.
*
* This method creates a new instance of `SystemInformation` and stores it in
* the class's static property `$system_information`. It is typically called once
* during initial startup to establish the system information source.
*
* @return void
*/
public static function set_system_information(): void { public static function set_system_information(): void {
self::$system_information = system_information::new(); self::$system_information = system_information::new();
} }

View File

@@ -37,10 +37,20 @@ abstract class system_information {
abstract public function get_cpu_percent_per_core(): array; abstract public function get_cpu_percent_per_core(): array;
abstract public function get_network_speed(string $interface = 'eth0'): array; abstract public function get_network_speed(string $interface = 'eth0'): array;
/**
* Returns the system load average.
*
* @return array Three most recent one-minute load averages.
*/
public function get_load_average() { public function get_load_average() {
return sys_getloadavg(); return sys_getloadavg();
} }
/**
* Returns a system information object based on the underlying operating system.
*
* @return ?system_information The system information object for the current OS, or null if not supported.
*/
public static function new(): ?system_information { public static function new(): ?system_information {
if (stristr(PHP_OS, 'BSD')) { if (stristr(PHP_OS, 'BSD')) {
return new bsd_system_information(); return new bsd_system_information();

View File

@@ -38,6 +38,13 @@
//function to parse a FusionPBX service from a .service file //function to parse a FusionPBX service from a .service file
if (!function_exists('get_classname')) { if (!function_exists('get_classname')) {
/**
* Retrieves the name of a PHP class from an ExecStart directive in a service file.
*
* @param string $file Path to the service file.
*
* @return string The name of the PHP class, or empty string if not found.
*/
function get_classname(string $file) { function get_classname(string $file) {
if (!file_exists($file)) { if (!file_exists($file)) {
return ''; return '';
@@ -55,6 +62,14 @@
//function to check for running process: returns [running, pid, etime] //function to check for running process: returns [running, pid, etime]
if (!function_exists('is_running')) { if (!function_exists('is_running')) {
/**
* Checks if a process with the given name is currently running.
*
* @param string $name The name of the process to check for.
*
* @return array An array containing information about the process's status,
* including whether it's running, its PID, and how long it's been running.
*/
function is_running(string $name) { function is_running(string $name) {
$name = escapeshellarg($name); $name = escapeshellarg($name);
$pid = trim(shell_exec("ps -aux | grep $name | grep -v grep | awk '{print \$2}' | head -n 1") ?? ''); $pid = trim(shell_exec("ps -aux | grep $name | grep -v grep | awk '{print \$2}' | head -n 1") ?? '');
@@ -68,6 +83,21 @@
//function to format etime into friendly display //function to format etime into friendly display
if (!function_exists('format_etime')) { if (!function_exists('format_etime')) {
/**
* Formats a time duration string into a human-readable format.
*
* The input string can be in one of the following formats:
* - dd-hh:mm:ss
* - hh:mm:ss
* - mm:ss
* - seconds (no units)
*
* If the input string is empty or invalid, an empty string will be returned.
*
* @param string $etime Time duration string to format.
*
* @return string Formatted time duration string in human-readable format.
*/
function format_etime($etime) { function format_etime($etime) {
// Format: [[dd-]hh:]mm:ss // Format: [[dd-]hh:]mm:ss
if (empty($etime)) return '-'; if (empty($etime)) return '-';

View File

@@ -83,6 +83,14 @@
// //
//system information //system information
/**
* Retrieves system information.
*
* @return array An array containing various system information such as PHP and switch versions,
* git repository details, operating system name, version, uptime, kernel, and type,
* memory usage, CPU usage, and disk space. The keys of the returned array are
* 'version', 'git', 'path', 'switch', 'php', 'os', 'mem', and 'cpu'.
*/
function system_information(): array { function system_information(): array {
global $database, $db_type; global $database, $db_type;
$system_information = []; $system_information = [];

View File

@@ -25,371 +25,406 @@
*/ */
//define the time conditions class //define the time conditions class
class time_conditions { class time_conditions {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'time_conditions'; const app_name = 'time_conditions';
const app_uuid = '4b821450-926b-175a-af93-a03c441818b1'; const app_uuid = '4b821450-926b-175a-af93-a03c441818b1';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Username set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Username set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $username; * @var string
*/
private $username;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare public/private properties * declare public/private properties
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
private $toggle_field; private $toggle_field;
private $toggle_values; private $toggle_values;
private $dialplan_global; private $dialplan_global;
public function __construct(array $setting_array = []) { /**
//set domain and user UUIDs * Initializes the object with setting array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
* @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
* an empty array.
*
* @return void
*/
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
//set the default value //set the default value
$this->dialplan_global = false; $this->dialplan_global = false;
//assign property defaults //assign property defaults
$this->permission_prefix = 'time_condition_'; $this->permission_prefix = 'time_condition_';
$this->list_page = 'time_conditions.php'; $this->list_page = 'time_conditions.php';
$this->table = 'dialplans'; $this->table = 'dialplans';
$this->uuid_prefix = 'dialplan_'; $this->uuid_prefix = 'dialplan_';
$this->toggle_field = 'dialplan_enabled'; $this->toggle_field = 'dialplan_enabled';
$this->toggle_values = ['true','false']; $this->toggle_values = ['true', 'false'];
}
/**
* Deletes 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 delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
} }
/** //delete multiple records
* delete records if (is_array($records) && @sizeof($records) != 0) {
*/
public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) {
//add multi-lingual support //build the delete array
$language = new text; foreach ($records as $x => $record) {
$text = $language->get(); if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
//validate the token //build delete array
$token = new token; $array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
if (!$token->validate($_SERVER['PHP_SELF'])) { $array['dialplan_details'][$x]['dialplan_uuid'] = $record['uuid'];
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//delete multiple records //get the dialplan context
if (is_array($records) && @sizeof($records) != 0) { $sql = "select dialplan_context from v_dialplans ";
$sql .= "where dialplan_uuid = :dialplan_uuid ";
$parameters['dialplan_uuid'] = $record['uuid'];
$dialplan_contexts[] = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//build the delete array }
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
//build delete array
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
$array['dialplan_details'][$x]['dialplan_uuid'] = $record['uuid'];
//get the dialplan context
$sql = "select dialplan_context from v_dialplans ";
$sql .= "where dialplan_uuid = :dialplan_uuid ";
$parameters['dialplan_uuid'] = $record['uuid'];
$dialplan_contexts[] = $this->database->select($sql, $parameters, 'column');
unset($sql, $parameters);
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_delete', 'temp');
$p->add('dialplan_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
//revoke temporary permissions
$p->delete('dialplan_delete', 'temp');
$p->delete('dialplan_detail_delete', 'temp');
//clear the cache
if (is_array($dialplan_contexts) && @sizeof($dialplan_contexts) != 0) {
$dialplan_contexts = array_unique($dialplan_contexts, SORT_STRING);
$cache = new cache;
foreach ($dialplan_contexts as $dialplan_context) {
$cache->delete("dialplan:".$dialplan_context);
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete'].': '.@sizeof($array[$this->table]));
}
unset($records, $array);
}
} }
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_delete', 'temp');
$p->add('dialplan_detail_delete', 'temp');
//execute delete
$this->database->delete($array);
//revoke temporary permissions
$p->delete('dialplan_delete', 'temp');
$p->delete('dialplan_detail_delete', 'temp');
//clear the cache
if (is_array($dialplan_contexts) && @sizeof($dialplan_contexts) != 0) {
$dialplan_contexts = array_unique($dialplan_contexts, SORT_STRING);
$cache = new cache;
foreach ($dialplan_contexts as $dialplan_context) {
$cache->delete("dialplan:" . $dialplan_context);
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-delete'] . ': ' . @sizeof($array[$this->table]));
}
unset($records, $array);
}
}
}
/**
* Toggles the state of one or more records.
*
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix . 'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
} }
/** //toggle the checked records
* toggle records if (is_array($records) && @sizeof($records) != 0) {
*/
public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//toggle the checked records
if (is_array($records) && @sizeof($records) != 0) {
//get current toggle state
foreach($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle, dialplan_context from v_".$this->table." ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
$dialplan_contexts[] = $row['dialplan_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//clear the cache
if (is_array($dialplan_contexts) && @sizeof($dialplan_contexts) != 0) {
$dialplan_contexts = array_unique($dialplan_contexts, SORT_STRING);
$cache = new cache;
foreach ($dialplan_contexts as $dialplan_context) {
$cache->delete("dialplan:".$dialplan_context);
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
}
//get current toggle state
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
} }
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle, dialplan_context from v_" . $this->table . " ";
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$parameters['domain_uuid'] = $this->domain_uuid;
$rows = $this->database->select($sql, $parameters, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$states[$row['uuid']] = $row['toggle'];
$dialplan_contexts[] = $row['dialplan_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//build update array
$x = 0;
foreach ($states as $uuid => $state) {
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
$x++;
}
//save the changes
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_edit', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_edit', 'temp');
//clear the cache
if (is_array($dialplan_contexts) && @sizeof($dialplan_contexts) != 0) {
$dialplan_contexts = array_unique($dialplan_contexts, SORT_STRING);
$cache = new cache;
foreach ($dialplan_contexts as $dialplan_context) {
$cache->delete("dialplan:" . $dialplan_context);
}
}
//clear the destinations session array
if (isset($_SESSION['destinations']['array'])) {
unset($_SESSION['destinations']['array']);
}
//set message
message::add($text['message-toggle']);
}
unset($records, $states);
} }
/** }
* copy records }
*/
public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) {
//add multi-lingual support /**
$language = new text; * Copies one or more records
$text = $language->get(); *
* @param array $records An array of record IDs to delete, where each ID is an associative array
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function copy($records) {
if (permission_exists($this->permission_prefix . 'add')) {
//validate the token //add multi-lingual support
$token = new token; $language = new text;
if (!$token->validate($_SERVER['PHP_SELF'])) { $text = $language->get();
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->list_page);
exit;
}
//copy the checked records //validate the token
if (is_array($records) && @sizeof($records) != 0) { $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'], 'negative');
header('Location: ' . $this->list_page);
exit;
}
//get checked records //copy the checked records
foreach($records as $x => $record) { if (is_array($records) && @sizeof($records) != 0) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'"; //get checked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//create insert array from existing data
if (is_array($uuids) && @sizeof($uuids) != 0) {
//primary table
$sql = "select * from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string
foreach ($row as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $primary_uuid;
$array[$this->table][$x]['dialplan_description'] = trim($row['dialplan_description'] . ' (' . $text['label-copy'] . ')');
//details sub table
$sql_2 = "select * from v_dialplan_details where dialplan_uuid = :dialplan_uuid";
$parameters_2['dialplan_uuid'] = $row['dialplan_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach ($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
} }
}
//create insert array from existing data //copy data
if (is_array($uuids) && @sizeof($uuids) != 0) { $array['dialplan_details'][$y] = $row_2;
//primary table //overwrite
$sql = "select * from v_".$this->table." "; $array['dialplan_details'][$y]['dialplan_detail_uuid'] = uuid();
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") "; $array['dialplan_details'][$y]['dialplan_uuid'] = $primary_uuid;
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
$y = 0;
foreach ($rows as $x => $row) {
$primary_uuid = uuid();
//convert boolean values to a string //increment
foreach($row as $key => $value) { $y++;
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row[$key] = $value;
}
}
//copy data
$array[$this->table][$x] = $row;
//overwrite
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $primary_uuid;
$array[$this->table][$x]['dialplan_description'] = trim($row['dialplan_description'].' ('.$text['label-copy'].')');
//details sub table
$sql_2 = "select * from v_dialplan_details where dialplan_uuid = :dialplan_uuid";
$parameters_2['dialplan_uuid'] = $row['dialplan_uuid'];
$rows_2 = $this->database->select($sql_2, $parameters_2, 'all');
if (is_array($rows_2) && @sizeof($rows_2) != 0) {
foreach ($rows_2 as $row_2) {
//convert boolean values to a string
foreach($row_2 as $key => $value) {
if (gettype($value) == 'boolean') {
$value = $value ? 'true' : 'false';
$row_2[$key] = $value;
}
}
//copy data
$array['dialplan_details'][$y] = $row_2;
//overwrite
$array['dialplan_details'][$y]['dialplan_detail_uuid'] = uuid();
$array['dialplan_details'][$y]['dialplan_uuid'] = $primary_uuid;
//increment
$y++;
}
}
unset($sql_2, $parameters_2, $rows_2, $row_2);
//get dialplan contexts
$dialplan_contexts[] = $row['dialplan_context'];
}
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_add', 'temp');
$p->add('dialplan_detail_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_add', 'temp');
$p->delete('dialplan_detail_add', 'temp');
//clear the cache
if (is_array($dialplan_contexts) && @sizeof($dialplan_contexts) != 0) {
$dialplan_contexts = array_unique($dialplan_contexts, SORT_STRING);
$cache = new cache;
foreach ($dialplan_contexts as $dialplan_context) {
$cache->delete("dialplan:".$dialplan_context);
}
}
//set message
message::add($text['message-copy']);
} }
unset($records); }
unset($sql_2, $parameters_2, $rows_2, $row_2);
//get dialplan contexts
$dialplan_contexts[] = $row['dialplan_context'];
} }
}
unset($sql, $parameters, $rows, $row);
}
//save the changes and set the message
if (is_array($array) && @sizeof($array) != 0) {
//grant temporary permissions
$p = permissions::new();
$p->add('dialplan_add', 'temp');
$p->add('dialplan_detail_add', 'temp');
//save the array
$this->database->save($array);
unset($array);
//revoke temporary permissions
$p->delete('dialplan_add', 'temp');
$p->delete('dialplan_detail_add', 'temp');
//clear the cache
if (is_array($dialplan_contexts) && @sizeof($dialplan_contexts) != 0) {
$dialplan_contexts = array_unique($dialplan_contexts, SORT_STRING);
$cache = new cache;
foreach ($dialplan_contexts as $dialplan_context) {
$cache->delete("dialplan:" . $dialplan_context);
}
}
//set message
message::add($text['message-copy']);
} }
} //method unset($records);
}
}
} //method
} //class } //class

View File

@@ -990,6 +990,13 @@ echo " ".$text['description-extension']."<br />\n";
echo "</td>\n"; echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
/**
* Adds a custom condition to the given group.
*
* @param object $destination The destination object being processed.
* @param int $group_id The ID of the group to which the condition is being added.
* @param string $dialplan_action The dialplan action for the group (optional).
*/
function add_custom_condition($destination, $group_id, $dialplan_action = '') { function add_custom_condition($destination, $group_id, $dialplan_action = '') {
global $text, $v_link_label_add; global $text, $v_link_label_add;
echo "<tr>\n"; echo "<tr>\n";

View File

@@ -46,7 +46,12 @@
private $toggle_values; private $toggle_values;
/** /**
* called when the object is created * Initializes the object with setting array.
*
* @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
* an empty array.
*
* @return void
*/ */
public function __construct(array $setting_array = []) { public function __construct(array $setting_array = []) {
//set objects //set objects
@@ -62,7 +67,13 @@
} }
/** /**
* delete records * Deletes 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 delete($records) { public function delete($records) {
if (permission_exists($this->permission_prefix.'delete')) { if (permission_exists($this->permission_prefix.'delete')) {
@@ -111,7 +122,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) { public function toggle($records) {
if (permission_exists($this->permission_prefix.'edit')) { if (permission_exists($this->permission_prefix.'edit')) {
@@ -181,7 +198,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) { public function copy($records) {
if (permission_exists($this->permission_prefix.'add')) { if (permission_exists($this->permission_prefix.'add')) {

View File

@@ -105,8 +105,8 @@
$param = $search ? "&search=".$search : null; $param = $search ? "&search=".$search : null;
$param = $order_by ? "&order_by=".$order_by."&order=".$order : null; $param = $order_by ? "&order_by=".$order_by."&order=".$order : null;
$page = empty($_GET['page']) ? $page = 0 : $page = $_GET['page']; $page = empty($_GET['page']) ? $page = 0 : $page = $_GET['page'];
list($paging_controls, $rows_per_page) = paging($num_rows, $param, $rows_per_page); [$paging_controls, $rows_per_page] = paging($num_rows, $param, $rows_per_page);
list($paging_controls_mini, $rows_per_page) = paging($num_rows, $param, $rows_per_page, true); [$paging_controls_mini, $rows_per_page] = paging($num_rows, $param, $rows_per_page, true);
$offset = $rows_per_page * $page; $offset = $rows_per_page * $page;
//get the list //get the list
@@ -191,6 +191,13 @@
echo "<div class='card'>\n"; echo "<div class='card'>\n";
echo "<table class='list'>\n"; echo "<table class='list'>\n";
/**
* Writes the header for a list of variables.
*
* @param string $modifier The modifier to be used in the header, with slashes and extra spaces removed.
*
* @return void
*/
function write_header($modifier) { function write_header($modifier) {
global $text, $order_by, $order, $vars, $list_row_edit_button; global $text, $order_by, $order, $vars, $list_row_edit_button;
$modifier = str_replace('/', '', $modifier); $modifier = str_replace('/', '', $modifier);

View File

@@ -25,175 +25,193 @@
*/ */
//define the voicemail greetings class //define the voicemail greetings class
class voicemail_greetings { class voicemail_greetings {
/** /**
* declare constant variables * declare constant variables
*/ */
const app_name = 'voicemail_greetings'; const app_name = 'voicemail_greetings';
const app_uuid = 'e4b4fbee-9e4d-8e46-3810-91ba663db0c2'; const app_uuid = 'e4b4fbee-9e4d-8e46-3810-91ba663db0c2';
/** /**
* Set in the constructor. Must be a database object and cannot be null. * Set in the constructor. Must be a database object and cannot be null.
* @var database Database Object *
*/ * @var database Database Object
private $database; */
private $database;
/** /**
* Settings object set in the constructor. Must be a settings object and cannot be null. * Settings object set in the constructor. Must be a settings object and cannot be null.
* @var settings Settings Object *
*/ * @var settings Settings Object
private $settings; */
private $settings;
/** /**
* User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * User UUID set in the constructor. This can be passed in through the $settings_array associative array or set in
* @var string * the session global array
*/ *
private $user_uuid; * @var string
*/
private $user_uuid;
/** /**
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_uuid; * @var string
*/
private $domain_uuid;
/** /**
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array * Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
* @var string * in the session global array
*/ *
private $domain_name; * @var string
*/
private $domain_name;
/** /**
* declare private variables * declare private variables
*/ */
private $permission_prefix; private $permission_prefix;
private $list_page; private $list_page;
private $table; private $table;
private $uuid_prefix; private $uuid_prefix;
/** /**
* declare public variables * declare public variables
*/ */
public $voicemail_id; public $voicemail_id;
/** /**
* called when the object is created * Initializes the object with setting array.
*/ *
public function __construct(array $setting_array = []) { * @param array $setting_array An array containing settings for domain, user, and database connections. Defaults to
//set domain and user UUIDs * an empty array.
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? ''; *
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? ''; * @return void
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? ''; */
public function __construct(array $setting_array = []) {
//set domain and user UUIDs
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
$this->domain_name = $setting_array['domain_name'] ?? $_SESSION['domain_name'] ?? '';
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
//set objects //set objects
$this->database = $setting_array['database'] ?? database::new(); $this->database = $setting_array['database'] ?? database::new();
$this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]); $this->settings = $setting_array['settings'] ?? new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
//assign private variables //assign private variables
$this->permission_prefix = 'voicemail_greeting_'; $this->permission_prefix = 'voicemail_greeting_';
if (is_numeric($this->voicemail_id)) { if (is_numeric($this->voicemail_id)) {
$this->list_page = 'voicemail_greetings.php?id='.urlencode($this->voicemail_id).'&back='.urlencode(PROJECT_PATH.'/app/voicemail/voicemails.php'); $this->list_page = 'voicemail_greetings.php?id=' . urlencode($this->voicemail_id) . '&back=' . urlencode(PROJECT_PATH . '/app/voicemail/voicemails.php');
} } else {
else { $this->list_page = PROJECT_PATH . '/app/voicemails/voicemails.php';
$this->list_page = PROJECT_PATH.'/app/voicemails/voicemails.php';
}
$this->table = 'voicemail_greetings';
$this->uuid_prefix = 'voicemail_greeting_';
} }
$this->table = 'voicemail_greetings';
$this->uuid_prefix = 'voicemail_greeting_';
}
/** /**
* delete records * Deletes one or more records.
*/ *
public function delete($records) { * @param array $records An array of record IDs to delete, where each ID is an associative array
if (permission_exists($this->permission_prefix.'delete')) { * containing 'uuid' and 'checked' keys. The 'checked' value indicates
* whether the corresponding checkbox was checked for deletion.
*
* @return void No return value; this method modifies the database state and sets a message.
*/
public function delete($records) {
if (permission_exists($this->permission_prefix . 'delete')) {
//add multi-lingual support //add multi-lingual support
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//validate the token //validate the token
$token = new token; $token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) { if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative'); message::add($text['message-invalid_token'], 'negative');
header('Location: '.$this->list_page); header('Location: ' . $this->list_page);
exit; exit;
}
//check voicemail id
if (!is_numeric($this->voicemail_id)) {
header('Location: '.$this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'".$record['uuid']."'";
}
}
//get necessary greeting details
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select ".$this->uuid_prefix."uuid as uuid, greeting_filename, greeting_id from v_".$this->table." ";
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$greeting_filenames[$row['uuid']] = $row['greeting_filename'];
$greeting_ids[$this->voicemail_id] = $row['greeting_id'];
}
}
unset($sql, $parameters, $rows, $row);
}
//set the greeting directory
$greeting_directory = $this->settings->get('switch', 'storage').'/voicemail/default/'.$this->domain_name.'/'.$this->voicemail_id;
//loop through greetings
if (is_array($greeting_filenames) && @sizeof($greeting_filenames) != 0) {
$x = 0;
foreach ($greeting_filenames as $voicemail_greeting_uuid => $greeting_filename) {
//delete the recording file
@unlink($greeting_directory.'/'.$greeting_filename);
//build the delete array
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $voicemail_greeting_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$x++;
}
}
//reset voicemail box(es) to default (null) if deleted greeting(s) were assigned
if (is_array($array) && @sizeof($array) != 0 && is_array($greeting_ids) && @sizeof($greeting_ids)) {
foreach ($greeting_ids as $voicemail_id => $greeting_id) {
if (is_numeric($voicemail_id) && is_numeric($greeting_id)) {
$sql = "update v_voicemails set greeting_id = null ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and voicemail_id = :voicemail_id ";
$sql .= "and greeting_id = :greeting_id ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['voicemail_id'] = $voicemail_id;
$parameters['greeting_id'] = $greeting_id;
$this->database->execute($sql, $parameters);
unset($sql, $parameters);
}
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
} }
} //method
} //class //check voicemail id
if (!is_numeric($this->voicemail_id)) {
header('Location: ' . $this->list_page);
exit;
}
//delete multiple records
if (is_array($records) && @sizeof($records) != 0) {
//filter out unchecked records
foreach ($records as $x => $record) {
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
$uuids[] = "'" . $record['uuid'] . "'";
}
}
//get necessary greeting details
if (is_array($uuids) && @sizeof($uuids) != 0) {
$sql = "select " . $this->uuid_prefix . "uuid as uuid, greeting_filename, greeting_id from v_" . $this->table . " ";
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
$rows = $this->database->select($sql, $parameters ?? null, 'all');
if (is_array($rows) && @sizeof($rows) != 0) {
foreach ($rows as $row) {
$greeting_filenames[$row['uuid']] = $row['greeting_filename'];
$greeting_ids[$this->voicemail_id] = $row['greeting_id'];
}
}
unset($sql, $parameters, $rows, $row);
}
//set the greeting directory
$greeting_directory = $this->settings->get('switch', 'storage') . '/voicemail/default/' . $this->domain_name . '/' . $this->voicemail_id;
//loop through greetings
if (is_array($greeting_filenames) && @sizeof($greeting_filenames) != 0) {
$x = 0;
foreach ($greeting_filenames as $voicemail_greeting_uuid => $greeting_filename) {
//delete the recording file
@unlink($greeting_directory . '/' . $greeting_filename);
//build the delete array
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $voicemail_greeting_uuid;
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
$x++;
}
}
//reset voicemail box(es) to default (null) if deleted greeting(s) were assigned
if (is_array($array) && @sizeof($array) != 0 && is_array($greeting_ids) && @sizeof($greeting_ids)) {
foreach ($greeting_ids as $voicemail_id => $greeting_id) {
if (is_numeric($voicemail_id) && is_numeric($greeting_id)) {
$sql = "update v_voicemails set greeting_id = null ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and voicemail_id = :voicemail_id ";
$sql .= "and greeting_id = :greeting_id ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['voicemail_id'] = $voicemail_id;
$parameters['greeting_id'] = $greeting_id;
$this->database->execute($sql, $parameters);
unset($sql, $parameters);
}
}
}
//delete the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//execute delete
$this->database->delete($array);
unset($array);
//set message
message::add($text['message-delete']);
}
unset($records);
}
}
} //method
} //class

View File

@@ -62,6 +62,13 @@
} }
//used (above) to search the array to determine if an extension is assigned to the user //used (above) to search the array to determine if an extension is assigned to the user
/**
* Checks if the given extension number is assigned to the user.
*
* @param string $number The extension number to check.
*
* @return bool True if the extension number is assigned, False otherwise.
*/
function extension_assigned($number) { function extension_assigned($number) {
foreach ($_SESSION['user']['extension'] as $row) { foreach ($_SESSION['user']['extension'] as $row) {
if ((is_numeric($row['number_alias']) && $row['number_alias'] == $number) || $row['user'] == $number) { if ((is_numeric($row['number_alias']) && $row['number_alias'] == $number) || $row['user'] == $number) {
@@ -506,6 +513,11 @@
require_once "resources/footer.php"; require_once "resources/footer.php";
//define the download function (helps safari play audio sources) //define the download function (helps safari play audio sources)
/**
* Handles a range download request for the given file.
*
* @param string $file The path to the file being downloaded.
*/
function range_download($file) { function range_download($file) {
$fp = @fopen($file, 'rb'); $fp = @fopen($file, 'rb');
@@ -534,7 +546,7 @@
$c_start = $start; $c_start = $start;
$c_end = $end; $c_end = $end;
// Extract the range string // Extract the range string
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); [, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2);
// Make sure the client hasn't sent us a multibyte range // Make sure the client hasn't sent us a multibyte range
if (strpos($range, ',') !== false) { if (strpos($range, ',') !== false) {
// (?) Shoud this be issued here, or should the first // (?) Shoud this be issued here, or should the first

File diff suppressed because it is too large Load Diff

View File

@@ -61,6 +61,13 @@
$available_columns[] = 'voicemail_tutorial'; $available_columns[] = 'voicemail_tutorial';
//define the functions //define the functions
/**
* Converts a 2D array into a CSV string.
*
* @param array &$array The input array to convert. Each inner array represents a row in the CSV output.
*
* @return string|null The CSV data as a string, or null if the input array is empty.
*/
function array2csv(array &$array) { function array2csv(array &$array) {
if (count($array) == 0) { if (count($array) == 0) {
return null; return null;
@@ -75,6 +82,13 @@
return ob_get_clean(); return ob_get_clean();
} }
/**
* Sends HTTP headers to initiate a file download.
*
* @param string $filename The name of the file to be downloaded.
*
* @return void
*/
function download_send_headers($filename) { function download_send_headers($filename) {
// disable caching // disable caching
$now = gmdate("D, d M Y H:i:s"); $now = gmdate("D, d M Y H:i:s");

View File

@@ -38,18 +38,6 @@
$language = new text; $language = new text;
$text = $language->get(); $text = $language->get();
//built in str_getcsv requires PHP 5.3 or higher, this function can be used to reproduct the functionality but requirs PHP 5.1.0 or higher
if (!function_exists('str_getcsv')) {
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
$fp = fopen("php://memory", 'r+');
fputs($fp, $input);
rewind($fp);
$data = fgetcsv($fp, null, $delimiter, $enclosure); // $escape only got added in 5.3.0
fclose($fp);
return $data;
}
}
//set the max php execution time //set the max php execution time
ini_set('max_execution_time', 7200); ini_set('max_execution_time', 7200);
@@ -230,7 +218,15 @@
} }
//get the parent table //get the parent table
function get_parent($schema,$table_name) { /**
* Retrieves the parent table for a given table name from a schema.
*
* @param array $schema A multidimensional array representing the schema of tables.
* @param string $table_name The name of the table to retrieve the parent for.
*
* @return string|null The name of the parent table, or null if not found in the schema.
*/
function get_parent($schema, $table_name) {
foreach ($schema as $row) { foreach ($schema as $row) {
if ($row['table'] == $table_name) { if ($row['table'] == $table_name) {
return $row['parent']; return $row['parent'];

Some files were not shown because too many files have changed in this diff Show More