mirror of
https://github.com/fusionpbx/fusionpbx.git
synced 2025-12-30 00:53:50 +00:00
Documentation, format class, no modification. (#7629)
This commit is contained in:
@@ -6,23 +6,42 @@ class array_order {
|
||||
var $backwards = false;
|
||||
var $numeric = false;
|
||||
|
||||
/**
|
||||
* Sorts the provided array based on the specified fields.
|
||||
*
|
||||
* If no fields are provided, sorts in default order. If numeric sorting is enabled,
|
||||
* uses the numericCompare method for comparison; otherwise, uses the stringCompare method.
|
||||
*
|
||||
* @param array $array The array to be sorted
|
||||
*
|
||||
* @return array The sorted array
|
||||
*/
|
||||
function sort() {
|
||||
$args = func_get_args();
|
||||
$array = $args[0];
|
||||
if (!$array) return array();
|
||||
if (!$array) return [];
|
||||
$this->sort_fields = array_slice($args, 1);
|
||||
if (!$this->sort_fields) return $array();
|
||||
|
||||
if ($this->numeric) {
|
||||
usort($array, array($this, 'numericCompare'));
|
||||
usort($array, [$this, 'numericCompare']);
|
||||
} else {
|
||||
usort($array, array($this, 'stringCompare'));
|
||||
usort($array, [$this, 'stringCompare']);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two values based on a specified set of sort fields.
|
||||
*
|
||||
* @param array $a The first value to compare.
|
||||
* @param array $b The second value to compare.
|
||||
*
|
||||
* @return int A negative integer if the first value is less than the second, a positive integer if the first value
|
||||
* is greater than the second, and zero if they are equal.
|
||||
*/
|
||||
function numericCompare($a, $b) {
|
||||
foreach($this->sort_fields as $sort_field) {
|
||||
foreach ($this->sort_fields as $sort_field) {
|
||||
if ($a[$sort_field] == $b[$sort_field]) {
|
||||
continue;
|
||||
}
|
||||
@@ -31,8 +50,17 @@ class array_order {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two strings according to the specified sort fields.
|
||||
*
|
||||
* @param string $a The first string to compare.
|
||||
* @param string $b The second string to compare.
|
||||
*
|
||||
* @return int A negative integer if $a is less than $b, a positive integer if $a is greater than $b,
|
||||
* and 0 if the strings are equal according to the specified sort fields.
|
||||
*/
|
||||
function stringCompare($a, $b) {
|
||||
foreach($this->sort_fields as $sort_field) {
|
||||
foreach ($this->sort_fields as $sort_field) {
|
||||
$cmp_result = strcasecmp($a[$sort_field], $b[$sort_field]);
|
||||
if ($cmp_result == 0) continue;
|
||||
return ($this->backwards ? -$cmp_result : $cmp_result);
|
||||
@@ -40,7 +68,6 @@ class array_order {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//$order = new array_order();
|
||||
//$registrations = $order->sort($registrations, 'domain', 'user');
|
||||
|
||||
?>
|
||||
@@ -38,38 +38,41 @@ class auto_loader {
|
||||
const CLASSES_FILE = 'autoloader_cache.php';
|
||||
const INTERFACES_KEY = "autoloader_interfaces";
|
||||
const INTERFACES_FILE = "autoloader_interface_cache.php";
|
||||
|
||||
private $classes;
|
||||
|
||||
/**
|
||||
* Tracks the APCu extension for caching to RAM drive across requests
|
||||
* @var bool
|
||||
*/
|
||||
private $apcu_enabled;
|
||||
|
||||
/**
|
||||
* Cache path and file name for classes
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $classes_file = null;
|
||||
|
||||
/**
|
||||
* Cache path and file name for interfaces
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $interfaces_file = null;
|
||||
private $classes;
|
||||
/**
|
||||
* Tracks the APCu extension for caching to RAM drive across requests
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $apcu_enabled;
|
||||
/**
|
||||
* Maps interfaces to classes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $interfaces;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $traits;
|
||||
|
||||
/**
|
||||
* Cache path and file name for interfaces
|
||||
* @var string
|
||||
* Initializes the class and sets up caching mechanisms.
|
||||
*
|
||||
* @param bool $disable_cache If true, disables cache usage. Defaults to false.
|
||||
*/
|
||||
private static $interfaces_file = null;
|
||||
|
||||
public function __construct($disable_cache = false) {
|
||||
|
||||
//set if we can use RAM cache
|
||||
@@ -93,130 +96,14 @@ class auto_loader {
|
||||
$this->update_cache();
|
||||
}
|
||||
//register this object to load any unknown classes
|
||||
spl_autoload_register(array($this, 'loader'));
|
||||
spl_autoload_register([$this, 'loader']);
|
||||
}
|
||||
|
||||
/**
|
||||
* The loader is set to private because only the PHP engine should be calling this method
|
||||
* @param string $class_name The class name that needs to be loaded
|
||||
* @return bool True if the class is loaded or false when the class is not found
|
||||
* @access private
|
||||
* Loads the class cache from various sources.
|
||||
*
|
||||
* @return bool True if the cache is loaded successfully, false otherwise.
|
||||
*/
|
||||
private function loader($class_name): bool {
|
||||
|
||||
//sanitize the class name
|
||||
$class_name = preg_replace('[^a-zA-Z0-9_]', '', $class_name);
|
||||
|
||||
//find the path using the class_name as the key in the classes array
|
||||
if (isset($this->classes[$class_name])) {
|
||||
//include the class or interface
|
||||
include_once $this->classes[$class_name];
|
||||
|
||||
//return boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
//Smarty has it's own autoloader so reject the request
|
||||
if ($class_name === 'Smarty_Autoloader') {
|
||||
return false;
|
||||
}
|
||||
|
||||
//cache miss
|
||||
self::log(LOG_WARNING, "class '$class_name' not found in cache");
|
||||
|
||||
//set project path using magic dir constant
|
||||
$project_path = dirname(__DIR__, 2);
|
||||
|
||||
//build the search path array
|
||||
$search_path[] = glob($project_path . "/resources/interfaces/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/resources/traits/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/resources/classes/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/*/*/resources/interfaces/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/*/*/resources/traits/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/*/*/resources/classes/" . $class_name . ".php");
|
||||
|
||||
//fix class names in the plugins directory prefixed with 'plugin_'
|
||||
if (str_starts_with($class_name, 'plugin_')) {
|
||||
$class_name = substr($class_name, 7);
|
||||
}
|
||||
$search_path[] = glob($project_path . "/core/authentication/resources/classes/plugins/" . $class_name . ".php");
|
||||
|
||||
//collapse all entries to only the matched entry
|
||||
$matches = array_filter($search_path);
|
||||
if (!empty($matches)) {
|
||||
$path = array_pop($matches)[0];
|
||||
|
||||
//include the class, interface, or trait
|
||||
include_once $path;
|
||||
|
||||
//inject the class in to the array
|
||||
$this->classes[$class_name] = $path;
|
||||
|
||||
//update the cache with new classes
|
||||
$this->update_cache();
|
||||
|
||||
//return boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
//send to syslog when debugging
|
||||
self::log(LOG_ERR, "class '$class_name' not found name");
|
||||
|
||||
//return boolean
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the auto loader
|
||||
*/
|
||||
public function update() {
|
||||
self::clear_cache();
|
||||
$this->reload_classes();
|
||||
$this->update_cache();
|
||||
}
|
||||
|
||||
public function update_cache(): bool {
|
||||
//guard against writing an empty file
|
||||
if (empty($this->classes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//update RAM cache when available
|
||||
if ($this->apcu_enabled) {
|
||||
$classes_cached = apcu_store(self::CLASSES_KEY, $this->classes);
|
||||
$interfaces_cached = apcu_store(self::INTERFACES_KEY, $this->interfaces);
|
||||
//do not save to drive when we are using apcu
|
||||
if ($classes_cached && $interfaces_cached)
|
||||
return true;
|
||||
}
|
||||
|
||||
//export the classes array using PHP engine
|
||||
$classes_array = var_export($this->classes, true);
|
||||
|
||||
//put the array in a form that it can be loaded directly to an array
|
||||
$class_result = file_put_contents(self::$classes_file, "<?php\n return " . $classes_array . ";\n");
|
||||
if ($class_result === false) {
|
||||
//file failed to save - send error to syslog when debugging
|
||||
$error_array = error_get_last();
|
||||
self::log(LOG_WARNING, $error_array['message'] ?? '');
|
||||
}
|
||||
|
||||
//export the interfaces array using PHP engine
|
||||
$interfaces_array = var_export($this->interfaces, true);
|
||||
|
||||
//put the array in a form that it can be loaded directly to an array
|
||||
$interface_result = file_put_contents(self::$interfaces_file, "<?php\n return " . $interfaces_array . ";\n");
|
||||
if ($interface_result === false) {
|
||||
//file failed to save - send error to syslog when debugging
|
||||
$error_array = error_get_last();
|
||||
self::log(LOG_WARNING, $error_array['message'] ?? '');
|
||||
}
|
||||
|
||||
$result = ($class_result && $interface_result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function load_cache(): bool {
|
||||
$this->classes = [];
|
||||
$this->interfaces = [];
|
||||
@@ -251,6 +138,15 @@ class auto_loader {
|
||||
return (!empty($this->classes) && !empty($this->interfaces));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads classes and interfaces from the project's resources.
|
||||
*
|
||||
* This method scans all PHP files in the specified locations, parses their contents,
|
||||
* and updates the internal storage of classes and interfaces. It also processes
|
||||
* implementation relationships between classes and interfaces.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reload_classes() {
|
||||
//set project path using magic dir constant
|
||||
$project_path = dirname(__DIR__, 2);
|
||||
@@ -350,42 +246,85 @@ class auto_loader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of classes loaded by the auto_loader. If no classes have been loaded an empty array is returned.
|
||||
* @return array List of classes loaded by the auto_loader or empty array
|
||||
* Updates the cache by writing the classes and interfaces to files on disk.
|
||||
*
|
||||
* @return bool True if the update was successful, false otherwise
|
||||
*/
|
||||
public function get_class_list(): array {
|
||||
if (!empty($this->classes)) {
|
||||
return $this->classes;
|
||||
public function update_cache(): bool {
|
||||
//guard against writing an empty file
|
||||
if (empty($this->classes)) {
|
||||
return false;
|
||||
}
|
||||
return [];
|
||||
|
||||
//update RAM cache when available
|
||||
if ($this->apcu_enabled) {
|
||||
$classes_cached = apcu_store(self::CLASSES_KEY, $this->classes);
|
||||
$interfaces_cached = apcu_store(self::INTERFACES_KEY, $this->interfaces);
|
||||
//do not save to drive when we are using apcu
|
||||
if ($classes_cached && $interfaces_cached)
|
||||
return true;
|
||||
}
|
||||
|
||||
//export the classes array using PHP engine
|
||||
$classes_array = var_export($this->classes, true);
|
||||
|
||||
//put the array in a form that it can be loaded directly to an array
|
||||
$class_result = file_put_contents(self::$classes_file, "<?php\n return " . $classes_array . ";\n");
|
||||
if ($class_result === false) {
|
||||
//file failed to save - send error to syslog when debugging
|
||||
$error_array = error_get_last();
|
||||
self::log(LOG_WARNING, $error_array['message'] ?? '');
|
||||
}
|
||||
|
||||
//export the interfaces array using PHP engine
|
||||
$interfaces_array = var_export($this->interfaces, true);
|
||||
|
||||
//put the array in a form that it can be loaded directly to an array
|
||||
$interface_result = file_put_contents(self::$interfaces_file, "<?php\n return " . $interfaces_array . ";\n");
|
||||
if ($interface_result === false) {
|
||||
//file failed to save - send error to syslog when debugging
|
||||
$error_array = error_get_last();
|
||||
self::log(LOG_WARNING, $error_array['message'] ?? '');
|
||||
}
|
||||
|
||||
$result = ($class_result && $interface_result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of classes implementing the interface
|
||||
* @param string $interface_name
|
||||
* @return array
|
||||
* Logs a message at the specified level
|
||||
*
|
||||
* @param int $level The log level (e.g. E_ERROR)
|
||||
* @param string $message The log message
|
||||
*/
|
||||
public function get_interface_list(string $interface_name): array {
|
||||
//make sure we can return values
|
||||
if (empty($this->classes) || empty($this->interfaces)) {
|
||||
return [];
|
||||
private static function log(int $level, string $message): void {
|
||||
if (filter_var($_REQUEST['debug'] ?? false, FILTER_VALIDATE_BOOLEAN) || filter_var(getenv('DEBUG') ?? false, FILTER_VALIDATE_BOOLEAN)) {
|
||||
openlog("PHP", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||
syslog($level, "[auto_loader] " . $message);
|
||||
closelog();
|
||||
}
|
||||
//check if we have an interface with that name
|
||||
if (!empty($this->interfaces[$interface_name])) {
|
||||
//return the list of classes associated with that interface
|
||||
return $this->interfaces[$interface_name];
|
||||
}
|
||||
//interface is not implemented by any classes
|
||||
return [];
|
||||
}
|
||||
|
||||
public function get_interfaces(): array {
|
||||
if (!empty($this->interfaces)) {
|
||||
return $this->interfaces;
|
||||
}
|
||||
return [];
|
||||
/**
|
||||
* Main method used to update internal state by clearing cache, reloading classes and updating cache.
|
||||
*
|
||||
* @return void
|
||||
* @see \auto_loader::clear_cache()
|
||||
* @see \auto_loader::reload_classes()
|
||||
* @see \auto_loader::update_cache()
|
||||
*/
|
||||
public function update() {
|
||||
self::clear_cache();
|
||||
$this->reload_classes();
|
||||
$this->update_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cache of stored classes and interfaces.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clear_cache() {
|
||||
|
||||
//check for apcu cache
|
||||
@@ -426,11 +365,120 @@ class auto_loader {
|
||||
}
|
||||
}
|
||||
|
||||
private static function log(int $level, string $message): void {
|
||||
if (filter_var($_REQUEST['debug'] ?? false, FILTER_VALIDATE_BOOL) || filter_var(getenv('DEBUG') ?? false, FILTER_VALIDATE_BOOL)) {
|
||||
openlog("PHP", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||
syslog($level, "[auto_loader] " . $message);
|
||||
closelog();
|
||||
/**
|
||||
* Returns a list of classes loaded by the auto_loader. If no classes have been loaded an empty array is returned.
|
||||
*
|
||||
* @return array List of classes loaded by the auto_loader or empty array
|
||||
*/
|
||||
public function get_class_list(): array {
|
||||
if (!empty($this->classes)) {
|
||||
return $this->classes;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of classes implementing the interface
|
||||
*
|
||||
* @param string $interface_name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_interface_list(string $interface_name): array {
|
||||
//make sure we can return values
|
||||
if (empty($this->classes) || empty($this->interfaces)) {
|
||||
return [];
|
||||
}
|
||||
//check if we have an interface with that name
|
||||
if (!empty($this->interfaces[$interface_name])) {
|
||||
//return the list of classes associated with that interface
|
||||
return $this->interfaces[$interface_name];
|
||||
}
|
||||
//interface is not implemented by any classes
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all user defined interfaces that have been registered.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_interfaces(): array {
|
||||
if (!empty($this->interfaces)) {
|
||||
return $this->interfaces;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* The loader is set to private because only the PHP engine should be calling this method
|
||||
*
|
||||
* @param string $class_name The class name that needs to be loaded
|
||||
*
|
||||
* @return bool True if the class is loaded or false when the class is not found
|
||||
* @access private
|
||||
*/
|
||||
private function loader($class_name): bool {
|
||||
|
||||
//sanitize the class name
|
||||
$class_name = preg_replace('[^a-zA-Z0-9_]', '', $class_name);
|
||||
|
||||
//find the path using the class_name as the key in the classes array
|
||||
if (isset($this->classes[$class_name])) {
|
||||
//include the class or interface
|
||||
include_once $this->classes[$class_name];
|
||||
|
||||
//return boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
//Smarty has it's own autoloader so reject the request
|
||||
if ($class_name === 'Smarty_Autoloader') {
|
||||
return false;
|
||||
}
|
||||
|
||||
//cache miss
|
||||
self::log(LOG_WARNING, "class '$class_name' not found in cache");
|
||||
|
||||
//set project path using magic dir constant
|
||||
$project_path = dirname(__DIR__, 2);
|
||||
|
||||
//build the search path array
|
||||
$search_path[] = glob($project_path . "/resources/interfaces/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/resources/traits/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/resources/classes/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/*/*/resources/interfaces/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/*/*/resources/traits/" . $class_name . ".php");
|
||||
$search_path[] = glob($project_path . "/*/*/resources/classes/" . $class_name . ".php");
|
||||
|
||||
//fix class names in the plugins directory prefixed with 'plugin_'
|
||||
if (str_starts_with($class_name, 'plugin_')) {
|
||||
$class_name = substr($class_name, 7);
|
||||
}
|
||||
$search_path[] = glob($project_path . "/core/authentication/resources/classes/plugins/" . $class_name . ".php");
|
||||
|
||||
//collapse all entries to only the matched entry
|
||||
$matches = array_filter($search_path);
|
||||
if (!empty($matches)) {
|
||||
$path = array_pop($matches)[0];
|
||||
|
||||
//include the class, interface, or trait
|
||||
include_once $path;
|
||||
|
||||
//inject the class in to the array
|
||||
$this->classes[$class_name] = $path;
|
||||
|
||||
//update the cache with new classes
|
||||
$this->update_cache();
|
||||
|
||||
//return boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
//send to syslog when debugging
|
||||
self::log(LOG_ERR, "class '$class_name' not found name");
|
||||
|
||||
//return boolean
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
*
|
||||
* @package binary-to-text-php
|
||||
*/
|
||||
class base2n
|
||||
{
|
||||
class base2n {
|
||||
protected $_chars;
|
||||
protected $_bitsPerCharacter;
|
||||
protected $_radix;
|
||||
@@ -36,21 +35,20 @@ class base2n
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param integer $bitsPerCharacter Bits to use for each encoded character
|
||||
* @param string $chars Base character alphabet
|
||||
* @param boolean $caseSensitive To decode in a case-sensitive manner
|
||||
* @param boolean $rightPadFinalBits How to encode last character
|
||||
* @param boolean $padFinalGroup Add padding to end of encoded output
|
||||
* @param string $padCharacter Character to use for padding
|
||||
* @param integer $bitsPerCharacter Bits to use for each encoded character
|
||||
* @param string $chars Base character alphabet
|
||||
* @param boolean $caseSensitive To decode in a case-sensitive manner
|
||||
* @param boolean $rightPadFinalBits How to encode last character
|
||||
* @param boolean $padFinalGroup Add padding to end of encoded output
|
||||
* @param string $padCharacter Character to use for padding
|
||||
*
|
||||
* @throws InvalidArgumentException for incompatible parameters
|
||||
*/
|
||||
public function __construct(
|
||||
$bitsPerCharacter,
|
||||
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
|
||||
$caseSensitive = TRUE, $rightPadFinalBits = FALSE,
|
||||
$padFinalGroup = FALSE, $padCharacter = '=')
|
||||
{
|
||||
$caseSensitive = true, $rightPadFinalBits = false,
|
||||
$padFinalGroup = false, $padCharacter = '=') {
|
||||
// Ensure validity of $chars
|
||||
if (!is_string($chars) || ($charLength = strlen($chars)) < 2) {
|
||||
throw new InvalidArgumentException('$chars must be a string of at least two characters');
|
||||
@@ -68,7 +66,7 @@ class base2n
|
||||
$padCharFound = stripos($chars, $padCharacter[0]);
|
||||
}
|
||||
|
||||
if ($padCharFound !== FALSE) {
|
||||
if ($padCharFound !== false) {
|
||||
throw new InvalidArgumentException('$padCharacter can not be a member of $chars');
|
||||
}
|
||||
}
|
||||
@@ -94,9 +92,9 @@ class base2n
|
||||
|
||||
$radix >>= 1;
|
||||
throw new InvalidArgumentException(
|
||||
'$bitsPerCharacter can not be more than ' . $bitsPerCharacter
|
||||
. ' given $chars length of ' . $charLength
|
||||
. ' (max radix ' . $radix . ')');
|
||||
'$bitsPerCharacter can not be more than ' . $bitsPerCharacter
|
||||
. ' given $chars length of ' . $charLength
|
||||
. ' (max radix ' . $radix . ')');
|
||||
|
||||
} elseif ($bitsPerCharacter > 8) {
|
||||
// $bitsPerCharacter must not be greater than 8
|
||||
@@ -106,23 +104,23 @@ class base2n
|
||||
$radix = 1 << $bitsPerCharacter;
|
||||
}
|
||||
|
||||
$this->_chars = $chars;
|
||||
$this->_bitsPerCharacter = $bitsPerCharacter;
|
||||
$this->_radix = $radix;
|
||||
$this->_chars = $chars;
|
||||
$this->_bitsPerCharacter = $bitsPerCharacter;
|
||||
$this->_radix = $radix;
|
||||
$this->_rightPadFinalBits = $rightPadFinalBits;
|
||||
$this->_padFinalGroup = $padFinalGroup;
|
||||
$this->_padCharacter = $padCharacter[0];
|
||||
$this->_caseSensitive = $caseSensitive;
|
||||
$this->_padFinalGroup = $padFinalGroup;
|
||||
$this->_padCharacter = $padCharacter[0];
|
||||
$this->_caseSensitive = $caseSensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a string
|
||||
*
|
||||
* @param string $rawString Binary data to encode
|
||||
* @param string $rawString Binary data to encode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encode($rawString)
|
||||
{
|
||||
public function encode($rawString) {
|
||||
// Unpack string into an array of bytes
|
||||
$bytes = unpack('C*', $rawString);
|
||||
$byteCount = count($bytes);
|
||||
@@ -132,11 +130,11 @@ class base2n
|
||||
$bitsRead = 0;
|
||||
$oldBits = 0;
|
||||
|
||||
$chars = $this->_chars;
|
||||
$bitsPerCharacter = $this->_bitsPerCharacter;
|
||||
$chars = $this->_chars;
|
||||
$bitsPerCharacter = $this->_bitsPerCharacter;
|
||||
$rightPadFinalBits = $this->_rightPadFinalBits;
|
||||
$padFinalGroup = $this->_padFinalGroup;
|
||||
$padCharacter = $this->_padCharacter;
|
||||
$padFinalGroup = $this->_padFinalGroup;
|
||||
$padCharacter = $this->_padCharacter;
|
||||
|
||||
$charsPerByte = 8 / $bitsPerCharacter;
|
||||
$encodedLength = $byteCount * $charsPerByte;
|
||||
@@ -159,7 +157,7 @@ class base2n
|
||||
|
||||
if ($padFinalGroup) {
|
||||
// Array of the lowest common multiples of $bitsPerCharacter and 8, divided by 8
|
||||
$lcmMap = array(1 => 1, 2 => 1, 3 => 3, 4 => 1, 5 => 5, 6 => 3, 7 => 7, 8 => 1);
|
||||
$lcmMap = [1 => 1, 2 => 1, 3 => 3, 4 => 1, 5 => 5, 6 => 3, 7 => 7, 8 => 1];
|
||||
$bytesPerGroup = $lcmMap[$bitsPerCharacter];
|
||||
$pads = $bytesPerGroup * $charsPerByte - ceil((strlen($rawString) % $bytesPerGroup) * $charsPerByte);
|
||||
$encodedString .= str_repeat($padCharacter, $pads);
|
||||
@@ -183,7 +181,7 @@ class base2n
|
||||
$bitsRead += $newBitCount;
|
||||
|
||||
if ($oldBitCount) {
|
||||
// Bits come from seperate bytes, add $oldBits to $bits
|
||||
// Bits come from separate bytes, add $oldBits to $bits
|
||||
$bits = ($oldBits << $newBitCount) | $bits;
|
||||
}
|
||||
|
||||
@@ -196,31 +194,31 @@ class base2n
|
||||
/**
|
||||
* Decode a string
|
||||
*
|
||||
* @param string $encodedString Data to decode
|
||||
* @param boolean $strict Returns NULL if $encodedString contains an undecodable character
|
||||
* @param string $encodedString Data to decode
|
||||
* @param boolean $strict Returns NULL if $encodedString contains an undecodable character
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function decode($encodedString, $strict = FALSE)
|
||||
{
|
||||
public function decode($encodedString, $strict = false) {
|
||||
if (!$encodedString || !is_string($encodedString)) {
|
||||
// Empty string, nothing to decode
|
||||
return '';
|
||||
}
|
||||
|
||||
$chars = $this->_chars;
|
||||
$bitsPerCharacter = $this->_bitsPerCharacter;
|
||||
$radix = $this->_radix;
|
||||
$chars = $this->_chars;
|
||||
$bitsPerCharacter = $this->_bitsPerCharacter;
|
||||
$radix = $this->_radix;
|
||||
$rightPadFinalBits = $this->_rightPadFinalBits;
|
||||
$padFinalGroup = $this->_padFinalGroup;
|
||||
$padCharacter = $this->_padCharacter;
|
||||
$caseSensitive = $this->_caseSensitive;
|
||||
$padFinalGroup = $this->_padFinalGroup;
|
||||
$padCharacter = $this->_padCharacter;
|
||||
$caseSensitive = $this->_caseSensitive;
|
||||
|
||||
// Get index of encoded characters
|
||||
if ($this->_charmap) {
|
||||
$charmap = $this->_charmap;
|
||||
|
||||
} else {
|
||||
$charmap = array();
|
||||
$charmap = [];
|
||||
|
||||
for ($i = 0; $i < $radix; $i++) {
|
||||
$charmap[$chars[$i]] = $i;
|
||||
@@ -293,12 +291,10 @@ class base2n
|
||||
|
||||
} elseif ($strict) {
|
||||
// Unable to decode character; abort
|
||||
return NULL;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $rawString;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -25,123 +25,144 @@
|
||||
Mark J Crane <markjcrane@fusionpbx.com>
|
||||
*/
|
||||
|
||||
class button {
|
||||
class button {
|
||||
|
||||
public static $collapse = 'hide-md-dn';
|
||||
public static $collapse = 'hide-md-dn';
|
||||
|
||||
public static function create($array) {
|
||||
global $settings;
|
||||
/**
|
||||
* Creates a button element based on the provided array of attributes.
|
||||
*
|
||||
* @param array $array An array containing button attributes, such as type, name, value, id, label, title, onclick,
|
||||
* etc.
|
||||
*
|
||||
* @return string The created button element as a string.
|
||||
*/
|
||||
public static function create($array) {
|
||||
global $settings;
|
||||
|
||||
$button_icons = $settings->get('theme', 'button_icons', 'auto');
|
||||
//parse styles into array
|
||||
if (!empty($array['style'])) {
|
||||
$tmp = explode(';',$array['style']);
|
||||
foreach ($tmp as $style) {
|
||||
if (!empty($style)) {
|
||||
$style = explode(':', $style);
|
||||
if (is_array($style) && @sizeof($style) == 2) {
|
||||
$styles[trim($style[0])] = trim($style[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$array['style'] = $styles;
|
||||
unset($styles);
|
||||
}
|
||||
//button: open
|
||||
$button = "<button ";
|
||||
$button .= "type='".(!empty($array['type']) ? $array['type'] : 'button')."' ";
|
||||
$button .= !empty($array['name']) ? "name=".self::quote($array['name'])." " : null;
|
||||
$button .= !empty($array['value']) ? "value=".self::quote($array['value'])." " : null;
|
||||
$button .= !empty($array['id']) ? "id='".$array['id']."' " : null;
|
||||
$button .= !empty($array['label']) ? "alt=".self::quote($array['label'])." " : (!empty($array['title']) ? "alt=".self::quote($array['title'])." " : null);
|
||||
if ($button_icons == 'only' || $button_icons == 'auto' || $array['title']) {
|
||||
if (!empty($array['title']) || !empty($array['label'])) {
|
||||
$button .= "title=".(!empty($array['title']) ? self::quote($array['title']) : self::quote($array['label']))." ";
|
||||
$button_icons = $settings->get('theme', 'button_icons', 'auto');
|
||||
//parse styles into array
|
||||
if (!empty($array['style'])) {
|
||||
$tmp = explode(';', $array['style']);
|
||||
foreach ($tmp as $style) {
|
||||
if (!empty($style)) {
|
||||
$style = explode(':', $style);
|
||||
if (is_array($style) && @sizeof($style) == 2) {
|
||||
$styles[trim($style[0])] = trim($style[1]);
|
||||
}
|
||||
}
|
||||
$button .= !empty($array['onclick']) ? "onclick=".self::quote($array['onclick'])." " : null;
|
||||
$button .= !empty($array['onmouseover']) ? "onmouseenter=".self::quote($array['onmouseover'])." " : null;
|
||||
$button .= !empty($array['onmouseout']) ? "onmouseleave=".self::quote($array['onmouseout'])." " : null;
|
||||
//detect class addition (using + prefix)
|
||||
$button_class = !empty($array['class']) && substr($array['class'],0,1) == '+' ? 'default '.substr($array['class'], 1) : $array['class'] ?? '';
|
||||
$button .= "class='btn btn-".(!empty($button_class) ? $button_class : 'default')." ".(isset($array['disabled']) && $array['disabled'] ? 'disabled' : null)."' ";
|
||||
//ensure margin* styles are not applied to the button element when a link is defined
|
||||
if (!empty($array['style']) && is_array($array['style']) && @sizeof($array['style']) != 0) {
|
||||
$styles = '';
|
||||
foreach ($array['style'] as $property => $value) {
|
||||
if (empty($array['link']) || !substr_count($property, 'margin')) {
|
||||
$styles .= $property.': '.$value.'; ';
|
||||
}
|
||||
}
|
||||
$button .= $styles ? "style=".self::quote($styles)." " : null;
|
||||
unset($styles);
|
||||
}
|
||||
$button .= isset($array['disabled']) && $array['disabled'] ? "disabled='disabled' " : null;
|
||||
$button .= ">";
|
||||
//icon
|
||||
if (!empty($array['icon']) && (
|
||||
$button_icons == 'only' ||
|
||||
$button_icons == 'always' ||
|
||||
$button_icons == 'auto' ||
|
||||
!$array['label']
|
||||
)) {
|
||||
$icon_class = is_array($array['icon']) ? $array['icon']['text'] : $array['icon'];
|
||||
$button .= "<span class='".(substr($icon_class, 0, 3) != 'fa-' ? 'fa-solid fa-' : null).$icon_class." fa-fw'></span>";
|
||||
}
|
||||
//label
|
||||
if (!empty($array['label']) && (
|
||||
$button_icons != 'only' ||
|
||||
!$array['icon'] ||
|
||||
$array['class'] == 'link'
|
||||
)) {
|
||||
if (!empty($array['icon']) && $button_icons != 'always' && $button_icons != 'never' && isset($array['collapse']) && $array['collapse'] !== false) {
|
||||
if ($array['collapse'] != '') {
|
||||
$collapse_class = $array['collapse'];
|
||||
}
|
||||
else if (self::$collapse !== false) {
|
||||
$collapse_class = self::$collapse;
|
||||
}
|
||||
}
|
||||
$pad_class = !empty($array['icon']) ? 'pad' : null;
|
||||
$button .= "<span class='button-label ".($collapse_class ?? '')." ".$pad_class."'>".$array['label']."</span>";
|
||||
}
|
||||
//button: close
|
||||
$button .= "</button>";
|
||||
//link
|
||||
if (!empty($array['link'])) {
|
||||
$anchor = "<a ";
|
||||
$anchor .= "href='" . self::escape_href($array['link']) . "' ";
|
||||
$anchor .= "target='".(!empty($array['target']) ? $array['target'] : '_self')."' ";
|
||||
//ensure only margin* styles are applied to the anchor element
|
||||
if (!empty($array['style']) && is_array($array['style']) && @sizeof($array['style']) != 0) {
|
||||
$styles = '';
|
||||
foreach ($array['style'] as $property => $value) {
|
||||
if (substr_count($property, 'margin')) {
|
||||
$styles .= $property.': '.$value.'; ';
|
||||
}
|
||||
}
|
||||
$anchor .= $styles ? "style=".self::quote($styles)." " : null;
|
||||
unset($styles);
|
||||
}
|
||||
$anchor .= isset($array['disabled']) && $array['disabled'] ? "class='disabled' onclick='return false;' " : null;
|
||||
$anchor .= ">";
|
||||
$button = $anchor.$button."</a>";
|
||||
}
|
||||
return $button;
|
||||
}
|
||||
$array['style'] = $styles;
|
||||
unset($styles);
|
||||
}
|
||||
|
||||
private static function quote($value) {
|
||||
return substr_count($value, "'") ? '"'.$value.'"' : "'".$value."'";
|
||||
//button: open
|
||||
$button = "<button ";
|
||||
$button .= "type='" . (!empty($array['type']) ? $array['type'] : 'button') . "' ";
|
||||
$button .= !empty($array['name']) ? "name=" . self::quote($array['name']) . " " : null;
|
||||
$button .= !empty($array['value']) ? "value=" . self::quote($array['value']) . " " : null;
|
||||
$button .= !empty($array['id']) ? "id='" . $array['id'] . "' " : null;
|
||||
$button .= !empty($array['label']) ? "alt=" . self::quote($array['label']) . " " : (!empty($array['title']) ? "alt=" . self::quote($array['title']) . " " : null);
|
||||
if ($button_icons == 'only' || $button_icons == 'auto' || $array['title']) {
|
||||
if (!empty($array['title']) || !empty($array['label'])) {
|
||||
$button .= "title=" . (!empty($array['title']) ? self::quote($array['title']) : self::quote($array['label'])) . " ";
|
||||
}
|
||||
}
|
||||
|
||||
private static function escape_href(string $url): string {
|
||||
// clear whitespace
|
||||
$url = trim($url);
|
||||
|
||||
return htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
|
||||
$button .= !empty($array['onclick']) ? "onclick=" . self::quote($array['onclick']) . " " : null;
|
||||
$button .= !empty($array['onmouseover']) ? "onmouseenter=" . self::quote($array['onmouseover']) . " " : null;
|
||||
$button .= !empty($array['onmouseout']) ? "onmouseleave=" . self::quote($array['onmouseout']) . " " : null;
|
||||
//detect class addition (using + prefix)
|
||||
$button_class = !empty($array['class']) && substr($array['class'], 0, 1) == '+' ? 'default ' . substr($array['class'], 1) : $array['class'] ?? '';
|
||||
$button .= "class='btn btn-" . (!empty($button_class) ? $button_class : 'default') . " " . (isset($array['disabled']) && $array['disabled'] ? 'disabled' : null) . "' ";
|
||||
//ensure margin* styles are not applied to the button element when a link is defined
|
||||
if (!empty($array['style']) && is_array($array['style']) && @sizeof($array['style']) != 0) {
|
||||
$styles = '';
|
||||
foreach ($array['style'] as $property => $value) {
|
||||
if (empty($array['link']) || !substr_count($property, 'margin')) {
|
||||
$styles .= $property . ': ' . $value . '; ';
|
||||
}
|
||||
}
|
||||
$button .= $styles ? "style=" . self::quote($styles) . " " : null;
|
||||
unset($styles);
|
||||
}
|
||||
$button .= isset($array['disabled']) && $array['disabled'] ? "disabled='disabled' " : null;
|
||||
$button .= ">";
|
||||
//icon
|
||||
if (!empty($array['icon']) && (
|
||||
$button_icons == 'only' ||
|
||||
$button_icons == 'always' ||
|
||||
$button_icons == 'auto' ||
|
||||
!$array['label']
|
||||
)) {
|
||||
$icon_class = is_array($array['icon']) ? $array['icon']['text'] : $array['icon'];
|
||||
$button .= "<span class='" . (substr($icon_class, 0, 3) != 'fa-' ? 'fa-solid fa-' : null) . $icon_class . " fa-fw'></span>";
|
||||
}
|
||||
//label
|
||||
if (!empty($array['label']) && (
|
||||
$button_icons != 'only' ||
|
||||
!$array['icon'] ||
|
||||
$array['class'] == 'link'
|
||||
)) {
|
||||
if (!empty($array['icon']) && $button_icons != 'always' && $button_icons != 'never' && isset($array['collapse']) && $array['collapse'] !== false) {
|
||||
if ($array['collapse'] != '') {
|
||||
$collapse_class = $array['collapse'];
|
||||
} elseif (self::$collapse !== false) {
|
||||
$collapse_class = self::$collapse;
|
||||
}
|
||||
}
|
||||
$pad_class = !empty($array['icon']) ? 'pad' : null;
|
||||
$button .= "<span class='button-label " . ($collapse_class ?? '') . " " . $pad_class . "'>" . $array['label'] . "</span>";
|
||||
}
|
||||
//button: close
|
||||
$button .= "</button>";
|
||||
//link
|
||||
if (!empty($array['link'])) {
|
||||
$anchor = "<a ";
|
||||
$anchor .= "href='" . self::escape_href($array['link']) . "' ";
|
||||
$anchor .= "target='" . (!empty($array['target']) ? $array['target'] : '_self') . "' ";
|
||||
//ensure only margin* styles are applied to the anchor element
|
||||
if (!empty($array['style']) && is_array($array['style']) && @sizeof($array['style']) != 0) {
|
||||
$styles = '';
|
||||
foreach ($array['style'] as $property => $value) {
|
||||
if (substr_count($property, 'margin')) {
|
||||
$styles .= $property . ': ' . $value . '; ';
|
||||
}
|
||||
}
|
||||
$anchor .= $styles ? "style=" . self::quote($styles) . " " : null;
|
||||
unset($styles);
|
||||
}
|
||||
$anchor .= isset($array['disabled']) && $array['disabled'] ? "class='disabled' onclick='return false;' " : null;
|
||||
$anchor .= ">";
|
||||
$button = $anchor . $button . "</a>";
|
||||
}
|
||||
return $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a value by surrounding it with single or double quotes based on whether it contains single quotes.
|
||||
*
|
||||
* @param string $value The value to be quoted.
|
||||
*
|
||||
* @return string The quoted value.
|
||||
*/
|
||||
private static function quote($value) {
|
||||
return substr_count($value, "'") ? '"' . $value . '"' : "'" . $value . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a URL by removing leading/trailing whitespace and encoding special characters.
|
||||
*
|
||||
* @param string $url The URL to escape.
|
||||
*
|
||||
* @return string The escaped URL.
|
||||
*/
|
||||
private static function escape_href(string $url): string {
|
||||
// clear whitespace
|
||||
$url = trim($url);
|
||||
|
||||
return htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
//usage
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Provides an abstracted cache
|
||||
*/
|
||||
@@ -11,7 +10,11 @@ class cache {
|
||||
private $method;
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
* Initializes the cache object with default settings if none are provided.
|
||||
*
|
||||
* @param settings|null $settings The settings to use for initialization. Defaults to null.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(settings $settings = null) {
|
||||
//set defaults
|
||||
@@ -29,217 +32,236 @@ class cache {
|
||||
$this->location = '/var/cache/fusionpbx';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific cache setting from the settings array.
|
||||
*
|
||||
* @param string $subcategory The subcategory of the cache setting to retrieve.
|
||||
*
|
||||
* @return mixed The value of the specified cache setting, or null if it does not exist.
|
||||
*/
|
||||
private function setting($subcategory) {
|
||||
return $this->settings->get('cache', $subcategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a specific item in the cache
|
||||
* @var string $key the cache id
|
||||
* @var string $value string to be cached
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
|
||||
//change the delimiter
|
||||
$key = str_replace(":", ".", $key);
|
||||
|
||||
//save to memcache
|
||||
if ($this->method === "memcache") {
|
||||
//connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache set ".$key." ".$value;
|
||||
$result = event_socket::api($command);
|
||||
|
||||
}
|
||||
|
||||
//save to the file cache
|
||||
if ($this->method === "file") {
|
||||
$result = file_put_contents($this->location . "/" . $key, $value);
|
||||
}
|
||||
|
||||
//return result
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific item from the cache
|
||||
* @var string $key cache id
|
||||
* Retrieve the value associated with a given cache key.
|
||||
*
|
||||
* @param string $key The cache key to retrieve. Delimiter is automatically changed from ':' to '.'.
|
||||
*
|
||||
* @return mixed The cached value, or null if it does not exist.
|
||||
*/
|
||||
public function get($key) {
|
||||
|
||||
//change the delimiter
|
||||
$key = str_replace(":", ".", $key);
|
||||
$key = str_replace(":", ".", $key);
|
||||
|
||||
//cache method memcache
|
||||
if ($this->method === "memcache") {
|
||||
// connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if (!$esl->is_connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache get ".$key;
|
||||
$result = event_socket::api($command);
|
||||
|
||||
if ($this->method === "memcache") {
|
||||
// connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if (!$esl->is_connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache get " . $key;
|
||||
$result = event_socket::api($command);
|
||||
|
||||
}
|
||||
|
||||
//get the file cache
|
||||
if ($this->method === "file") {
|
||||
if (file_exists($this->location . "/" . $key)) {
|
||||
$result = file_get_contents($this->location . "/" . $key);
|
||||
}
|
||||
if ($this->method === "file") {
|
||||
if (file_exists($this->location . "/" . $key)) {
|
||||
$result = file_get_contents($this->location . "/" . $key);
|
||||
}
|
||||
}
|
||||
|
||||
//return result
|
||||
return $result ?? null;
|
||||
return $result ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specific item from the cache
|
||||
* @var string $key cache id
|
||||
* Set a value in the cache based on the cache type in global default settings.
|
||||
*
|
||||
* Cache location is based on the global default setting for either "memcache" or "file".
|
||||
*
|
||||
* @param string $key The key of the value to set.
|
||||
* @param mixed $value The value to store.
|
||||
*
|
||||
* @return mixed When location is "file" the return value is in bytes written or null. When location is "memcache"
|
||||
* return value is the return value from the switch socket response or false.
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
|
||||
//change the delimiter
|
||||
$key = str_replace(":", ".", $key);
|
||||
|
||||
//save to memcache
|
||||
if ($this->method === "memcache") {
|
||||
//connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache set " . $key . " " . $value;
|
||||
$result = event_socket::api($command);
|
||||
|
||||
}
|
||||
|
||||
//save to the file cache
|
||||
if ($this->method === "file") {
|
||||
$result = file_put_contents($this->location . "/" . $key, $value);
|
||||
}
|
||||
|
||||
//return result
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a single cache key.
|
||||
*
|
||||
* @param string $key The cache key to delete
|
||||
*
|
||||
* @return bool When cache type is "memcache" false is returned on failure otherwise no value is returned
|
||||
*/
|
||||
public function delete($key) {
|
||||
|
||||
//debug information
|
||||
if ($this->syslog === "true") {
|
||||
openlog("fusionpbx", LOG_PID | LOG_PERROR, LOG_USER);
|
||||
syslog(LOG_WARNING, "debug: cache: [key: ".$key.", script: ".$_SERVER['SCRIPT_NAME'].", line: ".__line__."]");
|
||||
closelog();
|
||||
}
|
||||
if ($this->syslog === "true") {
|
||||
openlog("fusionpbx", LOG_PID | LOG_PERROR, LOG_USER);
|
||||
syslog(LOG_WARNING, "debug: cache: [key: " . $key . ", script: " . $_SERVER['SCRIPT_NAME'] . ", line: " . __line__ . "]");
|
||||
closelog();
|
||||
}
|
||||
|
||||
//cache method memcache
|
||||
if ($this->method === "memcache") {
|
||||
//connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::memcache\n";
|
||||
$event .= "API-Command: memcache\n";
|
||||
$event .= "API-Command-Argument: delete ".$key."\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache delete ".$key;
|
||||
$result = event_socket::api($command);
|
||||
|
||||
if ($this->method === "memcache") {
|
||||
//connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::memcache\n";
|
||||
$event .= "API-Command: memcache\n";
|
||||
$event .= "API-Command-Argument: delete " . $key . "\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache delete " . $key;
|
||||
$result = event_socket::api($command);
|
||||
|
||||
}
|
||||
|
||||
//cache method file
|
||||
if ($this->method === "file") {
|
||||
//change the delimiter
|
||||
$key = str_replace(":", ".", $key);
|
||||
if ($this->method === "file") {
|
||||
//change the delimiter
|
||||
$key = str_replace(":", ".", $key);
|
||||
|
||||
//connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::file\n";
|
||||
$event .= "API-Command: cache\n";
|
||||
$event .= "API-Command-Argument: delete ".$key."\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//remove the local files
|
||||
foreach (glob($this->location . "/" . $key) as $file) {
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
if (file_exists($file)) {
|
||||
unlink($file . ".tmp");
|
||||
}
|
||||
}
|
||||
//connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::file\n";
|
||||
$event .= "API-Command: cache\n";
|
||||
$event .= "API-Command-Argument: delete " . $key . "\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//remove the local files
|
||||
foreach (glob($this->location . "/" . $key) as $file) {
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
if (file_exists($file)) {
|
||||
unlink($file . ".tmp");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the entire cache
|
||||
* Flushes the cache based on the current method setting.
|
||||
*
|
||||
* @return string|false The result of the flush operation, or false if an error occurred.
|
||||
*/
|
||||
public function flush() {
|
||||
|
||||
//debug information
|
||||
if ($this->syslog === "true") {
|
||||
openlog("fusionpbx", LOG_PID | LOG_PERROR, LOG_USER);
|
||||
syslog(LOG_WARNING, "debug: cache: [flush: all, script: ".$_SERVER['SCRIPT_NAME'].", line: ".__line__."]");
|
||||
closelog();
|
||||
}
|
||||
if ($this->syslog === "true") {
|
||||
openlog("fusionpbx", LOG_PID | LOG_PERROR, LOG_USER);
|
||||
syslog(LOG_WARNING, "debug: cache: [flush: all, script: " . $_SERVER['SCRIPT_NAME'] . ", line: " . __line__ . "]");
|
||||
closelog();
|
||||
}
|
||||
|
||||
//check for apcu extension
|
||||
if (function_exists('apcu_enabled') && apcu_enabled()) {
|
||||
//flush everything
|
||||
apcu_clear_cache();
|
||||
}
|
||||
if (function_exists('apcu_enabled') && apcu_enabled()) {
|
||||
//flush everything
|
||||
apcu_clear_cache();
|
||||
}
|
||||
|
||||
//remove the autoloader file cache
|
||||
if (file_exists(sys_get_temp_dir() . '/' . auto_loader::CLASSES_FILE)) {
|
||||
@unlink(sys_get_temp_dir() . '/' . auto_loader::CLASSES_FILE);
|
||||
}
|
||||
if (file_exists(sys_get_temp_dir() . '/' . auto_loader::CLASSES_FILE)) {
|
||||
@unlink(sys_get_temp_dir() . '/' . auto_loader::CLASSES_FILE);
|
||||
}
|
||||
|
||||
//cache method memcache
|
||||
if ($this->method === "memcache") {
|
||||
// connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::memcache\n";
|
||||
$event .= "API-Command: memcache\n";
|
||||
$event .= "API-Command-Argument: flush\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache flush";
|
||||
$result = event_socket::api($command);
|
||||
|
||||
if ($this->method === "memcache") {
|
||||
// connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::memcache\n";
|
||||
$event .= "API-Command: memcache\n";
|
||||
$event .= "API-Command-Argument: flush\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//run the memcache
|
||||
$command = "memcache flush";
|
||||
$result = event_socket::api($command);
|
||||
|
||||
}
|
||||
|
||||
//cache method file
|
||||
if ($this->method === "file") {
|
||||
// connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::file\n";
|
||||
$event .= "API-Command: cache\n";
|
||||
$event .= "API-Command-Argument: flush\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//remove the cache
|
||||
recursive_delete($this->location);
|
||||
|
||||
//set message
|
||||
$result = '+OK cache flushed';
|
||||
if ($this->method === "file") {
|
||||
// connect to event socket
|
||||
$esl = event_socket::create();
|
||||
if ($esl === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//send a custom event
|
||||
$event = "sendevent CUSTOM\n";
|
||||
$event .= "Event-Name: CUSTOM\n";
|
||||
$event .= "Event-Subclass: fusion::file\n";
|
||||
$event .= "API-Command: cache\n";
|
||||
$event .= "API-Command-Argument: flush\n";
|
||||
event_socket::command($event);
|
||||
|
||||
//remove the cache
|
||||
recursive_delete($this->location);
|
||||
|
||||
//set message
|
||||
$result = '+OK cache flushed';
|
||||
}
|
||||
|
||||
//return result
|
||||
return $result;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -32,20 +32,32 @@
|
||||
class captcha {
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
*/
|
||||
* Called when the object is created
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the captcha image
|
||||
* @var string $code
|
||||
* Returns a Base64 encoded version of the CAPTCHA image.
|
||||
*
|
||||
* @return string The Base64 encoded CAPTCHA image data.
|
||||
*/
|
||||
public function image_base64() {
|
||||
return base64_encode($this->image_captcha());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a CAPTCHA image.
|
||||
*
|
||||
* Requires the object property code for the text to create
|
||||
*
|
||||
* @return string The CAPTCHA image buffer.
|
||||
*/
|
||||
public function image_captcha() {
|
||||
|
||||
@@ -54,25 +66,25 @@ class captcha {
|
||||
$text = $this->code;
|
||||
|
||||
// Set the font path
|
||||
$font_path = $_SERVER["DOCUMENT_ROOT"]."/resources/captcha/fonts";
|
||||
$font_path = $_SERVER["DOCUMENT_ROOT"] . "/resources/captcha/fonts";
|
||||
|
||||
// Array of fonts
|
||||
//$fonts[] = 'ROUGD.TTF';
|
||||
//$fonts[] = 'Zebra.ttf';
|
||||
//$fonts[] = 'hanshand.ttf';
|
||||
$fonts = glob($font_path.'/*.[tT][tT][fF]');
|
||||
$fonts = glob($font_path . '/*.[tT][tT][fF]');
|
||||
//print_r($fonts);
|
||||
//exit;
|
||||
|
||||
// Randomize the fonts
|
||||
srand();
|
||||
$random = (rand()%count($fonts));
|
||||
$random = (rand() % count($fonts));
|
||||
//$font = $font_path.'/'.$fonts[$random];
|
||||
$font = $fonts[$random];
|
||||
|
||||
// Set the font size
|
||||
$font_size = 16;
|
||||
if(@$_GET['fontsize']) {
|
||||
if (@$_GET['fontsize']) {
|
||||
$font_size = $_GET['fontsize'];
|
||||
}
|
||||
|
||||
@@ -109,15 +121,14 @@ class captcha {
|
||||
}
|
||||
|
||||
/**
|
||||
* return the image in base64
|
||||
*/
|
||||
public function image_base64() {
|
||||
return base64_encode($this->image_captcha());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image size
|
||||
* @var string $value string image size
|
||||
* Calculates the bounding box of a text in an image.
|
||||
*
|
||||
* @param int $size The size of the font.
|
||||
* @param float $angle The angle of rotation.
|
||||
* @param string $font The path to the font file.
|
||||
* @param string $text The text to be rendered.
|
||||
*
|
||||
* @return array An array containing the bounding box coordinates (x, y, w, h).
|
||||
*/
|
||||
private function image_size($size, $angle, $font, $text) {
|
||||
$dummy = imagecreate(1, 1);
|
||||
@@ -135,5 +146,3 @@ $captcha->code = 'abcdefg';
|
||||
$image_base64 = $captcha->base64();
|
||||
echo "<img src=\"data:image/png;base64, ".$image_base64."\" />\n";
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
/**
|
||||
* Container object for creating command line options when creating a service
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
class command_option {
|
||||
@@ -52,9 +53,11 @@ class command_option {
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method to create a new command_option
|
||||
* @param type $options
|
||||
* @return command_option
|
||||
* Creates a new instance of CommandOption with automatically assigned properties.
|
||||
*
|
||||
* @param array $options Key/Value pairs to assign as properties on the new instance.
|
||||
*
|
||||
* @return command_option Returns a populated instance of command_option.
|
||||
*/
|
||||
public static function new(...$options): command_option {
|
||||
$obj = new command_option();
|
||||
@@ -67,6 +70,15 @@ class command_option {
|
||||
}
|
||||
|
||||
// used to parse object values when created
|
||||
|
||||
/**
|
||||
* Recursively parses the provided options array and applies its values to the given object.
|
||||
*
|
||||
* @param mixed $obj The object whose properties will be updated with the parsed options
|
||||
* @param array $options The associative array containing the options to parse and apply
|
||||
*
|
||||
* @return void This method does not return a value, it updates the provided object instead.
|
||||
*/
|
||||
private static function parse_options($obj, $options) {
|
||||
foreach ($options as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
@@ -81,9 +93,63 @@ class command_option {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the callback function to the array of existing callback functions
|
||||
*
|
||||
* @param string|null $function When function param is set, the callback function will be appended to the list of
|
||||
* functions. When called without a param, the array will be returned of current
|
||||
* callbacks.
|
||||
*
|
||||
* @return $this|array Returns the array of callbacks if no parameters passed or this object when appending a
|
||||
* callback
|
||||
*/
|
||||
public function callback(?string $function = null) {
|
||||
if ($function !== null) {
|
||||
$this->functions += [$function];
|
||||
return $this;
|
||||
}
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the callback function to the array of existing callback functions
|
||||
*
|
||||
* @param string|null $function When function param is set, the callback function will be appended to the list of
|
||||
* functions. When called without a param, the array will be returned of current
|
||||
* callbacks.
|
||||
*
|
||||
* @return $this|array Returns the array of callbacks if no parameters passed or this object when appending a
|
||||
* callback
|
||||
*/
|
||||
public function function_append(?string $function = null) {
|
||||
if ($function !== null) {
|
||||
$this->functions += [$function];
|
||||
return $this;
|
||||
}
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the current object to an array.
|
||||
*
|
||||
* @return array The array representation of the current object, containing
|
||||
* information about options and functions.
|
||||
*/
|
||||
public function to_array(): array {
|
||||
$array['short_option'] = $this->short_option();
|
||||
$array['long_option'] = $this->long_option();
|
||||
$array['description'] = $this->description();
|
||||
$array['short_description'] = $this->short_description();
|
||||
$array['long_description'] = $this->long_description();
|
||||
$array['functions'] = $this->functions();
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or returns the short option value
|
||||
*
|
||||
* @param string|null $short_option
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function short_option(?string $short_option = null) {
|
||||
@@ -96,7 +162,9 @@ class command_option {
|
||||
|
||||
/**
|
||||
* Sets or returns the long option value
|
||||
*
|
||||
* @param string|null $long_option
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function long_option(?string $long_option = null) {
|
||||
@@ -109,7 +177,9 @@ class command_option {
|
||||
|
||||
/**
|
||||
* Set the general description
|
||||
*
|
||||
* @param string|null $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function description(?string $description = null) {
|
||||
@@ -122,7 +192,10 @@ class command_option {
|
||||
|
||||
/**
|
||||
* Sets or returns the short_description. If short_description is empty then the short_option is used as a default.
|
||||
* @param string|null $short_description When parameter is null, it returns the currently set value. When not null the short description is set to the passed value.
|
||||
*
|
||||
* @param string|null $short_description When parameter is null, it returns the currently set value. When not null
|
||||
* the short description is set to the passed value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function short_description(?string $short_description = null) {
|
||||
@@ -145,8 +218,11 @@ class command_option {
|
||||
|
||||
/**
|
||||
* Sets or returns the long_description. If long_description is empty then the long_option is used as a default.
|
||||
* @param string|null $long_description When parameter is null, it returns the currently set value. When not null the long description is set to the passed value.
|
||||
* @return $this
|
||||
*
|
||||
* @param string|null $long_description When parameter is null, it returns the currently set value. When not null
|
||||
* the long description is set to the passed value.
|
||||
*
|
||||
* @return self|string
|
||||
*/
|
||||
public function long_description(?string $long_description = null) {
|
||||
if ($long_description !== null) {
|
||||
@@ -167,9 +243,13 @@ class command_option {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array of callback functions replacing the existing callback functions
|
||||
* @param array|null $functions
|
||||
* @return $this
|
||||
* Sets or retrieves the array of callback functions
|
||||
*
|
||||
* @param array|null $functions When functions param is set, the array will be assigned to the list of callbacks.
|
||||
* When called without a parameter, the current array of callbacks will be returned.
|
||||
*
|
||||
* @return $this|array Returns the array of callbacks if no parameters passed or this object when setting a new
|
||||
* array
|
||||
*/
|
||||
public function functions(?array $functions = null) {
|
||||
if ($functions !== null) {
|
||||
@@ -178,46 +258,6 @@ class command_option {
|
||||
}
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the callback function to the array of existing callback functions
|
||||
* @param string|null $function When function param is set, the callback function will be appended to the list of functions. When called without a param, the array will be returned of current callbacks.
|
||||
* @return $this|array Returns the array of callbacks if no parameters passed or this object when appending a callback
|
||||
*/
|
||||
public function callback(?string $function = null) {
|
||||
if ($function !== null) {
|
||||
$this->functions += [$function];
|
||||
return $this;
|
||||
}
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the callback function to the array of existing callback functions
|
||||
* @param string|null $function
|
||||
* @return $this
|
||||
*/
|
||||
public function function_append(?string $function = null) {
|
||||
if ($function !== null) {
|
||||
$this->functions += [$function];
|
||||
return $this;
|
||||
}
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array structure required for service
|
||||
* @return array
|
||||
*/
|
||||
public function to_array(): array {
|
||||
$array['short_option'] = $this->short_option();
|
||||
$array['long_option'] = $this->long_option();
|
||||
$array['description'] = $this->description();
|
||||
$array['short_description'] = $this->short_description();
|
||||
$array['long_description'] = $this->long_description();
|
||||
$array['functions'] = $this->functions();
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
/* Examples
|
||||
|
||||
@@ -2,39 +2,48 @@
|
||||
|
||||
/**
|
||||
* config class loads configuration from the file system
|
||||
* @param string $db_type Type of database
|
||||
* @param string $db_driver Alias of type
|
||||
* @param string $db_host Host to connect to
|
||||
* @param string $db_path Path of the database if it is file system based
|
||||
* @param string $db_file File name of the database if it is file system based
|
||||
* @param string $db_port Port to connect to
|
||||
* @param string $db_name Name of the database
|
||||
* @param string $db_sslmode SSL Mode to use
|
||||
* @param string $db_cert_authority The certificate authority
|
||||
* @param string $db_secure If the database is using a secure connection
|
||||
* @param string $db_username Username credentials to connect with
|
||||
* @param string $db_password Password credentials to connect with
|
||||
* @param string $config_path Configuration path currently in use
|
||||
* @param string $config_file Configuration file currently in use
|
||||
*
|
||||
* @param string $db_type Type of database
|
||||
* @param string $db_driver Alias of type
|
||||
* @param string $db_host Host to connect to
|
||||
* @param string $db_path Path of the database if it is file system based
|
||||
* @param string $db_file File name of the database if it is file system based
|
||||
* @param string $db_port Port to connect to
|
||||
* @param string $db_name Name of the database
|
||||
* @param string $db_sslmode SSL Mode to use
|
||||
* @param string $db_cert_authority The certificate authority
|
||||
* @param string $db_secure If the database is using a secure connection
|
||||
* @param string $db_username Username credentials to connect with
|
||||
* @param string $db_password Password credentials to connect with
|
||||
* @param string $config_path Configuration path currently in use
|
||||
* @param string $config_file Configuration file currently in use
|
||||
* @param string $config_path_and_filename Full path and configuration file currently in use
|
||||
* @internal the @param statements are used because they match the magic __get function that allows those to be accessed publicly
|
||||
*
|
||||
* @internal the @param statements are used because they match the magic __get function that allows those to be
|
||||
* accessed publicly
|
||||
*/
|
||||
final class config {
|
||||
|
||||
// Full path and filename of config.conf
|
||||
private $file;
|
||||
|
||||
// The internal array that holds the configuration in the config.conf file
|
||||
private $configuration;
|
||||
|
||||
/**
|
||||
* Configuration object used to hold a single instance
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $config = null;
|
||||
|
||||
// The internal array that holds the configuration in the config.conf file
|
||||
private $file;
|
||||
private $configuration;
|
||||
|
||||
/**
|
||||
* Loads the framework configuration file
|
||||
* Initializes a new instance of the class with an optional configuration file.
|
||||
*
|
||||
* If no file is provided, it will attempt to locate one using the `find()` method.
|
||||
*
|
||||
* @param string $file The path to the configuration file (optional).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $file = '') {
|
||||
|
||||
@@ -60,78 +69,45 @@ final class config {
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to allow backward compatibility for variables such as db_type.
|
||||
* <p>This will allow using config object with the syntax of:<br>
|
||||
* $config = new config();<br>
|
||||
* $db_type = $config->db_type;<br></p>
|
||||
* <p>Note:<br>
|
||||
* The <i>InvalidArgumentException</i> is thrown if there is no such variable accessed such as:<br>
|
||||
* $config = new config();<br>
|
||||
* $db_function = $config->db_function();
|
||||
* </p>
|
||||
* <p>This is ensure that any invalid code is detected and fixed.</p>
|
||||
* @param string $name Name of the object property
|
||||
* @return string Returns the value as a string
|
||||
* Finds and returns the path of the configuration file.
|
||||
*
|
||||
* Find tries to look for the config.conf file in the following locations: /etc/fusionpbx, /usr/local/etc/fusionpbx.
|
||||
* When unsuccessful it will then search for the config.php file in the same locations. Last, find will search the
|
||||
* SystemDrive folder for Windows operating systems trying first for config.conf and then config.php.
|
||||
*
|
||||
* @return string path to the configuration file
|
||||
*/
|
||||
public function __get(string $name): string {
|
||||
switch($name) {
|
||||
case 'db_type':
|
||||
case 'db_driver':
|
||||
return $this->configuration['database.0.type'] ?? '';
|
||||
case 'db_path':
|
||||
case 'path':
|
||||
return $this->configuration['database.0.path'] ?? '';
|
||||
case 'db_host':
|
||||
return $this->configuration['database.0.host'] ?? '';
|
||||
case 'db_port':
|
||||
return $this->configuration['database.0.port'] ?? '';
|
||||
case 'db_name':
|
||||
return $this->configuration['database.0.name'] ?? '';
|
||||
case 'db_sslmode':
|
||||
return $this->configuration['database.0.sslmode'] ?? 'prefer';
|
||||
case 'db_cert_authority':
|
||||
return $this->configuration['database.0.cert_authority'] ?? '';
|
||||
case 'db_secure':
|
||||
return $this->configuration['database.0.secure'] ?? 'false';
|
||||
case 'db_username':
|
||||
case 'username':
|
||||
return $this->configuration['database.0.username'] ?? '';
|
||||
case 'db_password':
|
||||
case 'password':
|
||||
return $this->configuration['database.0.password'] ?? '';
|
||||
case 'db_file':
|
||||
return $this->configuration['database.0.file'] ?? '';
|
||||
case 'config_path':
|
||||
return $this->path();
|
||||
case 'config_filename':
|
||||
return $this->filename();
|
||||
case 'config_path_and_filename':
|
||||
case 'config_file':
|
||||
return $this->path_and_filename();
|
||||
default:
|
||||
if (property_exists($this, $name)) {
|
||||
return $this->{$name};
|
||||
}
|
||||
elseif (array_key_exists($name, $this->configuration)) {
|
||||
return $this->configuration[$name];
|
||||
}
|
||||
public static function find(): string {
|
||||
//define the file variable
|
||||
$file = "";
|
||||
|
||||
//find the file
|
||||
if (file_exists("/etc/fusionpbx/config.conf")) {
|
||||
$file = "/etc/fusionpbx/config.conf";
|
||||
} elseif (file_exists("/usr/local/etc/fusionpbx/config.conf")) {
|
||||
$file = "/usr/local/etc/fusionpbx/config.conf";
|
||||
} elseif (file_exists("/etc/fusionpbx/config.php")) {
|
||||
$file = "/etc/fusionpbx/config.php";
|
||||
} elseif (file_exists("/usr/local/etc/fusionpbx/config.php")) {
|
||||
$file = "/usr/local/etc/fusionpbx/config.php";
|
||||
} elseif (file_exists(getenv('SystemDrive') . DIRECTORY_SEPARATOR . 'ProgramData' . DIRECTORY_SEPARATOR . 'fusionpbx' . DIRECTORY_SEPARATOR . 'config.conf')) {
|
||||
$file = getenv('SystemDrive') . DIRECTORY_SEPARATOR . 'ProgramData' . DIRECTORY_SEPARATOR . 'fusionpbx' . DIRECTORY_SEPARATOR . 'config.conf';
|
||||
} elseif (file_exists(dirname(__DIR__, 2) . "/resources/config.php")) {
|
||||
//use the current web directory to find it as a last resort
|
||||
$file = "/var/www/fusionpbx/resources/config.php";
|
||||
}
|
||||
return "";
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of the configuration file
|
||||
* @return string configuration
|
||||
* Reads and parses the configuration file.
|
||||
*
|
||||
* If the file has a .php extension, it will be included as PHP code. Otherwise,
|
||||
* it will be parsed using the parse_ini_file function.
|
||||
* The old properties from config.php are converted to the new standard.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __toString(): string {
|
||||
$string_builder = "";
|
||||
foreach ($this->configuration as $key => $value) {
|
||||
$string_builder .= "$key = '$value'\n";
|
||||
}
|
||||
return $string_builder;
|
||||
}
|
||||
|
||||
// loads the config.conf file
|
||||
public function read() {
|
||||
|
||||
//check if include is needed
|
||||
@@ -183,27 +159,39 @@ final class config {
|
||||
|
||||
//remove from the global namespace
|
||||
unset($db_type, $db_host, $db_port, $db_name, $db_username, $db_password, $db_sslmode, $db_secure, $db_cert_authority);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//save the loaded and parsed conf file to the object
|
||||
$this->configuration = parse_ini_file($this->file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set project paths if not already defined
|
||||
// loads the config.conf file
|
||||
|
||||
/**
|
||||
* Defines project paths and sets internal server variables
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function define_project_paths() {
|
||||
// Load the document root
|
||||
$doc_root = $this->get('document.root', '/var/www/fusionpbx');
|
||||
$doc_path = $this->get('document.path', '');
|
||||
//set the server variables and define project path constant
|
||||
if (!empty($doc_path)) {
|
||||
if (!defined('PROJECT_PATH')) { define("PROJECT_PATH", $doc_path); }
|
||||
if (!defined('PROJECT_ROOT')) { define("PROJECT_ROOT", $doc_root.'/'.$doc_path); }
|
||||
}
|
||||
else {
|
||||
if (!defined('PROJECT_PATH')) { define("PROJECT_PATH", ''); }
|
||||
if (!defined('PROJECT_ROOT')) { define("PROJECT_ROOT", $doc_root); }
|
||||
if (!defined('PROJECT_PATH')) {
|
||||
define("PROJECT_PATH", $doc_path);
|
||||
}
|
||||
if (!defined('PROJECT_ROOT')) {
|
||||
define("PROJECT_ROOT", $doc_root . '/' . $doc_path);
|
||||
}
|
||||
} else {
|
||||
if (!defined('PROJECT_PATH')) {
|
||||
define("PROJECT_PATH", '');
|
||||
}
|
||||
if (!defined('PROJECT_ROOT')) {
|
||||
define("PROJECT_ROOT", $doc_root);
|
||||
}
|
||||
}
|
||||
|
||||
// internal definitions to the framework
|
||||
@@ -217,41 +205,15 @@ final class config {
|
||||
set_include_path(PROJECT_ROOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the path to the config.conf file
|
||||
* @var string $config_path - full path to the config.php file
|
||||
*/
|
||||
public static function find(): string {
|
||||
//define the file variable
|
||||
$file = "";
|
||||
|
||||
//find the file
|
||||
if (file_exists("/etc/fusionpbx/config.conf")) {
|
||||
$file = "/etc/fusionpbx/config.conf";
|
||||
}
|
||||
elseif (file_exists("/usr/local/etc/fusionpbx/config.conf")) {
|
||||
$file = "/usr/local/etc/fusionpbx/config.conf";
|
||||
}
|
||||
elseif (file_exists("/etc/fusionpbx/config.php")) {
|
||||
$file = "/etc/fusionpbx/config.php";
|
||||
}
|
||||
elseif (file_exists("/usr/local/etc/fusionpbx/config.php")) {
|
||||
$file = "/usr/local/etc/fusionpbx/config.php";
|
||||
}
|
||||
elseif (file_exists(getenv('SystemDrive') . DIRECTORY_SEPARATOR . 'ProgramData' . DIRECTORY_SEPARATOR . 'fusionpbx' . DIRECTORY_SEPARATOR . 'config.conf')) {
|
||||
$file = getenv('SystemDrive') . DIRECTORY_SEPARATOR . 'ProgramData' . DIRECTORY_SEPARATOR . 'fusionpbx' . DIRECTORY_SEPARATOR . 'config.conf';
|
||||
}
|
||||
elseif (file_exists(dirname(__DIR__, 2) . "/resources/config.php")) {
|
||||
//use the current web directory to find it as a last resort
|
||||
$file = "/var/www/fusionpbx/resources/config.php";
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
// set project paths if not already defined
|
||||
|
||||
/**
|
||||
* Get a configuration value using a key in the configuration file
|
||||
* @param string $key Match key on the left hand side of the '=' in the config file. If $key is null the default value is returned
|
||||
*
|
||||
* @param string $key Match key on the left hand side of the '=' in the config file. If $key is null
|
||||
* the default value is returned
|
||||
* @param string|null $default_value if no matching key is found, then this value will be returned
|
||||
*
|
||||
* @return string|null returns a value in the config.conf file or an empty string
|
||||
*/
|
||||
public function get(string $key, ?string $default_value = ''): ?string {
|
||||
@@ -262,48 +224,103 @@ final class config {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the config path or an empty string
|
||||
* @return string
|
||||
* Magic method to allow backward compatibility for variables such as db_type.
|
||||
* <p>This will allow using config object with the syntax of:<br>
|
||||
* $config = new config();<br>
|
||||
* $db_type = $config->db_type;<br></p>
|
||||
* <p>Note:<br>
|
||||
* The <i>InvalidArgumentException</i> is thrown if there is no such variable accessed such as:<br>
|
||||
* $config = new config();<br>
|
||||
* $db_function = $config->db_function();
|
||||
* </p>
|
||||
* <p>This is ensure that any invalid code is detected and fixed.</p>
|
||||
*
|
||||
* @param string $name Name of the object property
|
||||
*
|
||||
* @return string Returns the value as a string
|
||||
*/
|
||||
public function __get(string $name): string {
|
||||
switch ($name) {
|
||||
case 'db_type':
|
||||
case 'db_driver':
|
||||
return $this->configuration['database.0.type'] ?? '';
|
||||
case 'db_path':
|
||||
case 'path':
|
||||
return $this->configuration['database.0.path'] ?? '';
|
||||
case 'db_host':
|
||||
return $this->configuration['database.0.host'] ?? '';
|
||||
case 'db_port':
|
||||
return $this->configuration['database.0.port'] ?? '';
|
||||
case 'db_name':
|
||||
return $this->configuration['database.0.name'] ?? '';
|
||||
case 'db_sslmode':
|
||||
return $this->configuration['database.0.sslmode'] ?? 'prefer';
|
||||
case 'db_cert_authority':
|
||||
return $this->configuration['database.0.cert_authority'] ?? '';
|
||||
case 'db_secure':
|
||||
return $this->configuration['database.0.secure'] ?? 'false';
|
||||
case 'db_username':
|
||||
case 'username':
|
||||
return $this->configuration['database.0.username'] ?? '';
|
||||
case 'db_password':
|
||||
case 'password':
|
||||
return $this->configuration['database.0.password'] ?? '';
|
||||
case 'db_file':
|
||||
return $this->configuration['database.0.file'] ?? '';
|
||||
case 'config_path':
|
||||
return $this->path();
|
||||
case 'config_filename':
|
||||
return $this->filename();
|
||||
case 'config_path_and_filename':
|
||||
case 'config_file':
|
||||
return $this->path_and_filename();
|
||||
default:
|
||||
if (property_exists($this, $name)) {
|
||||
return $this->{$name};
|
||||
} elseif (array_key_exists($name, $this->configuration)) {
|
||||
return $this->configuration[$name];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory path of the configuration file.
|
||||
*
|
||||
* @return string the directory path of the configuration file
|
||||
*/
|
||||
public function path(): string {
|
||||
return dirname($this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name only of the configuration file
|
||||
* @return string
|
||||
* Returns the filename of the processed file.
|
||||
*
|
||||
* @return string filename
|
||||
*/
|
||||
public function filename(): string {
|
||||
return basename($this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path and the file name
|
||||
* @return string
|
||||
* Returns the file's path and filename.
|
||||
*
|
||||
* @return string path and filename of the file
|
||||
*/
|
||||
public function path_and_filename(): string {
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the config class has a loaded configuration or not
|
||||
* @return bool True if configuration has loaded and false if it is empty
|
||||
*/
|
||||
public function is_empty(): bool {
|
||||
return count($this->configuration) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of configuration settings
|
||||
* @return array
|
||||
*/
|
||||
public function configuration(): array {
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the configuration file is loaded only once
|
||||
* @return config
|
||||
* Returns a singleton instance of the configuration object
|
||||
*
|
||||
* If no file path is provided, loads the default configuration.
|
||||
* Otherwise, attempts to load the specified file and returns the result.
|
||||
*
|
||||
* @param string $file The optional file path to load (default: ''). Note: If the configuration file is already
|
||||
* loaded, the file provided will be ignored.
|
||||
*
|
||||
* @return config The loaded or default configuration object
|
||||
*/
|
||||
public static function load(string $file = ''): config {
|
||||
if (self::$config === null) {
|
||||
@@ -311,6 +328,37 @@ final class config {
|
||||
}
|
||||
return self::$config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of the configuration file
|
||||
*
|
||||
* @return string configuration
|
||||
*/
|
||||
public function __toString(): string {
|
||||
$string_builder = "";
|
||||
foreach ($this->configuration as $key => $value) {
|
||||
$string_builder .= "$key = '$value'\n";
|
||||
}
|
||||
return $string_builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the configuration is empty.
|
||||
*
|
||||
* @return bool true if the configuration is empty, false otherwise
|
||||
*/
|
||||
public function is_empty(): bool {
|
||||
return count($this->configuration) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current application configuration
|
||||
*
|
||||
* @return array configuration data
|
||||
*/
|
||||
public function configuration(): array {
|
||||
return $this->configuration;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ class buffer {
|
||||
return $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
//$b = new buffer;
|
||||
//$b->append("hello\nworld\n");
|
||||
//print($b->read_line());
|
||||
@@ -44,23 +45,24 @@ class buffer {
|
||||
|
||||
/**
|
||||
* Subscribes to the event socket of the FreeSWITCH (c) Event Socket Server
|
||||
*
|
||||
* @depends buffer::class
|
||||
*/
|
||||
class event_socket {
|
||||
private static $socket = null;
|
||||
public $fp;
|
||||
/**
|
||||
* Used as a flag to determine if the socket should be created automatically
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $auto_create;
|
||||
|
||||
private $buffer;
|
||||
public $fp;
|
||||
|
||||
private static $socket = null;
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Create a new connection to the socket
|
||||
*
|
||||
* @param resource|false $fp
|
||||
*/
|
||||
public function __construct($fp = false, ?config $config = null) {
|
||||
@@ -71,15 +73,59 @@ class event_socket {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a closed connection on destruction of object
|
||||
* Sends an API command on the socket
|
||||
*
|
||||
* @param string $api_cmd
|
||||
*
|
||||
* @return string|false Response from server or false if failed
|
||||
*/
|
||||
public function __destructor() {
|
||||
$this->close();
|
||||
public static function api(string $api_cmd) {
|
||||
return self::command('api ' . $api_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command on the socket blocking for a response
|
||||
*
|
||||
* @param string $cmd
|
||||
*
|
||||
* @return string|false Response from server or false if failed
|
||||
*/
|
||||
public static function command(string $cmd) {
|
||||
return self::create()->request($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command to the FreeSWITCH Event Socket Server
|
||||
* <p>Multi-line commands can be sent when separated by '\n'</p>
|
||||
*
|
||||
* @param string $cmd Command to send through the socket
|
||||
*
|
||||
* @return mixed Returns the response from FreeSWITCH or false if not connected
|
||||
* @depends read_event()
|
||||
*/
|
||||
public function request($cmd) {
|
||||
if (!$this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cmd_array = explode("\n", $cmd);
|
||||
foreach ($cmd_array as $value) {
|
||||
fputs($this->fp, $value . "\n");
|
||||
}
|
||||
fputs($this->fp, "\n"); //second line feed to end the headers
|
||||
|
||||
$event = $this->read_event();
|
||||
|
||||
if (array_key_exists('$', $event)) {
|
||||
return $event['$'];
|
||||
}
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the event body from the socket
|
||||
* @return string|false Content body or false if not connected or empty message
|
||||
*
|
||||
* @return mixed Content body or false if not connected or empty message
|
||||
* @depends buffer::class
|
||||
*/
|
||||
public function read_event() {
|
||||
@@ -88,7 +134,7 @@ class event_socket {
|
||||
}
|
||||
|
||||
$b = $this->buffer;
|
||||
$content = array();
|
||||
$content = [];
|
||||
|
||||
while (true) {
|
||||
$line = $b->read_line();
|
||||
@@ -96,7 +142,7 @@ class event_socket {
|
||||
if ($line === '') {
|
||||
break;
|
||||
}
|
||||
list($key, $value) = explode(':', $line, 2);
|
||||
[$key, $value] = explode(':', $line, 2);
|
||||
$content[trim($key)] = trim($value);
|
||||
}
|
||||
|
||||
@@ -132,14 +178,41 @@ class event_socket {
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create uses a singleton design to return a connected socket to the FreeSWITCH Event Socket Layer
|
||||
*
|
||||
* @param string $host Host or IP address of FreeSWITCH event socket server. Defaults to 127.0.0.1
|
||||
* @param string $port Port number of FreeSWITCH event socket server. Defaults to 8021
|
||||
* @param string $password Password of FreeSWITCH event socket server. Defaults to ClueCon
|
||||
* @param int $timeout_microseconds Number of microseconds before timeout is triggered on socket
|
||||
*
|
||||
* @return self
|
||||
* @global array $conf Global configuration used in config.conf
|
||||
*/
|
||||
public static function create($host = null, $port = null, $password = null, $timeout_microseconds = 30000): self {
|
||||
//create the event socket object
|
||||
if (self::$socket === null) {
|
||||
self::$socket = new event_socket();
|
||||
}
|
||||
//attempt to connect it
|
||||
if (!self::$socket->connected()) {
|
||||
self::$socket->connect($host, $port, $password, $timeout_microseconds);
|
||||
}
|
||||
return self::$socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the FreeSWITCH (c) event socket server
|
||||
* <p>If the configuration is not loaded then the defaults of
|
||||
* host 127.0.0.1, port of 8021, and default password of ClueCon will be used</p>
|
||||
* @param null|string $host Host or IP address of FreeSWITCH event socket server. Defaults to 127.0.0.1
|
||||
* @param null|string|int $port Port number of FreeSWITCH event socket server. Defaults to 8021
|
||||
* @param null|string $password Password of FreeSWITCH event socket server. Defaults to ClueCon
|
||||
* @param int $timeout_microseconds Number of microseconds before timeout is triggered on socket. Defaults to 30,000
|
||||
*
|
||||
* @param null|string $host Host or IP address of FreeSWITCH event socket server. Defaults to
|
||||
* 127.0.0.1
|
||||
* @param null|string|int $port Port number of FreeSWITCH event socket server. Defaults to 8021
|
||||
* @param null|string $password Password of FreeSWITCH event socket server. Defaults to ClueCon
|
||||
* @param int $timeout_microseconds Number of microseconds before timeout is triggered on socket.
|
||||
* Defaults to 30,000
|
||||
*
|
||||
* @return bool Returns true on success or false if not connected
|
||||
*/
|
||||
public function connect($host = null, $port = null, $password = null, $timeout_microseconds = 30000) {
|
||||
@@ -165,7 +238,7 @@ class event_socket {
|
||||
//wait auth request and send a response
|
||||
while ($this->connected()) {
|
||||
$event = $this->read_event();
|
||||
if(($event['Content-Type'] ?? '') === 'auth/request'){
|
||||
if (($event['Content-Type'] ?? '') === 'auth/request') {
|
||||
fputs($this->fp, "auth $password\n\n");
|
||||
break;
|
||||
}
|
||||
@@ -186,8 +259,60 @@ class event_socket {
|
||||
return $this->connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an API command to FreeSWITCH using asynchronous (non-blocking) mode
|
||||
*
|
||||
* @param string $cmd API command to send
|
||||
*
|
||||
* @returns string $job_id the Job ID for tracking completion status
|
||||
*/
|
||||
public static function async(string $cmd) {
|
||||
return self::command('bgapi ' . $cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a closed connection on destruction of object
|
||||
*/
|
||||
public function __destructor() {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the socket connection with the FreeSWITCH Event Socket Server.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close() {
|
||||
//fp is public access so ensure it is a resource before closing it
|
||||
if (is_resource($this->fp)) {
|
||||
try {
|
||||
fclose($this->fp);
|
||||
} catch (Exception $t) {
|
||||
//report it
|
||||
trigger_error("event_socket failed to close socket", E_USER_WARNING);
|
||||
}
|
||||
} else {
|
||||
//log an error if fp was set to something other than a resource
|
||||
if ($this->fp !== false) {
|
||||
trigger_error("event_socket not a resource", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
//force fp to be false
|
||||
$this->fp = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* alias of connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_connected(): bool {
|
||||
return $this->connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if connected to the FreeSWITCH Event Socket Server
|
||||
*
|
||||
* @return bool Returns true when connected or false when not connected
|
||||
*/
|
||||
public function connected(): bool {
|
||||
@@ -203,124 +328,20 @@ class event_socket {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* alias of connected
|
||||
* @return bool
|
||||
*/
|
||||
public function is_connected(): bool {
|
||||
return $this->connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command to the FreeSWITCH Event Socket Server
|
||||
* <p>Multi-line commands can be sent when separated by '\n'</p>
|
||||
* @param string $cmd Command to send through the socket
|
||||
* @return mixed Returns the response from FreeSWITCH or false if not connected
|
||||
* @depends read_event()
|
||||
*/
|
||||
public function request($cmd) {
|
||||
if (!$this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cmd_array = explode("\n", $cmd);
|
||||
foreach ($cmd_array as $value) {
|
||||
fputs($this->fp, $value."\n");
|
||||
}
|
||||
fputs($this->fp, "\n"); //second line feed to end the headers
|
||||
|
||||
$event = $this->read_event();
|
||||
|
||||
if (array_key_exists('$', $event)) {
|
||||
return $event['$'];
|
||||
}
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current socket resource returning the old
|
||||
*
|
||||
* @param resource|bool $fp Sets the current FreeSWITCH resource
|
||||
*
|
||||
* @return mixed Returns the original resource
|
||||
* @deprecated since version 5.1
|
||||
*/
|
||||
public function reset_fp($fp = false){
|
||||
public function reset_fp($fp = false) {
|
||||
$tmp = $this->fp;
|
||||
$this->fp = $fp;
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket
|
||||
*/
|
||||
public function close() {
|
||||
//fp is public access so ensure it is a resource before closing it
|
||||
if (is_resource($this->fp)) {
|
||||
try {
|
||||
fclose($this->fp);
|
||||
} catch (\Exception $t) {
|
||||
//report it
|
||||
trigger_error("event_socket failed to close socket", E_USER_WARNING);
|
||||
}
|
||||
} else {
|
||||
//log an error if fp was set to something other than a resource
|
||||
if ($this->fp !== false) {
|
||||
trigger_error("event_socket not a resource", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
//force fp to be false
|
||||
$this->fp = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create uses a singleton design to return a connected socket to the FreeSWITCH Event Socket Layer
|
||||
* @global array $conf Global configuration used in config.conf
|
||||
* @param string $host Host or IP address of FreeSWITCH event socket server. Defaults to 127.0.0.1
|
||||
* @param string $port Port number of FreeSWITCH event socket server. Defaults to 8021
|
||||
* @param string $password Password of FreeSWITCH event socket server. Defaults to ClueCon
|
||||
* @param int $timeout_microseconds Number of microseconds before timeout is triggered on socket
|
||||
* @return self
|
||||
*/
|
||||
public static function create($host = null, $port = null, $password = null, $timeout_microseconds = 30000): self {
|
||||
//create the event socket object
|
||||
if (self::$socket === null) {
|
||||
self::$socket = new event_socket();
|
||||
}
|
||||
//attempt to connect it
|
||||
if(!self::$socket->connected()) {
|
||||
self::$socket->connect($host, $port, $password, $timeout_microseconds);
|
||||
}
|
||||
return self::$socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command on the socket blocking for a response
|
||||
* @param string $cmd
|
||||
* @return string|false Response from server or false if failed
|
||||
*/
|
||||
public static function command(string $cmd) {
|
||||
return self::create()->request($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an API command on the socket
|
||||
* @param string $api_cmd
|
||||
* @return string|false Response from server or false if failed
|
||||
*/
|
||||
public static function api(string $api_cmd) {
|
||||
return self::command('api '.$api_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an API command to FreeSWITCH using asynchronous (non-blocking) mode
|
||||
* @param string $cmd API command to send
|
||||
* @returns string $job_id the Job ID for tracking completion status
|
||||
*/
|
||||
public static function async(string $cmd) {
|
||||
return self::command('bgapi '.$cmd);
|
||||
}
|
||||
}
|
||||
|
||||
// $esl = event_socket::create('127.0.0.1', 8021, 'ClueCon');
|
||||
// print($esl->request('api sofia status'));
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,58 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* cache class provides an abstracted cache
|
||||
* file class provides an abstracted cache
|
||||
*/
|
||||
class file {
|
||||
|
||||
/**
|
||||
* variables
|
||||
*/
|
||||
*/
|
||||
public $recursive;
|
||||
public $files;
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the session global array
|
||||
*
|
||||
* @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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
* Constructor for the class.
|
||||
*
|
||||
* This method initializes the object with setting_array and session data.
|
||||
*
|
||||
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||
*/
|
||||
public function __construct(array $setting_array = []) {
|
||||
//set domain and user UUIDs
|
||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||
$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
|
||||
$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]);
|
||||
//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]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Glob search for a list of files
|
||||
* @var string $dir this is the directory to scan
|
||||
* @var boolean $recursive get the sub directories
|
||||
* @return array list of files or an empty array if not found
|
||||
* Returns an array of sound files.
|
||||
*
|
||||
* This method retrieves a list of sound files based on the provided language,
|
||||
* dialect, and voice settings. If no specific values are provided, default values
|
||||
* will be used.
|
||||
*
|
||||
* @param string $language The desired language (default: 'en').
|
||||
* @param string $dialect The desired dialect (default: 'us').
|
||||
* @param string $voice The desired voice (default: 'callie').
|
||||
*
|
||||
* @return array An array of sound files.
|
||||
*/
|
||||
public function sounds($language = 'en', $dialect = 'us', $voice = 'callie') {
|
||||
//define an empty array
|
||||
$array = [];
|
||||
|
||||
//set default values
|
||||
if (!isset($language)) {
|
||||
$language = 'en';
|
||||
}
|
||||
if (!isset($dialect)) {
|
||||
$dialect = 'us';
|
||||
}
|
||||
if (!isset($voice)) {
|
||||
$voice = 'callie';
|
||||
}
|
||||
|
||||
//set the variables
|
||||
if (!empty($this->settings->get('switch', 'sounds')) && file_exists($this->settings->get('switch', 'sounds'))) {
|
||||
$dir = $this->settings->get('switch', 'sounds') . '/' . $language . '/' . $dialect . '/' . $voice;
|
||||
$rate = '8000';
|
||||
$files = $this->glob($dir . '/*/' . $rate, true);
|
||||
}
|
||||
|
||||
//loop through the languages
|
||||
if (!empty($files)) {
|
||||
foreach ($files as $file) {
|
||||
$file = substr($file, strlen($dir) + 1);
|
||||
$file = str_replace("/" . $rate, "", $file);
|
||||
$array[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
//return the list of sounds
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds files in the specified directory.
|
||||
*
|
||||
* This method recursively searches for files and directories within the given
|
||||
* directory, returning an array of paths if found. If no recursion is performed,
|
||||
* only the files directly within the directory are returned.
|
||||
*
|
||||
* @param string $dir The directory path to search.
|
||||
* @param bool $recursive Whether to recursively traverse subdirectories.
|
||||
*
|
||||
* @return array An array of file paths found in the specified directory.
|
||||
*/
|
||||
public function glob($dir, $recursive): array {
|
||||
$files = [];
|
||||
@@ -60,7 +124,7 @@ class file {
|
||||
$tree = glob(rtrim($dir, '/') . '/*');
|
||||
if ($recursive) {
|
||||
if (is_array($tree)) {
|
||||
foreach($tree as $file) {
|
||||
foreach ($tree as $file) {
|
||||
if (is_dir($file)) {
|
||||
if ($recursive == true) {
|
||||
$files[] = $this->glob($file, $recursive);
|
||||
@@ -71,41 +135,8 @@ class file {
|
||||
}
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the sounds list of search as a relative path without the rate
|
||||
*/
|
||||
public function sounds($language = 'en', $dialect = 'us', $voice = 'callie') {
|
||||
//define an empty array
|
||||
$array = [];
|
||||
|
||||
//set default values
|
||||
if (!isset($language)) { $language = 'en'; }
|
||||
if (!isset($dialect)) { $dialect = 'us'; }
|
||||
if (!isset($voice)) { $voice = 'callie'; }
|
||||
|
||||
//set the variables
|
||||
if (!empty($this->settings->get('switch', 'sounds')) && file_exists($this->settings->get('switch', 'sounds'))) {
|
||||
$dir = $this->settings->get('switch', 'sounds').'/'.$language.'/'.$dialect.'/'.$voice;
|
||||
$rate = '8000';
|
||||
$files = $this->glob($dir.'/*/'.$rate, true);
|
||||
}
|
||||
|
||||
//loop through the languages
|
||||
if (!empty($files)) {
|
||||
foreach($files as $file) {
|
||||
$file = substr($file, strlen($dir)+1);
|
||||
$file = str_replace("/".$rate, "", $file);
|
||||
$array[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
//return the list of sounds
|
||||
return $array;
|
||||
return $files;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -116,5 +147,3 @@ class file {
|
||||
$files = $file->sounds();
|
||||
print_r($files);
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
@@ -35,7 +35,9 @@ final class filter_chain {
|
||||
|
||||
/**
|
||||
* Builds a filter chain link for filter objects
|
||||
*
|
||||
* @param array $filters Array of filter objects
|
||||
*
|
||||
* @return filter
|
||||
*/
|
||||
public static function or_link(array $filters): filter {
|
||||
@@ -84,6 +86,13 @@ final class filter_chain {
|
||||
return $chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a filter chain link for filter objects
|
||||
*
|
||||
* @param array $filters Array of filter objects
|
||||
*
|
||||
* @return filter
|
||||
*/
|
||||
public static function and_link(array $filters): filter {
|
||||
return new class($filters) implements filter {
|
||||
private $filters;
|
||||
@@ -98,7 +107,7 @@ final class filter_chain {
|
||||
// Check if a filter requires a null to be returned
|
||||
if ($result === null) {
|
||||
return null;
|
||||
} elseif(!$result) {
|
||||
} elseif (!$result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,61 +25,98 @@ class google_authenticator {
|
||||
self::$PIN_MODULO = pow(10, self::$PASS_CODE_LENGTH);
|
||||
}
|
||||
|
||||
public function checkCode($secret,$code) {
|
||||
/**
|
||||
* Checks if the provided code is valid based on the secret and time.
|
||||
*
|
||||
* @param string $secret The secret to verify against.
|
||||
* @param string $code The code to check for validity.
|
||||
*
|
||||
* @return bool True if the code is valid, false otherwise.
|
||||
*/
|
||||
public function checkCode($secret, $code) {
|
||||
$time = floor(time() / 30);
|
||||
for ( $i = -1; $i <= 1; $i++) {
|
||||
if ($this->getCode($secret,$time + $i) == $code) {
|
||||
for ($i = -1; $i <= 1; $i++) {
|
||||
if ($this->getCode($secret, $time + $i) == $code) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getCode($secret,$time = null) {
|
||||
/**
|
||||
* Generates a PIN code based on the provided secret and time.
|
||||
*
|
||||
* @param string $secret The secret to use for generating the code.
|
||||
* @param int|null $time The current time in seconds since the Unix epoch. Defaults to the current time divided
|
||||
* by 30.
|
||||
*
|
||||
* @return string A six-digit PIN code.
|
||||
*/
|
||||
public function getCode($secret, $time = null) {
|
||||
|
||||
if (!$time) {
|
||||
$time = floor(time() / 30);
|
||||
}
|
||||
|
||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', TRUE, TRUE);
|
||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', true, true);
|
||||
$secret = $base32->decode($secret);
|
||||
|
||||
$time = pack("N", $time);
|
||||
$time = str_pad($time,8, chr(0), STR_PAD_LEFT);
|
||||
$time = str_pad($time, 8, chr(0), STR_PAD_LEFT);
|
||||
|
||||
$hash = hash_hmac('sha1',$time,$secret,true);
|
||||
$offset = ord(substr($hash,-1));
|
||||
$hash = hash_hmac('sha1', $time, $secret, true);
|
||||
$offset = ord(substr($hash, -1));
|
||||
$offset = $offset & 0xF;
|
||||
|
||||
$truncatedHash = self::hashToInt($hash, $offset) & 0x7FFFFFFF;
|
||||
$pinValue = str_pad($truncatedHash % self::$PIN_MODULO,6,"0",STR_PAD_LEFT);;
|
||||
$pinValue = str_pad($truncatedHash % self::$PIN_MODULO, 6, "0", STR_PAD_LEFT);
|
||||
return $pinValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to an integer value.
|
||||
*
|
||||
* @param string $bytes The byte array to convert.
|
||||
* @param int $start The starting position in the byte array.
|
||||
*
|
||||
* @return int The converted integer value.
|
||||
*/
|
||||
protected function hashToInt($bytes, $start) {
|
||||
$input = substr($bytes, $start, strlen($bytes) - $start);
|
||||
$val2 = unpack("N",substr($input,0,4));
|
||||
$val2 = unpack("N", substr($input, 0, 4));
|
||||
return $val2[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL for the Google QR code.
|
||||
*
|
||||
* @param string $user The user's username.
|
||||
* @param string $hostname The hostname of the service.
|
||||
* @param string $secret The secret to encode in the QR code.
|
||||
*
|
||||
* @return string A URL that can be used to generate a QR code with the provided secret.
|
||||
*/
|
||||
public function getUrl($user, $hostname, $secret) {
|
||||
$url = sprintf("otpauth://totp/%s@%s?secret=%s", $user, $hostname, $secret);
|
||||
$encoder = "https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=";
|
||||
$encoderURL = sprintf( "%sotpauth://totp/%s@%s&secret=%s",$encoder, $user, $hostname, $secret);
|
||||
$encoderURL = sprintf("%sotpauth://totp/%s@%s&secret=%s", $encoder, $user, $hostname, $secret);
|
||||
return $encoderURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a secret based on random characters and converts it to Base32.
|
||||
*
|
||||
* @return string The generated secret in Base32 format.
|
||||
*/
|
||||
public function generateSecret() {
|
||||
$secret = "";
|
||||
for($i = 1; $i<= self::$SECRET_LENGTH;$i++) {
|
||||
$c = rand(0,255);
|
||||
$secret .= pack("c",$c);
|
||||
for ($i = 1; $i <= self::$SECRET_LENGTH; $i++) {
|
||||
$c = rand(0, 255);
|
||||
$secret .= pack("c", $c);
|
||||
}
|
||||
|
||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', TRUE, TRUE);
|
||||
return $base32->encode($secret);
|
||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', true, true);
|
||||
return $base32->encode($secret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,16 @@
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
class invalid_uuid_exception extends Exception {
|
||||
public function __construct(string $message = "UUID is not valid", int $code = 0, ?\Throwable $previous = null) {
|
||||
return parent::__construct($message, $code, $previous);
|
||||
/**
|
||||
* Constructs a new instance of the class.
|
||||
*
|
||||
* @param string $message The error message. Defaults to "UUID is not valid".
|
||||
* @param int $code The HTTP status code. Defaults to 0.
|
||||
* @param \Throwable|null $previous The previous exception, if any.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $message = "UUID is not valid", int $code = 0, ?Throwable $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,165 +1,269 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Logging class:
|
||||
* - constructor requires the full file name and path for the log file. if it
|
||||
* does not exist php will automatically try and create it. The log file will
|
||||
* remain open for the life cycle of the object to improve performance.
|
||||
* - message is written with the following format: [d/M/Y:H:i:s] (script name) message.
|
||||
* - log file is closed when the object is destroyed.
|
||||
*/
|
||||
class logging {
|
||||
|
||||
// declare log file and file pointer as private properties
|
||||
private $fp;
|
||||
private $debug_func;
|
||||
private $debug_line;
|
||||
private $debug_file;
|
||||
private $debug_class;
|
||||
|
||||
/**
|
||||
* Logging class:
|
||||
* - constructor requires the full file name and path for the log file. if it
|
||||
* does not exist php will automatically try and create it. The log file will
|
||||
* remain open for the life cycle of the object to improve performance.
|
||||
* - message is written with the following format: [d/M/Y:H:i:s] (script name) message.
|
||||
* - log file is closed when the object is destroyed.
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
* Opens a file in append mode and sets it as the output stream for subsequent operations.
|
||||
*
|
||||
* @param string $filename_and_path The path to the file to be opened.
|
||||
*
|
||||
* @throws Exception If there is an error opening the file.
|
||||
*/
|
||||
class logging {
|
||||
public function __construct(string $filename_and_path) {
|
||||
//init values
|
||||
$this->clear_debug();
|
||||
|
||||
// declare log file and file pointer as private properties
|
||||
private $fp;
|
||||
private $debug_func;
|
||||
private $debug_line;
|
||||
private $debug_file;
|
||||
private $debug_class;
|
||||
|
||||
public function __construct(string $filename_and_path) {
|
||||
//init values
|
||||
$this->clear_debug();
|
||||
|
||||
try {
|
||||
//open file in append mode
|
||||
$this->fp = fopen($filename_and_path, 'a');
|
||||
} catch (Exception $ex) {
|
||||
//send the error to the caller
|
||||
throw $ex;
|
||||
}
|
||||
try {
|
||||
//open file in append mode
|
||||
$this->fp = fopen($filename_and_path, 'a');
|
||||
} catch (Exception $ex) {
|
||||
//send the error to the caller
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
try {
|
||||
$this->flush();
|
||||
} catch (Exception $ex) {
|
||||
//do nothing
|
||||
} finally {
|
||||
//close the file
|
||||
if (is_resource($this->fp)) {
|
||||
fclose($this->fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Clear debug settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function clear_debug() {
|
||||
$this->debug_line = null;
|
||||
$this->debug_file = null;
|
||||
$this->debug_func = null;
|
||||
$this->debug_class = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure all data arrives on disk
|
||||
* @throws Exception
|
||||
*/
|
||||
public function flush() {
|
||||
try {
|
||||
//ensure everything arrives on disk
|
||||
if (is_resource($this->fp)) {
|
||||
fflush($this->fp);
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
// write message to the log file
|
||||
private function _write($msg) {
|
||||
// define current time and suppress E_WARNING if using the system TZ settings
|
||||
}
|
||||
|
||||
private function clear_debug() {
|
||||
$this->debug_line = null;
|
||||
$this->debug_file = null;
|
||||
$this->debug_func = null;
|
||||
$this->debug_class = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write raw data to the
|
||||
* @param string $level
|
||||
* @param string $message
|
||||
*/
|
||||
public function write(string $level, string $message) {
|
||||
$this->get_backtrace_details();
|
||||
// write current time, script name and message to the log file
|
||||
// (don't forget to set the INI setting date.timezone)
|
||||
$time = @date('Y-m-d H:i:s');
|
||||
$file = $this->debug_file ?? 'file not set';
|
||||
$line = $this->debug_line ?? '0000';
|
||||
fwrite($this->fp, "[$time] [$level] [{$file}:{$line}] $message");
|
||||
$this->clear_debug();
|
||||
}
|
||||
|
||||
public function debug_class(?string $debug_class = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_class = $debug_class;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_class;
|
||||
}
|
||||
|
||||
public function debug_line(?string $debug_line = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_line = $debug_line;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_line;
|
||||
}
|
||||
|
||||
public function debug_func(?string $debug_func = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_func = $debug_func;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_func;
|
||||
}
|
||||
|
||||
public function debug_file(?string $debug_file = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_file = $debug_file;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_file;
|
||||
}
|
||||
|
||||
public function writeln($level, $message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->write($level, $message . "\n");
|
||||
}
|
||||
|
||||
public function debug($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("DEBUG", $message);
|
||||
}
|
||||
|
||||
public function info($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("INFO", $message);
|
||||
}
|
||||
|
||||
public function warning($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("WARNING", $message);
|
||||
}
|
||||
|
||||
public function error($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("ERROR", $message);
|
||||
}
|
||||
|
||||
private function get_backtrace_details() {
|
||||
if ($this->debug_file === null) {
|
||||
$debug = debug_backtrace();
|
||||
$ndx = count($debug) - 1;
|
||||
$this->debug_file = $debug[$ndx]['file'];
|
||||
$this->debug_line = $debug[$ndx]['line'];
|
||||
$this->debug_func = $debug[$ndx]['function'];
|
||||
$this->debug_class = $debug[$ndx]['class'] ?? '';
|
||||
/**
|
||||
* Clean up any resources held by this object on destruction.
|
||||
*
|
||||
* @throws Exception if an error occurs during flushing or closing of the file pointer.
|
||||
*/
|
||||
public function __destruct() {
|
||||
try {
|
||||
$this->flush();
|
||||
} catch (Exception $ex) {
|
||||
//do nothing
|
||||
} finally {
|
||||
//close the file
|
||||
if (is_resource($this->fp)) {
|
||||
fclose($this->fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Example:
|
||||
$log = new logging(sys_get_temp_dir() . '/logging.log');
|
||||
$log->writeln("debug", "passed validation");
|
||||
$log->debug("pass");
|
||||
$log->warning("variable should not used");
|
||||
$log->debug_file(__FILE__)->debug_line(__LINE__)->write("DEBUG", "Raw message\n");
|
||||
*/
|
||||
// write message to the log file
|
||||
|
||||
/**
|
||||
* Ensure all data arrives on disk
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function flush() {
|
||||
try {
|
||||
//ensure everything arrives on disk
|
||||
if (is_resource($this->fp)) {
|
||||
fflush($this->fp);
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or retrieve the class name for debugging purposes.
|
||||
*
|
||||
* @param string|null $debug_class The class name to set for debugging. If null, returns the current debug class.
|
||||
*
|
||||
* @return object This object instance for chaining.
|
||||
*/
|
||||
public function debug_class(?string $debug_class = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_class = $debug_class;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or retrieve the current debug line
|
||||
*
|
||||
* @param string|null $debug_line The new debug line to set, or null to clear it
|
||||
*
|
||||
* @return object|string The instance itself if a new value was provided, otherwise the current debug line as a
|
||||
* string
|
||||
*/
|
||||
public function debug_line(?string $debug_line = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_line = $debug_line;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or retrieves the current debug function.
|
||||
*
|
||||
* If a string argument is provided, it sets the current debug function. If no argument is provided,
|
||||
* it returns the current debug function.
|
||||
*
|
||||
* @param string|null $debug_func The debug function to set (optional)
|
||||
*
|
||||
* @return $this Self-reference for chaining
|
||||
*/
|
||||
public function debug_func(?string $debug_func = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_func = $debug_func;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or retrieve the path to a debug file.
|
||||
*
|
||||
* @param string|null $debug_file Path to the debug file (optional)
|
||||
*
|
||||
* @return object|string The current object if setting the debug file, otherwise the current debug file path
|
||||
*/
|
||||
public function debug_file(?string $debug_file = null) {
|
||||
if (func_num_args() > 0) {
|
||||
$this->debug_file = $debug_file;
|
||||
return $this;
|
||||
}
|
||||
return $this->debug_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a debug message to the log along with its backtrace details
|
||||
*
|
||||
* @param string $message The debug message to be written
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function debug($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("DEBUG", $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get detailed backtrace information for the current call stack.
|
||||
*
|
||||
* If the debug file, line and function have not been cached, this method will
|
||||
* cache them in object properties to prevent repeated calls to debug_backtrace().
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function get_backtrace_details() {
|
||||
if ($this->debug_file === null) {
|
||||
$debug = debug_backtrace();
|
||||
$ndx = count($debug) - 1;
|
||||
$this->debug_file = $debug[$ndx]['file'];
|
||||
$this->debug_line = $debug[$ndx]['line'];
|
||||
$this->debug_func = $debug[$ndx]['function'];
|
||||
$this->debug_class = $debug[$ndx]['class'] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a message to the output with an optional level and trailing newline character.
|
||||
*
|
||||
* @param string $level The logging level (optional).
|
||||
* @param string $message The message to be written.
|
||||
*/
|
||||
public function writeln($level, $message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->write($level, $message . "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a log message to the file
|
||||
*
|
||||
* @param string $level The level of the log message (e.g. 'error', 'warning', etc.)
|
||||
* @param string $message The actual log message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function write(string $level, string $message) {
|
||||
$this->get_backtrace_details();
|
||||
// write current time, script name and message to the log file
|
||||
// (don't forget to set the INI setting date.timezone)
|
||||
$time = @date('Y-m-d H:i:s');
|
||||
$file = $this->debug_file ?? 'file not set';
|
||||
$line = $this->debug_line ?? '0000';
|
||||
fwrite($this->fp, "[$time] [$level] [{$file}:{$line}] $message");
|
||||
$this->clear_debug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an informational message.
|
||||
*
|
||||
* This method logs a message with level "INFO" and stores backtrace details for debugging purposes.
|
||||
*
|
||||
* @param string $message The message to be logged
|
||||
*/
|
||||
public function info($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("INFO", $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning message to the user
|
||||
*
|
||||
* @param string $message The warning message to display
|
||||
*
|
||||
* @throws Exception If an error occurs while displaying the message
|
||||
*/
|
||||
public function warning($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("WARNING", $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error message with a backtrace.
|
||||
*
|
||||
* @param string $message The error message to log
|
||||
*/
|
||||
public function error($message) {
|
||||
$this->get_backtrace_details();
|
||||
$this->writeln("ERROR", $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a message to the underlying output stream.
|
||||
*
|
||||
* @param string $msg The message to be written
|
||||
*
|
||||
* @throws Exception If an error occurs while writing to the stream
|
||||
*/
|
||||
private function _write($msg) {
|
||||
// define current time and suppress E_WARNING if using the system TZ settings
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Example:
|
||||
$log = new logging(sys_get_temp_dir() . '/logging.log');
|
||||
$log->writeln("debug", "passed validation");
|
||||
$log->debug("pass");
|
||||
$log->warning("variable should not used");
|
||||
$log->debug_file(__FILE__)->debug_line(__LINE__)->write("DEBUG", "Raw message\n");
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,48 +25,70 @@
|
||||
Matthew Vale <github@mafoo.org>
|
||||
*/
|
||||
|
||||
class message {
|
||||
class message {
|
||||
|
||||
static function add($message, $mood = null, $delay = null) {
|
||||
//set mood and delay
|
||||
$mood = $mood ?: 'positive';
|
||||
$delay = $delay ?: (1000 * (float) $_SESSION['theme']['message_delay']['text']);
|
||||
//ignore duplicate messages
|
||||
if (isset($_SESSION["messages"]) && !empty($_SESSION["messages"][$mood]['message'])) {
|
||||
if (!in_array($message, $_SESSION["messages"][$mood]['message'])) {
|
||||
$_SESSION["messages"][$mood]['message'][] = $message;
|
||||
$_SESSION["messages"][$mood]['delay'][] = $delay;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_SESSION["messages"][$mood]['message'][] = $message;
|
||||
$_SESSION["messages"][$mood]['delay'][] = $delay;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the total number of messages in the session.
|
||||
*
|
||||
* @return int The number of messages, or 0 if no messages are present in the session.
|
||||
*/
|
||||
static function count() {
|
||||
return isset($_SESSION["messages"]) && is_array($_SESSION["messages"]) ? sizeof($_SESSION["messages"]) : 0;
|
||||
}
|
||||
|
||||
static function count() {
|
||||
return isset($_SESSION["messages"]) && is_array($_SESSION["messages"]) ? sizeof($_SESSION["messages"]) : 0;
|
||||
}
|
||||
|
||||
static function html($clear_messages = true, $spacer = "") {
|
||||
$html = "{$spacer}//render the messages\n";
|
||||
$spacer .="\t";
|
||||
if (isset($_SESSION['message']) || isset($_SESSION['messages'])) {
|
||||
if (!empty($_SESSION['message']) && !is_array($_SESSION['message'])) {
|
||||
self::add($_SESSION['message'], $_SESSION['message_mood'] ?? null, $_SESSION['message_delay'] ?? null);
|
||||
unset($_SESSION['message'], $_SESSION['message_mood'], $_SESSION['message_delay']);
|
||||
}
|
||||
if (!empty($_SESSION['messages']) && is_array($_SESSION['messages']) && @sizeof($_SESSION['messages']) != 0) {
|
||||
foreach ($_SESSION['messages'] as $message_mood => $message) {
|
||||
$message_text = str_replace(array("\r\n", "\n", "\r"),'\\n',addslashes(join('<br/>', $message['message'])));
|
||||
$message_delay = array_sum($message['delay'])/count($message['delay']);
|
||||
$html .= "{$spacer}display_message('$message_text', '$message_mood', '$message_delay');\n";
|
||||
}
|
||||
/**
|
||||
* Renders session messages into HTML.
|
||||
*
|
||||
* @param bool $clear_messages Whether to clear the session 'messages' array after rendering. Defaults to true.
|
||||
* @param string $spacer The indentation spacer for the generated HTML code.
|
||||
*
|
||||
* @return string The rendered HTML message display code.
|
||||
*/
|
||||
static function html($clear_messages = true, $spacer = "") {
|
||||
$html = "{$spacer}//render the messages\n";
|
||||
$spacer .= "\t";
|
||||
if (isset($_SESSION['message']) || isset($_SESSION['messages'])) {
|
||||
if (!empty($_SESSION['message']) && !is_array($_SESSION['message'])) {
|
||||
self::add($_SESSION['message'], $_SESSION['message_mood'] ?? null, $_SESSION['message_delay'] ?? null);
|
||||
unset($_SESSION['message'], $_SESSION['message_mood'], $_SESSION['message_delay']);
|
||||
}
|
||||
if (!empty($_SESSION['messages']) && is_array($_SESSION['messages']) && @sizeof($_SESSION['messages']) != 0) {
|
||||
foreach ($_SESSION['messages'] as $message_mood => $message) {
|
||||
$message_text = str_replace(["\r\n", "\n", "\r"], '\\n', addslashes(join('<br/>', $message['message'])));
|
||||
$message_delay = array_sum($message['delay']) / count($message['delay']);
|
||||
$html .= "{$spacer}display_message('$message_text', '$message_mood', '$message_delay');\n";
|
||||
}
|
||||
}
|
||||
if ($clear_messages) {
|
||||
unset($_SESSION['messages']);
|
||||
}
|
||||
if ($clear_messages) {
|
||||
unset($_SESSION['messages']);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a message to the session messages array.
|
||||
*
|
||||
* @param string $message The message to add.
|
||||
* @param string|null $mood The mood of the message. Defaults to 'positive'.
|
||||
* @param int|null $delay The delay before displaying the message. Defaults to the theme's default text
|
||||
* message delay in milliseconds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static function add($message, $mood = null, $delay = null) {
|
||||
//set mood and delay
|
||||
$mood = $mood ?: 'positive';
|
||||
$delay = $delay ?: (1000 * (float)$_SESSION['theme']['message_delay']['text']);
|
||||
//ignore duplicate messages
|
||||
if (isset($_SESSION["messages"]) && !empty($_SESSION["messages"][$mood]['message'])) {
|
||||
if (!in_array($message, $_SESSION["messages"][$mood]['message'])) {
|
||||
$_SESSION["messages"][$mood]['message'][] = $message;
|
||||
$_SESSION["messages"][$mood]['delay'][] = $delay;
|
||||
}
|
||||
return $html;
|
||||
} else {
|
||||
$_SESSION["messages"][$mood]['message'][] = $message;
|
||||
$_SESSION["messages"][$mood]['delay'][] = $delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,52 +25,70 @@
|
||||
Mark J Crane <markjcrane@fusionpbx.com>
|
||||
*/
|
||||
|
||||
class modal {
|
||||
class modal {
|
||||
|
||||
static function create($array) {
|
||||
/**
|
||||
* Creates a modal window.
|
||||
*
|
||||
* @param array $array Array containing the modal's properties.
|
||||
* The following keys are supported:
|
||||
* - id: ID of the modal (optional).
|
||||
* - type: Type of the modal (optional, one of 'copy', 'toggle',
|
||||
* 'delete' or 'unassign'). If not specified, a general
|
||||
* modal will be created. Defaults to 'general'.
|
||||
* - title: Title of the modal (optional). If not specified,
|
||||
* a default title will be used based on the type.
|
||||
* - message: Message of the modal (optional).
|
||||
* - actions: Actions of the modal (optional).
|
||||
* - onclose: Function to call when the modal is closed
|
||||
* (optional).
|
||||
*
|
||||
* @return string HTML string representing the modal window.
|
||||
*/
|
||||
static function create($array) {
|
||||
|
||||
//define as global
|
||||
global $settings;
|
||||
//define as global
|
||||
global $settings;
|
||||
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
$text = $language->get();
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
$text = $language->get();
|
||||
|
||||
$modal = "<div id='".(!empty($array['id']) ? $array['id'] : 'modal')."' class='modal-window'>\n";
|
||||
$modal .= " <div>\n";
|
||||
$modal .= " <span title=\"".$text['button-close']."\" class='modal-close' onclick=\"modal_close(); ".($array['onclose'] ?? '')."\">×</span>\n";
|
||||
if (!empty($array['type'])) {
|
||||
//determine type
|
||||
switch ($array['type']) {
|
||||
case 'copy':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-copy'];
|
||||
break;
|
||||
case 'toggle':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-toggle'];
|
||||
break;
|
||||
case 'delete':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-delete'];
|
||||
break;
|
||||
case 'unassign':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-unassign'];
|
||||
default: //general
|
||||
$array['title'] = !empty($array['title']) ? $array['title'] : $text['modal_title-confirmation'];
|
||||
}
|
||||
//prefix cancel button to action
|
||||
$array['actions'] = button::create(['type'=>'button','label'=>$text['button-cancel'],'icon'=>$settings->get('theme', 'button_icon_cancel'),'collapse'=>'never','onclick'=>'modal_close(); '.($array['onclose'] ?? '')]).$array['actions'];
|
||||
$modal = "<div id='" . (!empty($array['id']) ? $array['id'] : 'modal') . "' class='modal-window'>\n";
|
||||
$modal .= " <div>\n";
|
||||
$modal .= " <span title=\"" . $text['button-close'] . "\" class='modal-close' onclick=\"modal_close(); " . ($array['onclose'] ?? '') . "\">×</span>\n";
|
||||
if (!empty($array['type'])) {
|
||||
//determine type
|
||||
switch ($array['type']) {
|
||||
case 'copy':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-copy'];
|
||||
break;
|
||||
case 'toggle':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-toggle'];
|
||||
break;
|
||||
case 'delete':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-delete'];
|
||||
break;
|
||||
case 'unassign':
|
||||
$array['title'] = $text['modal_title-confirmation'];
|
||||
$array['message'] = $text['confirm-unassign'];
|
||||
default: //general
|
||||
$array['title'] = !empty($array['title']) ? $array['title'] : $text['modal_title-confirmation'];
|
||||
}
|
||||
$modal .= !empty($array['title']) ? " <span class='modal-title'>".$array['title']."</span>\n" : null;
|
||||
$modal .= !empty($array['message']) ? " <span class='modal-message'>".$array['message']."</span>\n" : null;
|
||||
$modal .= !empty($array['actions']) ? " <span class='modal-actions'>".$array['actions']."</span>\n" : null;
|
||||
$modal .= " </div>\n";
|
||||
$modal .= "</div>";
|
||||
|
||||
return $modal;
|
||||
|
||||
//prefix cancel button to action
|
||||
$array['actions'] = button::create(['type' => 'button', 'label' => $text['button-cancel'], 'icon' => $settings->get('theme', 'button_icon_cancel'), 'collapse' => 'never', 'onclick' => 'modal_close(); ' . ($array['onclose'] ?? '')]) . $array['actions'];
|
||||
}
|
||||
$modal .= !empty($array['title']) ? " <span class='modal-title'>" . $array['title'] . "</span>\n" : null;
|
||||
$modal .= !empty($array['message']) ? " <span class='modal-message'>" . $array['message'] . "</span>\n" : null;
|
||||
$modal .= !empty($array['actions']) ? " <span class='modal-actions'>" . $array['actions'] . "</span>\n" : null;
|
||||
$modal .= " </div>\n";
|
||||
$modal .= "</div>";
|
||||
|
||||
return $modal;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,15 +26,23 @@
|
||||
*/
|
||||
class permissions {
|
||||
|
||||
private static $permission;
|
||||
private $database;
|
||||
private $domain_uuid;
|
||||
private $user_uuid;
|
||||
private $groups;
|
||||
private $permissions;
|
||||
private static $permission;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* Constructor.
|
||||
*
|
||||
* Initializes this object with a database connection, domain UUID, and user UUID.
|
||||
*
|
||||
* @param Database|null $database Database connection. If null, a new database connection will be created.
|
||||
* @param string|null $domain_uuid Domain UUID. If null, the value from the session will be used.
|
||||
* @param string|null $user_uuid User UUID. If null, the value from the session will be used.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($database = null, $domain_uuid = null, $user_uuid = null) {
|
||||
|
||||
@@ -45,32 +53,28 @@ class permissions {
|
||||
//handle the database object
|
||||
if (isset($database)) {
|
||||
$this->database = $database;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->database = database::new();
|
||||
}
|
||||
|
||||
//set the domain_uuid
|
||||
if (!empty($domain_uuid) && is_uuid($domain_uuid)) {
|
||||
$this->domain_uuid = $domain_uuid;
|
||||
}
|
||||
elseif (isset($_SESSION['domain_uuid']) && is_uuid($_SESSION['domain_uuid'])) {
|
||||
} elseif (isset($_SESSION['domain_uuid']) && is_uuid($_SESSION['domain_uuid'])) {
|
||||
$this->domain_uuid = $_SESSION['domain_uuid'];
|
||||
}
|
||||
|
||||
//set the user_uuid
|
||||
if (!empty($user_uuid) && is_uuid($user_uuid)) {
|
||||
$this->user_uuid = $user_uuid;
|
||||
}
|
||||
elseif (isset($_SESSION['user_uuid']) && is_uuid($_SESSION['user_uuid'])) {
|
||||
} elseif (isset($_SESSION['user_uuid']) && is_uuid($_SESSION['user_uuid'])) {
|
||||
$this->user_uuid = $_SESSION['user_uuid'];
|
||||
}
|
||||
|
||||
//get the permissions
|
||||
if (isset($_SESSION['permissions'])) {
|
||||
$this->permissions = $_SESSION['permissions'];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//create the groups object
|
||||
$groups = new groups($this->database, $this->domain_uuid, $this->user_uuid);
|
||||
$this->groups = $groups->assigned();
|
||||
@@ -83,15 +87,92 @@ class permissions {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the array of permissions
|
||||
* A singleton pattern for either creating a new object or the existing object.
|
||||
*
|
||||
* Initializes this object with a database connection, domain UUID, and user UUID.
|
||||
*
|
||||
* @param Database|null $database Database connection. If null, a new database connection will be created.
|
||||
* @param string|null $domain_uuid Domain UUID. If null, the value from the session will be used.
|
||||
* @param string|null $user_uuid User UUID. If null, the value from the session will be used.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function new($database = null, $domain_uuid = null, $user_uuid = null) {
|
||||
if (self::$permission === null) {
|
||||
self::$permission = new permissions($database, $domain_uuid, $user_uuid);
|
||||
}
|
||||
return self::$permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to retrieve permissions assigned to the user through their groups.
|
||||
*
|
||||
* Retrieves the list of group names associated with the user's assigned groups,
|
||||
* and then uses these group names to query for distinct permission names that are
|
||||
* assigned to these groups. The resulting list of permission names is stored in
|
||||
* this object's 'permissions' array.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function assigned() {
|
||||
//define the array
|
||||
$permissions = [];
|
||||
$parameter_names = [];
|
||||
|
||||
//return empty array if there are no groups
|
||||
if (empty($this->groups)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//prepare the parameters
|
||||
$x = 0;
|
||||
foreach ($this->groups as $field) {
|
||||
if (!empty($field['group_name'])) {
|
||||
$parameter_names[] = ":group_name_" . $x;
|
||||
$parameters['group_name_' . $x] = $field['group_name'];
|
||||
$x++;
|
||||
}
|
||||
}
|
||||
|
||||
//get the permissions assigned to the user through the assigned groups
|
||||
$sql = "select distinct(permission_name) from v_group_permissions ";
|
||||
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
||||
$sql .= "and group_name in (" . implode(", ", $parameter_names) . ") \n";
|
||||
$sql .= "and permission_assigned = 'true' ";
|
||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||
$group_permissions = $this->database->select($sql, $parameters, 'all');
|
||||
|
||||
//format the permission array
|
||||
foreach ($group_permissions as $row) {
|
||||
$permissions[$row['permission_name']] = 1;
|
||||
}
|
||||
|
||||
//save permissions to this object
|
||||
$this->permissions = $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of permissions assigned to this user.
|
||||
*
|
||||
* The list of permissions is populated from the session or retrieved from the database based on
|
||||
* the domain UUID and user UUID associated with this object.
|
||||
*
|
||||
* @return array An array of permission identifiers (e.g. 'create_user', 'edit_group', etc.)
|
||||
*/
|
||||
public function get_permissions() {
|
||||
return $this->permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the permission
|
||||
* @var string $permission
|
||||
* Adds a permission to this object.
|
||||
*
|
||||
* If the specified permission does not already exist, it will be added to the permissions array with the provided
|
||||
* type.
|
||||
*
|
||||
* @param string $permission Permission to add.
|
||||
* @param mixed $type Type of the permission.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($permission, $type) {
|
||||
//add the permission if it is not in array
|
||||
@@ -101,27 +182,13 @@ class permissions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the permission
|
||||
* @var string $permission
|
||||
*/
|
||||
public function delete($permission, $type) {
|
||||
if ($this->exists($permission) && !empty($this->permissions[$permission])) {
|
||||
if ($type === "temp") {
|
||||
if ($this->permissions[$permission] === "temp") {
|
||||
unset($this->permissions[$permission]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($this->permissions[$permission] !== "temp") {
|
||||
unset($this->permissions[$permission]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the permission exists
|
||||
* @var string $permission
|
||||
* Checks if a permission exists.
|
||||
*
|
||||
* Returns true if the permission is assigned to the user, or if this method is called from the command line.
|
||||
*
|
||||
* @param string $permission_name Name of the permission to check for existence.
|
||||
*
|
||||
* @return bool True if the permission exists, false otherwise.
|
||||
*/
|
||||
public function exists($permission_name) {
|
||||
|
||||
@@ -139,48 +206,33 @@ class permissions {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the assigned permissions
|
||||
* @var array $groups
|
||||
* Deletes a permission.
|
||||
*
|
||||
* If the permission exists and is not temporary, it will be removed from the permissions array.
|
||||
*
|
||||
* @param string $permission The name of the permission to delete.
|
||||
* @param string $type The type of permission (e.g. "temp", "permanent").
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function assigned() {
|
||||
//define the array
|
||||
$permissions = [];
|
||||
$parameter_names = [];
|
||||
|
||||
//return empty array if there are no groups
|
||||
if (empty($this->groups)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//prepare the parameters
|
||||
$x = 0;
|
||||
foreach ($this->groups as $field) {
|
||||
if (!empty($field['group_name'])) {
|
||||
$parameter_names[] = ":group_name_".$x;
|
||||
$parameters['group_name_'.$x] = $field['group_name'];
|
||||
$x++;
|
||||
public function delete($permission, $type) {
|
||||
if ($this->exists($permission) && !empty($this->permissions[$permission])) {
|
||||
if ($type === "temp") {
|
||||
if ($this->permissions[$permission] === "temp") {
|
||||
unset($this->permissions[$permission]);
|
||||
}
|
||||
} else {
|
||||
if ($this->permissions[$permission] !== "temp") {
|
||||
unset($this->permissions[$permission]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//get the permissions assigned to the user through the assigned groups
|
||||
$sql = "select distinct(permission_name) from v_group_permissions ";
|
||||
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
||||
$sql .= "and group_name in (".implode(", ", $parameter_names).") \n";
|
||||
$sql .= "and permission_assigned = 'true' ";
|
||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||
$group_permissions = $this->database->select($sql, $parameters, 'all');
|
||||
|
||||
//format the permission array
|
||||
foreach ($group_permissions as $row) {
|
||||
$permissions[$row['permission_name']] = 1;
|
||||
}
|
||||
|
||||
//save permissions to this object
|
||||
$this->permissions = $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* save the assigned permissions to a session
|
||||
* Saves the current permissions to the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function session() {
|
||||
if (!empty($this->permissions)) {
|
||||
@@ -191,24 +243,14 @@ class permissions {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new permission object
|
||||
*/
|
||||
public static function new($database = null, $domain_uuid = null, $user_uuid = null) {
|
||||
if (self::$permission === null) {
|
||||
self::$permission = new permissions($database, $domain_uuid, $user_uuid);
|
||||
}
|
||||
return self::$permission;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//examples
|
||||
/*
|
||||
//add the permission
|
||||
$p = permissions::new();
|
||||
$p->add($permission);
|
||||
//delete the permission
|
||||
$p = permissions::new();
|
||||
$p->delete($permission);
|
||||
*/
|
||||
/*
|
||||
//add the permission
|
||||
$p = permissions::new();
|
||||
$p->add($permission);
|
||||
//delete the permission
|
||||
$p = permissions::new();
|
||||
$p->delete($permission);
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@
|
||||
/**
|
||||
* The settings class is used to load settings using hierarchical overriding
|
||||
*
|
||||
* The settings are loaded from the database tables default_settings, domain_settings, and user_settings in that order with
|
||||
* Each setting overrides the setting from the previous table.
|
||||
* The settings are loaded from the database tables default_settings, domain_settings, and user_settings in that order
|
||||
* with Each setting overrides the setting from the previous table.
|
||||
*
|
||||
* @access public
|
||||
* @author Mark Crane <mark@fusionpbx.com>
|
||||
@@ -12,49 +12,59 @@
|
||||
class settings implements clear_cache {
|
||||
|
||||
/**
|
||||
* Set in the constructor. String used to load a specific domain. Must be a value domain UUID before sending to the constructor.
|
||||
* Set in the constructor. String used to load a specific domain. Must be a value domain UUID before sending to the
|
||||
* constructor.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
|
||||
/**
|
||||
* Set in the constructor. String used to load a specific user. Must be a valid user UUID before sending to the constructor.
|
||||
* Set in the constructor. String used to load a specific user. Must be a valid user UUID before sending to the
|
||||
* constructor.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $user_uuid;
|
||||
|
||||
/**
|
||||
* Set in the constructor. String used for loading a specific device UUID
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $device_uuid;
|
||||
|
||||
/**
|
||||
* Set in the constructor. String used for loading device profile
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $device_profile_uuid;
|
||||
|
||||
/**
|
||||
* Set in the constructor. Current category set to load
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $category;
|
||||
|
||||
/**
|
||||
* Internal array structure that is populated from the database
|
||||
*
|
||||
* @var array Array of settings loaded from Default Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Tracks if the APCu extension is loaded for database queries
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $apcu_enabled;
|
||||
@@ -63,9 +73,11 @@ class settings implements clear_cache {
|
||||
* Create a settings object using key/value pairs in the $setting_array.
|
||||
*
|
||||
* Valid values are: database, domain_uuid, user_uuid, device_uuid, device_profile_uuid, and category.
|
||||
*
|
||||
* @param array setting_array
|
||||
*
|
||||
* @depends database::new()
|
||||
* @access public
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($setting_array = []) {
|
||||
|
||||
@@ -89,7 +101,7 @@ class settings implements clear_cache {
|
||||
//trap passing a PDO object instead of the required database object
|
||||
if (!($this->database instanceof database)) {
|
||||
//should never happen but will trap it here just-in-case
|
||||
throw new \InvalidArgumentException("Database object passed in settings class constructor is not a valid database object");
|
||||
throw new InvalidArgumentException("Database object passed in settings class constructor is not a valid database object");
|
||||
}
|
||||
|
||||
//set the values from the array
|
||||
@@ -102,14 +114,6 @@ class settings implements clear_cache {
|
||||
$this->reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database object used in the settings
|
||||
* @return database Object
|
||||
*/
|
||||
public function database(): database {
|
||||
return $this->database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the settings from the database
|
||||
*/
|
||||
@@ -144,107 +148,9 @@ class settings implements clear_cache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value utilizing the hierarchical overriding technique
|
||||
* @param string|null $category Returns all settings when empty or the default value if the settings array is null
|
||||
* @param string|null $subcategory Returns the array of category items when empty or the default value if the category array is null
|
||||
* @param mixed $default_value allows default value returned if category and subcategory not found
|
||||
*/
|
||||
public function get(?string $category = null, ?string $subcategory = null, $default_value = null) {
|
||||
|
||||
//incremental refinement from all settings to a single setting
|
||||
if (empty($category)) {
|
||||
return $this->settings ?? $default_value;
|
||||
}
|
||||
elseif (empty($subcategory)) {
|
||||
return $this->settings[$category] ?? $default_value;
|
||||
}
|
||||
else {
|
||||
return $this->settings[$category][$subcategory] ?? $default_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the domain_uuid in this object used to load the settings
|
||||
* @return string UUID of the domain used to load the object or an empty string
|
||||
*/
|
||||
public function get_domain_uuid(): string {
|
||||
if (!empty($this->domain_uuid)) {
|
||||
return $this->domain_uuid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user_uuid in this object used to load the settings
|
||||
* @return string UUID of the user used to load the object or an empty string
|
||||
*/
|
||||
public function get_user_uuid(): string {
|
||||
if (!empty($this->user_uuid)) {
|
||||
return $this->user_uuid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* set the default, domain, user, device or device profile settings
|
||||
* @param string $table_prefix prefix for the table.
|
||||
* @param string $uuid uuid of the setting if available. If set to an empty string then a new uuid will be created.
|
||||
* @param string $category Category of the setting.
|
||||
* @param string $subcategory Subcategory of the setting.
|
||||
* @param string $value (optional) Value to set. Default is empty string.
|
||||
* @param string $type Type of the setting (array, numeric, text, etc)
|
||||
* @param bool $enabled (optional) True or False. Default is True.
|
||||
* @param string $description (optional) Description. Default is empty string.
|
||||
*/
|
||||
public function set(string $table_prefix, string $uuid, string $category, string $subcategory, string $value = "", string $type = 'text', bool $enabled = true, string $description = "") {
|
||||
|
||||
//set the table name
|
||||
$table_name = $table_prefix.'_settings';
|
||||
|
||||
//init record as an array
|
||||
$record = [];
|
||||
if(!empty($this->domain_uuid)) {
|
||||
$record[$table_name][0]['domain_uuid'] = $this->domain_uuid;
|
||||
}
|
||||
if(!empty($this->user_uuid)) {
|
||||
$record[$table_name][0]['user_uuid'] = $this->user_uuid;
|
||||
}
|
||||
if(!empty($this->device_uuid)) {
|
||||
$record[$table_name][0]['device_uuid'] = $this->device_uuid;
|
||||
}
|
||||
if(!empty($this->device_profile_uuid)) {
|
||||
$record[$table_name][0]['device_profile_uuid'] = $this->device_profile_uuid;
|
||||
}
|
||||
if(!is_uuid($uuid)) {
|
||||
$uuid = uuid();
|
||||
}
|
||||
|
||||
//build the array
|
||||
$record[$table_name][0][$table_prefix.'_setting_uuid' ] = $uuid;
|
||||
$record[$table_name][0][$table_prefix.'_setting_category' ] = $category;
|
||||
$record[$table_name][0][$table_prefix.'_setting_subcategory'] = $subcategory;
|
||||
$record[$table_name][0][$table_prefix.'_setting_name' ] = $type;
|
||||
$record[$table_name][0][$table_prefix.'_setting_value' ] = $value;
|
||||
$record[$table_name][0][$table_prefix.'_setting_enabled' ] = $enabled;
|
||||
$record[$table_name][0][$table_prefix.'_setting_description'] = $description;
|
||||
|
||||
//grant temporary permissions
|
||||
$p = permissions::new();
|
||||
$p->add($table_prefix.'_setting_add', 'temp');
|
||||
$p->add($table_prefix.'_setting_edit', 'temp');
|
||||
|
||||
//execute insert
|
||||
$this->database->app_name = $table_name;
|
||||
$this->database->save($record);
|
||||
|
||||
//revoke temporary permissions
|
||||
$p->delete($table_prefix.'_setting_add', 'temp');
|
||||
$p->delete($table_prefix.'_setting_edit', 'temp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the internal settings array with the default settings from the database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function default_settings() {
|
||||
@@ -275,14 +181,12 @@ class settings implements clear_cache {
|
||||
if (isset($row['default_setting_value']) && $row['default_setting_value'] !== '') {
|
||||
if ($name == "boolean") {
|
||||
$this->settings[$category][$subcategory] = filter_var($row['default_setting_value'], FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
elseif ($name == "array") {
|
||||
} elseif ($name == "array") {
|
||||
if (!isset($this->settings[$category][$subcategory]) || !is_array($this->settings[$category][$subcategory])) {
|
||||
$this->settings[$category][$subcategory] = array();
|
||||
$this->settings[$category][$subcategory] = [];
|
||||
}
|
||||
$this->settings[$category][$subcategory][] = $row['default_setting_value'];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->settings[$category][$subcategory] = $row['default_setting_value'];
|
||||
}
|
||||
}
|
||||
@@ -297,6 +201,7 @@ class settings implements clear_cache {
|
||||
|
||||
/**
|
||||
* Update the internal settings array with the domain settings from the database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function domain_settings($domain_uuid = '', $i = 0) {
|
||||
@@ -312,7 +217,7 @@ class settings implements clear_cache {
|
||||
$this->domain_settings($uuid, $i++);
|
||||
}
|
||||
|
||||
$key = 'settings_domain_'.$domain_uuid;
|
||||
$key = 'settings_domain_' . $domain_uuid;
|
||||
|
||||
$result = '';
|
||||
//if the apcu extension is loaded get the cached database result
|
||||
@@ -336,7 +241,7 @@ class settings implements clear_cache {
|
||||
$category = $row['domain_setting_category'];
|
||||
$subcategory = $row['domain_setting_subcategory'];
|
||||
if ($name == "array") {
|
||||
$this->settings[$category][$subcategory] = array();
|
||||
$this->settings[$category][$subcategory] = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,11 +256,10 @@ class settings implements clear_cache {
|
||||
}
|
||||
if ($name == "array") {
|
||||
if (!isset($this->settings[$category][$subcategory]) || !is_array($this->settings[$category][$subcategory])) {
|
||||
$this->settings[$category][$subcategory] = array();
|
||||
$this->settings[$category][$subcategory] = [];
|
||||
}
|
||||
$this->settings[$category][$subcategory][] = $row['domain_setting_value'];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->settings[$category][$subcategory] = $row['domain_setting_value'];
|
||||
}
|
||||
}
|
||||
@@ -366,11 +270,12 @@ class settings implements clear_cache {
|
||||
|
||||
/**
|
||||
* Update the internal settings array with the user settings from the database
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
* @depends $this->domain_uuid
|
||||
*/
|
||||
private function user_settings() {
|
||||
$key = 'settings_user_'.$this->user_uuid;
|
||||
$key = 'settings_user_' . $this->user_uuid;
|
||||
$result = '';
|
||||
//if the apcu extension is loaded get the cached database result
|
||||
if ($this->apcu_enabled && apcu_exists($key)) {
|
||||
@@ -397,11 +302,9 @@ class settings implements clear_cache {
|
||||
if (isset($row['user_setting_value']) && $row['user_setting_value'] !== '') {
|
||||
if ($name == "boolean") {
|
||||
$this->settings[$category][$subcategory] = filter_var($row['user_setting_value'], FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
elseif ($name == "array") {
|
||||
} elseif ($name == "array") {
|
||||
$this->settings[$category][$subcategory][] = $row['user_setting_value'];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->settings[$category][$subcategory] = $row['user_setting_value'];
|
||||
}
|
||||
|
||||
@@ -413,7 +316,8 @@ class settings implements clear_cache {
|
||||
|
||||
/**
|
||||
* Update the internal settings array with the device profile settings from the database
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
* @depends $this->domain_uuid
|
||||
*/
|
||||
private function device_profile_settings() {
|
||||
@@ -438,7 +342,8 @@ class settings implements clear_cache {
|
||||
|
||||
/**
|
||||
* Update the internal settings array with the device settings from the database
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
* @depends $this->domain_uuid
|
||||
*/
|
||||
private function device_settings() {
|
||||
@@ -461,6 +366,15 @@ class settings implements clear_cache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the APC cache and reloads the settings object.
|
||||
*
|
||||
* This method checks if APC is enabled on the server and if so, it clears
|
||||
* any cached entries that start with "settings_". It then recreates the
|
||||
* settings object to load all settings from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clear_cache() {
|
||||
if (function_exists('apcu_enabled') && apcu_enabled()) {
|
||||
$cache = apcu_cache_info(false);
|
||||
@@ -484,4 +398,126 @@ class settings implements clear_cache {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database object used in the settings
|
||||
*
|
||||
* @return database Object
|
||||
*/
|
||||
public function database(): database {
|
||||
return $this->database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the domain_uuid in this object used to load the settings
|
||||
*
|
||||
* @return string UUID of the domain used to load the object or an empty string
|
||||
*/
|
||||
public function get_domain_uuid(): string {
|
||||
if (!empty($this->domain_uuid)) {
|
||||
return $this->domain_uuid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user_uuid in this object used to load the settings
|
||||
*
|
||||
* @return string UUID of the user used to load the object or an empty string
|
||||
*/
|
||||
public function get_user_uuid(): string {
|
||||
if (!empty($this->user_uuid)) {
|
||||
return $this->user_uuid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value utilizing the hierarchical overriding technique
|
||||
*
|
||||
* @param string|null $category Returns all settings when empty or the default value if the settings array is
|
||||
* null
|
||||
* @param string|null $subcategory Returns the array of category items when empty or the default value if the
|
||||
* category array is null
|
||||
* @param mixed $default_value allows default value returned if category and subcategory not found
|
||||
*/
|
||||
public function get(?string $category = null, ?string $subcategory = null, $default_value = null) {
|
||||
|
||||
//incremental refinement from all settings to a single setting
|
||||
if (empty($category)) {
|
||||
return $this->settings ?? $default_value;
|
||||
} elseif (empty($subcategory)) {
|
||||
return $this->settings[$category] ?? $default_value;
|
||||
} else {
|
||||
return $this->settings[$category][$subcategory] ?? $default_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update an in-memory setting for a domain, user, device,
|
||||
* or device profile.
|
||||
*
|
||||
* This method assembles a settings record, generates a UUID when needed,
|
||||
* assigns ownership context (domain, user, device, or device profile),
|
||||
* grants temporary permissions, and commits the record using the database
|
||||
* abstraction layer. Only in-memory values are modified; this does not
|
||||
* reload or apply settings system-wide.
|
||||
*
|
||||
* @param string $table_prefix Prefix used to build the settings table name.
|
||||
* @param string $uuid UUID of the setting. A new UUID is generated
|
||||
* if the provided value is empty or invalid.
|
||||
* @param string $category Setting category.
|
||||
* @param string $subcategory Setting subcategory.
|
||||
* @param string $value Optional value for the setting. Defaults to an empty string.
|
||||
* @param string $type Setting type (e.g. text, numeric, array).
|
||||
* @param bool $enabled Whether the setting is enabled. Defaults to true.
|
||||
* @param string $description Optional description for the setting.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set(string $table_prefix, string $uuid, string $category, string $subcategory, string $value = "", string $type = 'text', bool $enabled = true, string $description = "") {
|
||||
|
||||
//set the table name
|
||||
$table_name = $table_prefix . '_settings';
|
||||
|
||||
//init record as an array
|
||||
$record = [];
|
||||
if (!empty($this->domain_uuid)) {
|
||||
$record[$table_name][0]['domain_uuid'] = $this->domain_uuid;
|
||||
}
|
||||
if (!empty($this->user_uuid)) {
|
||||
$record[$table_name][0]['user_uuid'] = $this->user_uuid;
|
||||
}
|
||||
if (!empty($this->device_uuid)) {
|
||||
$record[$table_name][0]['device_uuid'] = $this->device_uuid;
|
||||
}
|
||||
if (!empty($this->device_profile_uuid)) {
|
||||
$record[$table_name][0]['device_profile_uuid'] = $this->device_profile_uuid;
|
||||
}
|
||||
if (!is_uuid($uuid)) {
|
||||
$uuid = uuid();
|
||||
}
|
||||
|
||||
//build the array
|
||||
$record[$table_name][0][$table_prefix . '_setting_uuid'] = $uuid;
|
||||
$record[$table_name][0][$table_prefix . '_setting_category'] = $category;
|
||||
$record[$table_name][0][$table_prefix . '_setting_subcategory'] = $subcategory;
|
||||
$record[$table_name][0][$table_prefix . '_setting_name'] = $type;
|
||||
$record[$table_name][0][$table_prefix . '_setting_value'] = $value;
|
||||
$record[$table_name][0][$table_prefix . '_setting_enabled'] = $enabled;
|
||||
$record[$table_name][0][$table_prefix . '_setting_description'] = $description;
|
||||
|
||||
//grant temporary permissions
|
||||
$p = permissions::new();
|
||||
$p->add($table_prefix . '_setting_add', 'temp');
|
||||
$p->add($table_prefix . '_setting_edit', 'temp');
|
||||
|
||||
//execute insert
|
||||
$this->database->app_name = $table_name;
|
||||
$this->database->save($record);
|
||||
|
||||
//revoke temporary permissions
|
||||
$p->delete($table_prefix . '_setting_add', 'temp');
|
||||
$p->delete($table_prefix . '_setting_edit', 'temp');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,31 +2,36 @@
|
||||
|
||||
/**
|
||||
* sounds class
|
||||
*
|
||||
* @method string get
|
||||
*/
|
||||
class sounds {
|
||||
|
||||
/**
|
||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $domain_uuid;
|
||||
|
||||
/**
|
||||
* Additional public variables
|
||||
*/
|
||||
* Additional public variables
|
||||
*/
|
||||
public $sound_types;
|
||||
public $full_path;
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
* Constructor for the class.
|
||||
*
|
||||
* This method initializes the object with setting_array and session data.
|
||||
*
|
||||
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||
*/
|
||||
public function __construct(array $setting_array = []) {
|
||||
//set domain and user UUIDs
|
||||
@@ -37,76 +42,75 @@ class sounds {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a specific item in the cache
|
||||
* @var array $array
|
||||
* @var string $value string to be cached
|
||||
* Retrieves a list of sound files based on the specified types.
|
||||
*
|
||||
* @return array A multidimensional array containing the sound files, where each sub-array has two keys: 'name' and
|
||||
* 'value'.
|
||||
*/
|
||||
public function get() {
|
||||
|
||||
//miscellaneous
|
||||
if (empty($this->sound_types) || (is_array($this->sound_types) && in_array('miscellaneous', $this->sound_types))) {
|
||||
$x = 0;
|
||||
if (if_group("superadmin")) {
|
||||
$array['miscellaneous'][$x]['name'] = "say";
|
||||
$array['miscellaneous'][$x]['value'] = "say:";
|
||||
$x++;
|
||||
$array['miscellaneous'][$x]['name'] = "tone_stream";
|
||||
$array['miscellaneous'][$x]['value'] = "tone_stream:";
|
||||
}
|
||||
if (empty($this->sound_types) || (is_array($this->sound_types) && in_array('miscellaneous', $this->sound_types))) {
|
||||
$x = 0;
|
||||
if (if_group("superadmin")) {
|
||||
$array['miscellaneous'][$x]['name'] = "say";
|
||||
$array['miscellaneous'][$x]['value'] = "say:";
|
||||
$x++;
|
||||
$array['miscellaneous'][$x]['name'] = "tone_stream";
|
||||
$array['miscellaneous'][$x]['value'] = "tone_stream:";
|
||||
}
|
||||
}
|
||||
//recordings
|
||||
if ((empty($this->sound_types) || (is_array($this->sound_types) && in_array('recordings', $this->sound_types))) && file_exists($_SERVER["PROJECT_ROOT"]."/app/recordings/app_config.php")) {
|
||||
$sql = "select recording_name, recording_filename from v_recordings ";
|
||||
$sql .= "where domain_uuid = :domain_uuid ";
|
||||
$sql .= "order by recording_name asc ";
|
||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||
$recordings = $this->database->select($sql, $parameters, 'all');
|
||||
if (is_array($recordings) && @sizeof($recordings) != 0) {
|
||||
foreach ($recordings as $x => $row) {
|
||||
$recording_name = $row["recording_name"];
|
||||
$recording_filename = $row["recording_filename"];
|
||||
$recording_path = !empty($this->full_path) && is_array($this->full_path) && in_array('recordings', $this->full_path) ? $_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/' : null;
|
||||
$array['recordings'][$x]['name'] = $recording_name;
|
||||
$array['recordings'][$x]['value'] = $recording_path.$recording_filename;
|
||||
}
|
||||
if ((empty($this->sound_types) || (is_array($this->sound_types) && in_array('recordings', $this->sound_types))) && file_exists($_SERVER["PROJECT_ROOT"] . "/app/recordings/app_config.php")) {
|
||||
$sql = "select recording_name, recording_filename from v_recordings ";
|
||||
$sql .= "where domain_uuid = :domain_uuid ";
|
||||
$sql .= "order by recording_name asc ";
|
||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||
$recordings = $this->database->select($sql, $parameters, 'all');
|
||||
if (is_array($recordings) && @sizeof($recordings) != 0) {
|
||||
foreach ($recordings as $x => $row) {
|
||||
$recording_name = $row["recording_name"];
|
||||
$recording_filename = $row["recording_filename"];
|
||||
$recording_path = !empty($this->full_path) && is_array($this->full_path) && in_array('recordings', $this->full_path) ? $_SESSION['switch']['recordings']['dir'] . '/' . $_SESSION['domain_name'] . '/' : null;
|
||||
$array['recordings'][$x]['name'] = $recording_name;
|
||||
$array['recordings'][$x]['value'] = $recording_path . $recording_filename;
|
||||
}
|
||||
unset($sql, $parameters, $recordings, $row);
|
||||
}
|
||||
unset($sql, $parameters, $recordings, $row);
|
||||
}
|
||||
//phrases
|
||||
if ((empty($this->sound_types) || (is_array($this->sound_types) && in_array('phrases', $this->sound_types))) && file_exists($_SERVER["PROJECT_ROOT"]."/app/phrases/app_config.php")) {
|
||||
$sql = "select * from v_phrases ";
|
||||
$sql .= "where domain_uuid = :domain_uuid ";
|
||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||
$phrases = $this->database->select($sql, $parameters, 'all');
|
||||
if (is_array($phrases) && @sizeof($phrases) != 0) {
|
||||
foreach ($phrases as $row) {
|
||||
$array['phrases'][$x]['name'] = "phrase:".$row["phrase_name"];
|
||||
$array['phrases'][$x]['value'] = "phrase:".$row["phrase_uuid"];
|
||||
$x++;
|
||||
}
|
||||
if ((empty($this->sound_types) || (is_array($this->sound_types) && in_array('phrases', $this->sound_types))) && file_exists($_SERVER["PROJECT_ROOT"] . "/app/phrases/app_config.php")) {
|
||||
$sql = "select * from v_phrases ";
|
||||
$sql .= "where domain_uuid = :domain_uuid ";
|
||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||
$phrases = $this->database->select($sql, $parameters, 'all');
|
||||
if (is_array($phrases) && @sizeof($phrases) != 0) {
|
||||
foreach ($phrases as $row) {
|
||||
$array['phrases'][$x]['name'] = "phrase:" . $row["phrase_name"];
|
||||
$array['phrases'][$x]['value'] = "phrase:" . $row["phrase_uuid"];
|
||||
$x++;
|
||||
}
|
||||
unset($sql, $parameters, $phrases, $row);
|
||||
}
|
||||
unset($sql, $parameters, $phrases, $row);
|
||||
}
|
||||
//sounds
|
||||
if ((empty($this->sound_types) || (is_array($this->sound_types) && in_array('sounds', $this->sound_types))) && file_exists($_SERVER["PROJECT_ROOT"]."/app/phrases/app_config.php")) {
|
||||
$file = new file;
|
||||
$sound_files = $file->sounds();
|
||||
if (is_array($sound_files) && @sizeof($sound_files) != 0) {
|
||||
foreach ($sound_files as $value) {
|
||||
if (substr($value, 0, 71) == "\$\${sounds_dir}/\${default_language}/\${default_dialect}/\${default_voice}/") {
|
||||
$value = substr($value, 71);
|
||||
}
|
||||
$array['sounds'][$x]['name'] = $value;
|
||||
$array['sounds'][$x]['value'] = $value;
|
||||
$x++;
|
||||
if ((empty($this->sound_types) || (is_array($this->sound_types) && in_array('sounds', $this->sound_types))) && file_exists($_SERVER["PROJECT_ROOT"] . "/app/phrases/app_config.php")) {
|
||||
$file = new file;
|
||||
$sound_files = $file->sounds();
|
||||
if (is_array($sound_files) && @sizeof($sound_files) != 0) {
|
||||
foreach ($sound_files as $value) {
|
||||
if (substr($value, 0, 71) == "\$\${sounds_dir}/\${default_language}/\${default_dialect}/\${default_voice}/") {
|
||||
$value = substr($value, 71);
|
||||
}
|
||||
$array['sounds'][$x]['name'] = $value;
|
||||
$array['sounds'][$x]['value'] = $value;
|
||||
$x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//send the results
|
||||
return $array;
|
||||
return $array;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -5,291 +5,310 @@
|
||||
*
|
||||
* @method settings will add missing switch directories to default settings
|
||||
*/
|
||||
class switch_settings {
|
||||
class switch_settings {
|
||||
|
||||
public $event_socket_ip_address;
|
||||
public $event_socket_port;
|
||||
public $event_socket_password;
|
||||
public $event_socket_ip_address;
|
||||
public $event_socket_port;
|
||||
public $event_socket_password;
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
private $settings;
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
private $user_uuid;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* @var string
|
||||
*/
|
||||
private $username;
|
||||
/**
|
||||
* Username 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 $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
|
||||
* @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
|
||||
*
|
||||
* @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
|
||||
* @var string
|
||||
*/
|
||||
private $domain_name;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private $domain_name;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
*/
|
||||
public function __construct(array $setting_array = []) {
|
||||
//set domain and user UUIDs
|
||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||
$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'] ?? '';
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*
|
||||
* This method initializes the object with setting_array and session data.
|
||||
*
|
||||
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||
*/
|
||||
public function __construct(array $setting_array = []) {
|
||||
//set domain and user UUIDs
|
||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||
$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
|
||||
$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]);
|
||||
//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]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* settings Set switch directories in default settings
|
||||
*/
|
||||
public function settings() {
|
||||
|
||||
//connect to event socket
|
||||
$esl = event_socket::create($this->event_socket_ip_address, $this->event_socket_port, $this->event_socket_password);
|
||||
|
||||
//run the api command
|
||||
$result = $esl->request('api global_getvar');
|
||||
|
||||
//set the result as a named array
|
||||
$vars = array();
|
||||
foreach (explode("\n", $result) as $row) {
|
||||
$a = explode("=", $row);
|
||||
if (substr($a[0], -4) == "_dir") {
|
||||
$vars[$a[0]] = $a[1];
|
||||
}
|
||||
}
|
||||
|
||||
//set defaults
|
||||
$vars['base_dir'] = $vars['base_dir'] ?? '';
|
||||
$vars['conf_dir'] = $vars['conf_dir'] ?? '';
|
||||
$vars['db_dir'] = $vars['db_dir'] ?? '';
|
||||
$vars['recordings_dir'] = $vars['recordings_dir'] ?? '';
|
||||
$vars['script_dir'] = $vars['script_dir'] ?? '';
|
||||
$vars['sounds_dir'] = $vars['sounds_dir'] ?? '';
|
||||
$vars['storage_dir'] = $vars['storage_dir'] ?? '';
|
||||
$vars['grammar_dir'] = $vars['grammar_dir'] ?? '';
|
||||
$vars['log_dir'] = $vars['log_dir'] ?? '';
|
||||
$vars['mod_dir'] = $vars['mod_dir'] ?? '';
|
||||
|
||||
//set the bin directory
|
||||
if ($vars['base_dir'] == "/usr/local/freeswitch") {
|
||||
$bin = '/usr/local/freeswitch/bin';
|
||||
}
|
||||
else {
|
||||
$bin = '';
|
||||
}
|
||||
|
||||
//create the default settings array
|
||||
$x=0;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'bin';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $bin;
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'base';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['base_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'call_center';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'].'/autoload_configs';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'conf';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'db';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['db_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'dialplan';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'].'/dialplan';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'extensions';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'].'/directory';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'grammar';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['grammar_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'log';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['log_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'mod';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['mod_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'languages';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'].'/languages';
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'recordings';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['recordings_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'scripts';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['script_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'sip_profiles';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'].'/sip_profiles';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'sounds';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['sounds_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'storage';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['storage_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'voicemail';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['storage_dir'].'/voicemail';
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
|
||||
//get an array of the default settings
|
||||
$sql = "select * from v_default_settings ";
|
||||
$sql .= "where default_setting_category = 'switch' ";
|
||||
$default_settings = $this->database->select($sql, null, 'all');
|
||||
unset($sql);
|
||||
|
||||
//find the missing default settings
|
||||
$x = 0;
|
||||
foreach ($array as $setting) {
|
||||
$found = false;
|
||||
$missing[$x] = $setting;
|
||||
foreach ($default_settings as $row) {
|
||||
if (trim($row['default_setting_subcategory']) == trim($setting['default_setting_subcategory'])) {
|
||||
$found = true;
|
||||
//remove items from the array that were found
|
||||
unset($missing[$x]);
|
||||
}
|
||||
}
|
||||
$x++;
|
||||
}
|
||||
unset($array);
|
||||
|
||||
//add the missing default settings
|
||||
if (count($missing) > 0) {
|
||||
$i = 1;
|
||||
foreach ($missing as $row) {
|
||||
//build insert array
|
||||
$array['default_settings'][$i]['default_setting_uuid'] = uuid();
|
||||
$array['default_settings'][$i]['default_setting_category'] = $row['default_setting_category'];
|
||||
$array['default_settings'][$i]['default_setting_subcategory'] = $row['default_setting_subcategory'];
|
||||
$array['default_settings'][$i]['default_setting_name'] = $row['default_setting_name'];
|
||||
$array['default_settings'][$i]['default_setting_value'] = $row['default_setting_value'];
|
||||
$array['default_settings'][$i]['default_setting_enabled'] = $row['default_setting_enabled'];
|
||||
$array['default_settings'][$i]['default_setting_description'] = $row['default_setting_description'];
|
||||
|
||||
//increment the row id
|
||||
$i++;
|
||||
}
|
||||
if (is_array($array) && @sizeof($array) != 0) {
|
||||
//grant temporary permissions
|
||||
$p = permissions::new();
|
||||
$p->add('default_setting_add', 'temp');
|
||||
|
||||
//execute insert
|
||||
$this->database->save($array);
|
||||
|
||||
//clear the apcu cache
|
||||
settings::clear_cache();
|
||||
|
||||
//revoke temporary permissions
|
||||
$p->delete('default_setting_add', 'temp');
|
||||
}
|
||||
unset($missing);
|
||||
}
|
||||
|
||||
//set the default settings
|
||||
if (!empty($array) && is_array($array)) {
|
||||
foreach ($array as $row) {
|
||||
if (isset($row['default_setting_enabled']) && $row['default_setting_enabled'] == "true" && isset($row['default_setting_subcategory'])) {
|
||||
$_SESSION['switch'][$row['default_setting_subcategory']][$row['default_setting_name']] = $row['default_setting_value'] ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unset the array variable
|
||||
unset($array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default settings for the application.
|
||||
*
|
||||
* This method retrieves the default settings from the event socket and
|
||||
* creates an array of default setting categories, subcategories, names,
|
||||
* values, and descriptions.
|
||||
*
|
||||
* @return array An array of default settings.
|
||||
*/
|
||||
public function settings() {
|
||||
|
||||
//connect to event socket
|
||||
$esl = event_socket::create($this->event_socket_ip_address, $this->event_socket_port, $this->event_socket_password);
|
||||
|
||||
//run the api command
|
||||
$result = $esl->request('api global_getvar');
|
||||
|
||||
//set the result as a named array
|
||||
$vars = [];
|
||||
foreach (explode("\n", $result) as $row) {
|
||||
$a = explode("=", $row);
|
||||
if (substr($a[0], -4) == "_dir") {
|
||||
$vars[$a[0]] = $a[1];
|
||||
}
|
||||
}
|
||||
|
||||
//set defaults
|
||||
$vars['base_dir'] = $vars['base_dir'] ?? '';
|
||||
$vars['conf_dir'] = $vars['conf_dir'] ?? '';
|
||||
$vars['db_dir'] = $vars['db_dir'] ?? '';
|
||||
$vars['recordings_dir'] = $vars['recordings_dir'] ?? '';
|
||||
$vars['script_dir'] = $vars['script_dir'] ?? '';
|
||||
$vars['sounds_dir'] = $vars['sounds_dir'] ?? '';
|
||||
$vars['storage_dir'] = $vars['storage_dir'] ?? '';
|
||||
$vars['grammar_dir'] = $vars['grammar_dir'] ?? '';
|
||||
$vars['log_dir'] = $vars['log_dir'] ?? '';
|
||||
$vars['mod_dir'] = $vars['mod_dir'] ?? '';
|
||||
|
||||
//set the bin directory
|
||||
if ($vars['base_dir'] == "/usr/local/freeswitch") {
|
||||
$bin = '/usr/local/freeswitch/bin';
|
||||
} else {
|
||||
$bin = '';
|
||||
}
|
||||
|
||||
//create the default settings array
|
||||
$x = 0;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'bin';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $bin;
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'base';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['base_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'call_center';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'] . '/autoload_configs';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'conf';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'db';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['db_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'dialplan';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'] . '/dialplan';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'extensions';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'] . '/directory';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'grammar';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['grammar_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'log';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['log_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'mod';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['mod_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'languages';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'] . '/languages';
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'recordings';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['recordings_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'scripts';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['script_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'sip_profiles';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['conf_dir'] . '/sip_profiles';
|
||||
$array[$x]['default_setting_enabled'] = 'false';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'sounds';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['sounds_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'storage';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['storage_dir'];
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
$array[$x]['default_setting_category'] = 'switch';
|
||||
$array[$x]['default_setting_subcategory'] = 'voicemail';
|
||||
$array[$x]['default_setting_name'] = 'dir';
|
||||
$array[$x]['default_setting_value'] = $vars['storage_dir'] . '/voicemail';
|
||||
$array[$x]['default_setting_enabled'] = 'true';
|
||||
$array[$x]['default_setting_description'] = '';
|
||||
$x++;
|
||||
|
||||
//get an array of the default settings
|
||||
$sql = "select * from v_default_settings ";
|
||||
$sql .= "where default_setting_category = 'switch' ";
|
||||
$default_settings = $this->database->select($sql, null, 'all');
|
||||
unset($sql);
|
||||
|
||||
//find the missing default settings
|
||||
$x = 0;
|
||||
foreach ($array as $setting) {
|
||||
$found = false;
|
||||
$missing[$x] = $setting;
|
||||
foreach ($default_settings as $row) {
|
||||
if (trim($row['default_setting_subcategory']) == trim($setting['default_setting_subcategory'])) {
|
||||
$found = true;
|
||||
//remove items from the array that were found
|
||||
unset($missing[$x]);
|
||||
}
|
||||
}
|
||||
$x++;
|
||||
}
|
||||
unset($array);
|
||||
|
||||
//add the missing default settings
|
||||
if (count($missing) > 0) {
|
||||
$i = 1;
|
||||
foreach ($missing as $row) {
|
||||
//build insert array
|
||||
$array['default_settings'][$i]['default_setting_uuid'] = uuid();
|
||||
$array['default_settings'][$i]['default_setting_category'] = $row['default_setting_category'];
|
||||
$array['default_settings'][$i]['default_setting_subcategory'] = $row['default_setting_subcategory'];
|
||||
$array['default_settings'][$i]['default_setting_name'] = $row['default_setting_name'];
|
||||
$array['default_settings'][$i]['default_setting_value'] = $row['default_setting_value'];
|
||||
$array['default_settings'][$i]['default_setting_enabled'] = $row['default_setting_enabled'];
|
||||
$array['default_settings'][$i]['default_setting_description'] = $row['default_setting_description'];
|
||||
|
||||
//increment the row id
|
||||
$i++;
|
||||
}
|
||||
if (is_array($array) && @sizeof($array) != 0) {
|
||||
//grant temporary permissions
|
||||
$p = permissions::new();
|
||||
$p->add('default_setting_add', 'temp');
|
||||
|
||||
//execute insert
|
||||
$this->database->save($array);
|
||||
|
||||
//clear the apcu cache
|
||||
settings::clear_cache();
|
||||
|
||||
//revoke temporary permissions
|
||||
$p->delete('default_setting_add', 'temp');
|
||||
}
|
||||
unset($missing);
|
||||
}
|
||||
|
||||
//set the default settings
|
||||
if (!empty($array) && is_array($array)) {
|
||||
foreach ($array as $row) {
|
||||
if (isset($row['default_setting_enabled']) && $row['default_setting_enabled'] == "true" && isset($row['default_setting_subcategory'])) {
|
||||
$_SESSION['switch'][$row['default_setting_subcategory']][$row['default_setting_name']] = $row['default_setting_value'] ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unset the array variable
|
||||
unset($array);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,67 +25,91 @@
|
||||
*/
|
||||
|
||||
//define the template class
|
||||
class template {
|
||||
class template {
|
||||
|
||||
public $engine;
|
||||
public $template_dir;
|
||||
public $cache_dir;
|
||||
private $object;
|
||||
private $var_array;
|
||||
public $engine;
|
||||
public $template_dir;
|
||||
public $cache_dir;
|
||||
private $object;
|
||||
private $var_array;
|
||||
|
||||
public function __construct(){
|
||||
}
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function init() {
|
||||
if ($this->engine === 'smarty') {
|
||||
require_once "resources/templates/engine/smarty/Smarty.class.php";
|
||||
$this->object = new Smarty();
|
||||
$this->object->setTemplateDir($this->template_dir);
|
||||
$this->object->setCompileDir($this->cache_dir);
|
||||
$this->object->setCacheDir($this->cache_dir);
|
||||
$this->object->registerPlugin("modifier","in_array", "in_array");
|
||||
}
|
||||
if ($this->engine === 'raintpl') {
|
||||
require_once "resources/templates/engine/raintpl/rain.tpl.class.php";
|
||||
$this->object = new RainTPL();
|
||||
RainTPL::configure('tpl_dir', realpath($this->template_dir)."/");
|
||||
RainTPL::configure('cache_dir', realpath($this->cache_dir)."/");
|
||||
}
|
||||
if ($this->engine === 'twig') {
|
||||
require_once "resources/templates/engine/Twig/Autoloader.php";
|
||||
Twig_Autoloader::register();
|
||||
$loader = new Twig_Loader_Filesystem($this->template_dir);
|
||||
$this->object = new Twig_Environment($loader);
|
||||
$lexer = new Twig_Lexer($this->object, array(
|
||||
'tag_comment' => array('{*', '*}'),
|
||||
'tag_block' => array('{', '}'),
|
||||
'tag_variable' => array('{$', '}'),
|
||||
));
|
||||
$this->object->setLexer($lexer);
|
||||
}
|
||||
}
|
||||
|
||||
public function assign($key, $value) {
|
||||
if ($this->engine === 'smarty') {
|
||||
$this->object->assign($key, $value);
|
||||
}
|
||||
if ($this->engine === 'raintpl') {
|
||||
$this->object->assign($key, $value);
|
||||
}
|
||||
if ($this->engine === 'twig') {
|
||||
$this->var_array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function render($name) {
|
||||
if ($this->engine === 'smarty') {
|
||||
return $this->object->fetch($name);
|
||||
}
|
||||
if ($this->engine === 'raintpl') {
|
||||
return $this->object-> draw($name, 'return_string=true');
|
||||
}
|
||||
if ($this->engine === 'twig') {
|
||||
return $this->object->render($name,$this->var_array);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Initializes the template engine based on the selected engine.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function init() {
|
||||
if ($this->engine === 'smarty') {
|
||||
require_once "resources/templates/engine/smarty/Smarty.class.php";
|
||||
$this->object = new Smarty();
|
||||
$this->object->setTemplateDir($this->template_dir);
|
||||
$this->object->setCompileDir($this->cache_dir);
|
||||
$this->object->setCacheDir($this->cache_dir);
|
||||
$this->object->registerPlugin("modifier", "in_array", "in_array");
|
||||
}
|
||||
if ($this->engine === 'raintpl') {
|
||||
require_once "resources/templates/engine/raintpl/rain.tpl.class.php";
|
||||
$this->object = new RainTPL();
|
||||
RainTPL::configure('tpl_dir', realpath($this->template_dir) . "/");
|
||||
RainTPL::configure('cache_dir', realpath($this->cache_dir) . "/");
|
||||
}
|
||||
if ($this->engine === 'twig') {
|
||||
require_once "resources/templates/engine/Twig/Autoloader.php";
|
||||
Twig_Autoloader::register();
|
||||
$loader = new Twig_Loader_Filesystem($this->template_dir);
|
||||
$this->object = new Twig_Environment($loader);
|
||||
$lexer = new Twig_Lexer($this->object, [
|
||||
'tag_comment' => ['{*', '*}'],
|
||||
'tag_block' => ['{', '}'],
|
||||
'tag_variable' => ['{$', '}'],
|
||||
]);
|
||||
$this->object->setLexer($lexer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the template engine based on the selected engine.
|
||||
*
|
||||
* @param string $key The key for the assigned value.
|
||||
* @param mixed $value The value to be assigned.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function assign($key, $value) {
|
||||
if ($this->engine === 'smarty') {
|
||||
$this->object->assign($key, $value);
|
||||
}
|
||||
if ($this->engine === 'raintpl') {
|
||||
$this->object->assign($key, $value);
|
||||
}
|
||||
if ($this->engine === 'twig') {
|
||||
$this->var_array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given template using the configured engine.
|
||||
*
|
||||
* @param string $name Name of the template to render. Values can be 'smarty', 'raintpl' or 'twig' (case sensitive)
|
||||
*
|
||||
* @return mixed The rendered template output, depending on the used engine
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function render($name) {
|
||||
if ($this->engine === 'smarty') {
|
||||
return $this->object->fetch($name);
|
||||
}
|
||||
if ($this->engine === 'raintpl') {
|
||||
return $this->object->draw($name, 'return_string=true');
|
||||
}
|
||||
if ($this->engine === 'twig') {
|
||||
return $this->object->render($name, $this->var_array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,17 +6,24 @@
|
||||
*/
|
||||
class text implements clear_cache {
|
||||
|
||||
/**
|
||||
* Translated flattened text array using the file path as key
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $tanslated;
|
||||
/**
|
||||
* Contains the list of supported languages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $languages;
|
||||
|
||||
/**
|
||||
* Legacy older list of supported languages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $legacy_map = array(
|
||||
public $legacy_map = [
|
||||
'he' => 'he-il',
|
||||
'pl' => 'pl-pl',
|
||||
'uk' => 'uk-ua',
|
||||
@@ -30,439 +37,94 @@ class text implements clear_cache {
|
||||
'es' => 'es-cl',
|
||||
'fr' => 'fr-fr',
|
||||
'pt' => 'pt-pt',
|
||||
);
|
||||
|
||||
];
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the session global array
|
||||
*
|
||||
* @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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
|
||||
/**
|
||||
* Translated flattened text array using the file path as key
|
||||
* @var array
|
||||
*/
|
||||
private static $tanslated;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $apcu_enabled;
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
* Constructor for the class.
|
||||
*
|
||||
* This method initializes the object with setting_array and session data.
|
||||
*
|
||||
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||
*/
|
||||
public function __construct($setting_array = []) {
|
||||
//define the text array
|
||||
$text = array();
|
||||
$text = [];
|
||||
|
||||
//check for apcu caching
|
||||
$this->apcu_enabled = function_exists('apcu_enabled') && apcu_enabled();
|
||||
$this->apcu_enabled = function_exists('apcu_enabled') && apcu_enabled();
|
||||
|
||||
//set the domain and user uuids
|
||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
|
||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||
$this->user_uuid = $setting_array['user_uuid'] ?? $_SESSION['user_uuid'] ?? '';
|
||||
|
||||
//open a database connection
|
||||
if (empty($setting_array['database'])) {
|
||||
$this->database = database::new();
|
||||
} else {
|
||||
$this->database = $setting_array['database'];
|
||||
}
|
||||
if (empty($setting_array['database'])) {
|
||||
$this->database = database::new();
|
||||
} else {
|
||||
$this->database = $setting_array['database'];
|
||||
}
|
||||
|
||||
//load the settings
|
||||
if (empty($setting_array['settings'])) {
|
||||
$this->settings = new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
|
||||
} else {
|
||||
$this->settings = $setting_array['settings'];
|
||||
}
|
||||
if (empty($setting_array['settings'])) {
|
||||
$this->settings = new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
|
||||
} else {
|
||||
$this->settings = $setting_array['settings'];
|
||||
}
|
||||
|
||||
//get the global app_languages.php so we can get the list of languages
|
||||
if (file_exists($_SERVER["PROJECT_ROOT"]."/resources/app_languages.php")) {
|
||||
include $_SERVER["PROJECT_ROOT"]."/resources/app_languages.php";
|
||||
}
|
||||
if (file_exists($_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php")) {
|
||||
include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
|
||||
}
|
||||
|
||||
//get the list of languages, remove en-us, sort it then put en-us in front
|
||||
unset($text['language-name']['en-us']);
|
||||
if (is_array($text['language-name'])) {
|
||||
$languages = array_keys($text['language-name']);
|
||||
asort($languages);
|
||||
array_unshift($languages, 'en-us');
|
||||
}
|
||||
|
||||
//support legacy variable
|
||||
if (is_array($languages)) {
|
||||
$_SESSION['app']['languages'] = $languages;
|
||||
$this->languages = $languages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific language from the language file
|
||||
* @param string|null $language_code examples: en-us, es-cl, fr-fr, pt-pt
|
||||
* @param string|null $app_path examples: app/exec or core/domains
|
||||
* @param bool $exclude_global Exclude the global languages file
|
||||
*
|
||||
* @return array A flattened array containing the desired language
|
||||
*/
|
||||
public function get(?string $language_code = null, ?string $app_path = null, bool $exclude_global = false) {
|
||||
|
||||
//define the text array
|
||||
$text = [];
|
||||
|
||||
//check the session language
|
||||
if ($language_code == null) {
|
||||
$language_code = $this->settings->get('domain', 'language', 'en-us');
|
||||
}
|
||||
|
||||
//check the language code
|
||||
if (strlen($language_code) == 2 && array_key_exists($language_code, $this->legacy_map)) {
|
||||
$language_code = $this->legacy_map[$language_code];
|
||||
}
|
||||
|
||||
//get the app_languages.php
|
||||
if ($app_path != null) {
|
||||
$lang_path = $_SERVER["PROJECT_ROOT"]."/".$app_path;
|
||||
}
|
||||
else {
|
||||
$lang_path = getcwd();
|
||||
}
|
||||
|
||||
//check the class cache
|
||||
$cache_key = "text_{$language_code}_{$lang_path}";
|
||||
if ($this->apcu_enabled && apcu_exists($cache_key)) {
|
||||
return apcu_fetch($cache_key);
|
||||
|
||||
}
|
||||
if (isset(self::$tanslated[$cache_key])) {
|
||||
return self::$tanslated[$cache_key];
|
||||
}
|
||||
|
||||
//get the global app_languages.php
|
||||
if (!$exclude_global && file_exists($_SERVER["PROJECT_ROOT"]."/resources/app_languages.php")) {
|
||||
require $_SERVER["PROJECT_ROOT"]."/resources/app_languages.php";
|
||||
}
|
||||
|
||||
if (file_exists($lang_path."/app_languages.php") && ($lang_path != 'resources' or $exclude_global)) {
|
||||
include "{$lang_path}/app_languages.php";
|
||||
}
|
||||
//else {
|
||||
// throw new Exception("could not find app_languages for '$app_path'");
|
||||
//}
|
||||
|
||||
//reduce to specific language
|
||||
if ($language_code != 'all' && is_array($text)) {
|
||||
foreach ($text as $key => $value) {
|
||||
if (isset($value[$language_code]) && !empty($value[$language_code])) {
|
||||
//use the selected language
|
||||
$text[$key] = $value[$language_code];
|
||||
} elseif (isset($value['en-us'])) {
|
||||
//fallback to en-us
|
||||
$text[$key] = $value['en-us'];
|
||||
} else {
|
||||
$text[$key] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//cache the reduced language using the file as a key
|
||||
if ($this->apcu_enabled) {
|
||||
apcu_store($cache_key, $text);
|
||||
} else {
|
||||
self::$tanslated[$cache_key] = $text;
|
||||
}
|
||||
|
||||
//return the array of translations
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* reorganize an app_languages.php into a consistent format
|
||||
* @var string $app_path examples: app/exec or core/domains
|
||||
* @var string $no_sort don't sort the text label order
|
||||
*/
|
||||
public function organize_language($app_path = null, $no_sort = false) {
|
||||
|
||||
//clear $text ready for the import
|
||||
$text = array();
|
||||
|
||||
//get the app_languages.php
|
||||
if ($app_path == null) {
|
||||
throw new Exception("\$app_path must be specified");
|
||||
}
|
||||
$lang_path = $_SERVER["PROJECT_ROOT"]."/$app_path/app_languages.php";
|
||||
if (!file_exists($lang_path)) {
|
||||
throw new Exception("could not find app_languages for '$app_path'");
|
||||
}
|
||||
require $lang_path;
|
||||
|
||||
if (!is_array($text)) {
|
||||
throw new Exception("failed to import text data from '$app_path'");
|
||||
}
|
||||
|
||||
//collect existing comments
|
||||
$comment = array();
|
||||
$file_handle = fopen($lang_path, "r");
|
||||
while (!feof($file_handle)) {
|
||||
if(preg_match('/\$text\[[\'"](.+)[\'"]\]\[[\'"](.+)[\'"]]\s+=\s+[\'"].*[\'"];\s+\/\/(.+)/', fgets($file_handle), $matches)){
|
||||
$comment[$matches[0]][$matches[1]] = $matches[2];
|
||||
}
|
||||
}
|
||||
fclose($file_handle);
|
||||
|
||||
//open the language file for writing
|
||||
$lang_file = fopen($lang_path, 'w');
|
||||
date_default_timezone_set('UTC');
|
||||
fwrite($lang_file, "<?php\n#This file was last reorganized on " . date("jS \of F Y h:i:s A e") . "\n");
|
||||
if (!$no_sort) {
|
||||
if ($app_path == 'resources') {
|
||||
$temp_A['language-name'] = $text['language-name'];
|
||||
unset($text['language-name']);
|
||||
foreach($this->languages as $language) {
|
||||
$temp_B["language-$language"] = $text["language-$language"];
|
||||
unset($text["language-$language"]);
|
||||
}
|
||||
$temp_C["language-en-us"] = $temp_B["language-en-us"];
|
||||
unset($temp_B["language-en-us"]);
|
||||
ksort($temp_B);
|
||||
$temp_B = array_merge($temp_C, $temp_B);
|
||||
ksort($text);
|
||||
$text = array_merge($temp_A, $temp_B, $text);
|
||||
unset($temp_A, $temp_B, $temp_C);
|
||||
}
|
||||
else {
|
||||
ksort($text);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($app_path == 'resources') {
|
||||
foreach($this->languages as $language) {
|
||||
$label = array_shift($text["language-$language"]);
|
||||
if (empty($label))
|
||||
$label = $language;
|
||||
$text["language-$language"]['en-us'] = $label;
|
||||
}
|
||||
}
|
||||
}
|
||||
$last_lang_label = "";
|
||||
foreach ($text as $lang_label => $lang_codes) {
|
||||
|
||||
//behave differently if we are one of the special language-* tags
|
||||
if (preg_match('/\Alanguage-(\w{2}|\w{2}-\w{2})\z/', $lang_label, $lang_code)) {
|
||||
if ($lang_label == 'language-en-us')
|
||||
fwrite($lang_file, "\n");
|
||||
$target_lang = $lang_code[1];
|
||||
if (strlen($target_lang) == 2) {
|
||||
if (array_key_exists($target_lang, $this->legacy_map)) {
|
||||
$target_lang = $this->legacy_map[$target_lang];
|
||||
}
|
||||
}
|
||||
$spacer = "";
|
||||
if (strlen($target_lang) == 11)
|
||||
$spacer = " ";
|
||||
$language_name = $this->escape_str(array_shift($text[$lang_label]));
|
||||
if (empty($language_name))
|
||||
$language_name = $this->escape_str($target_lang);
|
||||
fwrite($lang_file, "\$text['language-$target_lang'$spacer]['en-us'] = \"$language_name\";\n");
|
||||
}
|
||||
else {
|
||||
|
||||
//put a line break in between the last tag if it has changed
|
||||
if ($last_lang_label != $lang_label)
|
||||
fwrite($lang_file, "\n");
|
||||
foreach ($this->languages as $lang_code) {
|
||||
$value = "";
|
||||
$append = "";
|
||||
$spacer = "";
|
||||
$target_lang = $lang_code;
|
||||
if (strlen($lang_code) == 2) {
|
||||
if (array_key_exists($lang_code, $this->legacy_map)) {
|
||||
$target_lang = $this->legacy_map[$lang_code];
|
||||
}
|
||||
}
|
||||
if (strlen($target_lang) == 2)
|
||||
$spacer = " ";
|
||||
if (array_key_exists($lang_code, $text[$lang_label]))
|
||||
$value = $text[$lang_label][$lang_code];
|
||||
if (empty($value) and array_key_exists($target_lang, $this->legacy_map)) {
|
||||
$value = $text[$lang_label][$this->legacy_map[$target_lang]];
|
||||
}
|
||||
$base_code = substr($target_lang, 0, 2);
|
||||
if (!empty($value)
|
||||
and array_key_exists($base_code, $this->legacy_map )
|
||||
and $this->legacy_map[$base_code] != $target_lang
|
||||
and $value == $text[$lang_label][$this->legacy_map[$base_code]]
|
||||
) {
|
||||
$append = " //copied from ".$this->legacy_map[$base_code];
|
||||
}
|
||||
if (empty($value)) {
|
||||
foreach($this->languages as $lang_code) {
|
||||
if (substr($lang_code, 0, 2) == $base_code and !empty($text[$lang_label][$lang_code])) {
|
||||
$value = $text[$lang_label][$lang_code];
|
||||
$append = " //copied from $lang_code";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(empty($append) && array_key_exists($comment[$lang_label], $lang_code)) {
|
||||
$append = " //$comment[$lang_label][$lang_code]";
|
||||
}
|
||||
fwrite($lang_file, "\$text['$lang_label']['$target_lang'$spacer] = \"".$this->escape_str($value)."\";$append\n");
|
||||
}
|
||||
}
|
||||
$last_lang_label = $lang_label;
|
||||
}
|
||||
|
||||
//close the language file
|
||||
fwrite($lang_file, "\n?>\n");
|
||||
fclose($lang_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect all languages from the application and session language settings.
|
||||
*
|
||||
* @param bool $no_sort Flag to prevent sorting of detected languages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function detect_all_languages($no_sort = false) {
|
||||
|
||||
//clear $text ready for the import
|
||||
$text = array();
|
||||
$languages = array();
|
||||
|
||||
//retrieve all the languages
|
||||
$files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
|
||||
foreach($files as $file) {
|
||||
include $file;
|
||||
}
|
||||
include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
|
||||
|
||||
//check every tag
|
||||
foreach($text as $lang_codes) {
|
||||
foreach($lang_codes as $language_code => $value) {
|
||||
if (strlen($language_code) == 2) {
|
||||
if (array_key_exists($language_code, $this->legacy_map)) {
|
||||
$language_code = $this->legacy_map[$language_code];
|
||||
}
|
||||
}
|
||||
$languages[$language_code] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//set $this->languages up according to what we found
|
||||
unset($languages['en-us']);
|
||||
$languages = array_keys($languages);
|
||||
unset($text['language-name']['en-us']);
|
||||
if (is_array($text['language-name'])) {
|
||||
$languages = array_keys($text['language-name']);
|
||||
asort($languages);
|
||||
array_unshift($languages, 'en-us');
|
||||
}
|
||||
|
||||
//support legacy variable
|
||||
if (is_array($languages)) {
|
||||
$_SESSION['app']['languages'] = $languages;
|
||||
$this->languages = $languages;
|
||||
|
||||
//rewrite resources/app_languges
|
||||
$this->organize_language('resources', $no_sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get totals of language usage across all languages and applications.
|
||||
*
|
||||
* This method retrieves the total number of translations, menu items,
|
||||
* and application descriptions for each language, as well as a total count
|
||||
* for each category.
|
||||
*
|
||||
* @return array A nested array containing the total counts for languages, menu items, and app descriptions
|
||||
*/
|
||||
public function language_totals() {
|
||||
|
||||
//setup variables
|
||||
$language_totals = array();
|
||||
$language_totals['languages']['total'] = 0;
|
||||
$language_totals['menu_items']['total'] = 0;
|
||||
$language_totals['app_descriptions']['total'] = 0;
|
||||
foreach ($this->languages as $language_code) {
|
||||
$language_totals[$language_code] = 0;
|
||||
}
|
||||
|
||||
//retrieve all the languages
|
||||
$text = array();
|
||||
$files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
|
||||
foreach($files as $file) {
|
||||
include $file;
|
||||
}
|
||||
include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
|
||||
|
||||
//check every tag
|
||||
foreach($text as $label_name => $values) {
|
||||
$language_totals['languages']['total']++;
|
||||
foreach ($this->languages as $language_code) {
|
||||
if (!empty($values[$language_code]))
|
||||
$language_totals['languages'][$language_code]++;
|
||||
}
|
||||
}
|
||||
unset($text);
|
||||
|
||||
//retrieve all the menus
|
||||
$x = 0;
|
||||
$files = glob($_SERVER["PROJECT_ROOT"] . "/*/*");
|
||||
foreach($files as $file) {
|
||||
if (file_exists($file . "/app_menu.php"))
|
||||
include $file . "/app_menu.php";
|
||||
if (file_exists($file . "/app_config.php"))
|
||||
include $file . "/app_config.php";
|
||||
$x++;
|
||||
}
|
||||
|
||||
//check every tag
|
||||
foreach ($apps as $app) {
|
||||
$language_totals['app_descriptions']['total']++;
|
||||
foreach($app['menu'] as $menu_item) {
|
||||
$language_totals['menu_items']['total']++;
|
||||
foreach ($this->languages as $language_code) {
|
||||
if (!empty($menu_item['title'][$language_code]))
|
||||
$language_totals['menu_items'][$language_code]++;
|
||||
}
|
||||
}
|
||||
foreach ($this->languages as $language_code) {
|
||||
if (!empty($app['description'][$language_code])) {
|
||||
$language_totals['app_descriptions'][$language_code]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $language_totals;
|
||||
}
|
||||
|
||||
private function escape_str($string = '') {
|
||||
//perform initial escape
|
||||
$string = addslashes(stripslashes($string));
|
||||
//swap \' as we don't need to escape those
|
||||
return preg_replace("/\\\'/", "'", $string);
|
||||
//escape " as we write our strings double quoted
|
||||
return preg_replace("/\"/", '\"', $string);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The clear_cache method is called automatically for any class that implements the clear_cache interface.
|
||||
* The function declared here ensures that all clear_cache methods have the same number of parameters being passed, which in this case, is no parameters.
|
||||
* The function declared here ensures that all clear_cache methods have the same number of parameters being passed,
|
||||
* which in this case, are no parameters.
|
||||
*/
|
||||
public static function clear_cache() {
|
||||
//check for apcu extension and if is enabled
|
||||
@@ -485,4 +147,356 @@ class text implements clear_cache {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific language from the language file
|
||||
*
|
||||
* @param string|null $language_code examples: en-us, es-cl, fr-fr, pt-pt
|
||||
* @param string|null $app_path examples: app/exec or core/domains
|
||||
* @param bool $exclude_global Exclude the global languages file
|
||||
*
|
||||
* @return array A flattened array containing the desired language
|
||||
*/
|
||||
public function get(?string $language_code = null, ?string $app_path = null, bool $exclude_global = false) {
|
||||
|
||||
//define the text array
|
||||
$text = [];
|
||||
|
||||
//check the session language
|
||||
if ($language_code == null) {
|
||||
$language_code = $this->settings->get('domain', 'language', 'en-us');
|
||||
}
|
||||
|
||||
//check the language code
|
||||
if (strlen($language_code) == 2 && array_key_exists($language_code, $this->legacy_map)) {
|
||||
$language_code = $this->legacy_map[$language_code];
|
||||
}
|
||||
|
||||
//get the app_languages.php
|
||||
if ($app_path != null) {
|
||||
$lang_path = $_SERVER["PROJECT_ROOT"] . "/" . $app_path;
|
||||
} else {
|
||||
$lang_path = getcwd();
|
||||
}
|
||||
|
||||
//check the class cache
|
||||
$cache_key = "text_{$language_code}_{$lang_path}";
|
||||
if ($this->apcu_enabled && apcu_exists($cache_key)) {
|
||||
return apcu_fetch($cache_key);
|
||||
|
||||
}
|
||||
if (isset(self::$tanslated[$cache_key])) {
|
||||
return self::$tanslated[$cache_key];
|
||||
}
|
||||
|
||||
//get the global app_languages.php
|
||||
if (!$exclude_global && file_exists($_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php")) {
|
||||
require $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
|
||||
}
|
||||
|
||||
if (file_exists($lang_path . "/app_languages.php") && ($lang_path != 'resources' or $exclude_global)) {
|
||||
include "{$lang_path}/app_languages.php";
|
||||
}
|
||||
//else {
|
||||
// throw new Exception("could not find app_languages for '$app_path'");
|
||||
//}
|
||||
|
||||
//reduce to specific language
|
||||
if ($language_code != 'all' && is_array($text)) {
|
||||
foreach ($text as $key => $value) {
|
||||
if (isset($value[$language_code]) && !empty($value[$language_code])) {
|
||||
//use the selected language
|
||||
$text[$key] = $value[$language_code];
|
||||
} elseif (isset($value['en-us'])) {
|
||||
//fallback to en-us
|
||||
$text[$key] = $value['en-us'];
|
||||
} else {
|
||||
$text[$key] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//cache the reduced language using the file as a key
|
||||
if ($this->apcu_enabled) {
|
||||
apcu_store($cache_key, $text);
|
||||
} else {
|
||||
self::$tanslated[$cache_key] = $text;
|
||||
}
|
||||
|
||||
//return the array of translations
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect all languages from the application and session language settings.
|
||||
*
|
||||
* @param bool $no_sort Flag to prevent sorting of detected languages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function detect_all_languages($no_sort = false) {
|
||||
|
||||
//clear $text ready for the import
|
||||
$text = [];
|
||||
$languages = [];
|
||||
|
||||
//retrieve all the languages
|
||||
$files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
|
||||
foreach ($files as $file) {
|
||||
include $file;
|
||||
}
|
||||
include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
|
||||
|
||||
//check every tag
|
||||
foreach ($text as $lang_codes) {
|
||||
foreach ($lang_codes as $language_code => $value) {
|
||||
if (strlen($language_code) == 2) {
|
||||
if (array_key_exists($language_code, $this->legacy_map)) {
|
||||
$language_code = $this->legacy_map[$language_code];
|
||||
}
|
||||
}
|
||||
$languages[$language_code] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//set $this->languages up according to what we found
|
||||
unset($languages['en-us']);
|
||||
$languages = array_keys($languages);
|
||||
asort($languages);
|
||||
array_unshift($languages, 'en-us');
|
||||
|
||||
//support legacy variable
|
||||
$_SESSION['app']['languages'] = $languages;
|
||||
$this->languages = $languages;
|
||||
|
||||
//rewrite resources/app_languges
|
||||
$this->organize_language('resources', $no_sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Organize a specific language from the language file.
|
||||
*
|
||||
* @param string $app_path Path to the application where the language file is located.
|
||||
* @param bool $no_sort Flag to determine if the text should be sorted or not.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function organize_language($app_path = null, $no_sort = false) {
|
||||
|
||||
//clear $text ready for the import
|
||||
$text = [];
|
||||
|
||||
//get the app_languages.php
|
||||
if ($app_path == null) {
|
||||
throw new Exception("\$app_path must be specified");
|
||||
}
|
||||
$lang_path = $_SERVER["PROJECT_ROOT"] . "/$app_path/app_languages.php";
|
||||
if (!file_exists($lang_path)) {
|
||||
throw new Exception("could not find app_languages for '$app_path'");
|
||||
}
|
||||
require $lang_path;
|
||||
|
||||
if (!is_array($text)) {
|
||||
throw new Exception("failed to import text data from '$app_path'");
|
||||
}
|
||||
|
||||
//collect existing comments
|
||||
$comment = [];
|
||||
$file_handle = fopen($lang_path, "r");
|
||||
while (!feof($file_handle)) {
|
||||
if (preg_match('/\$text\[[\'"](.+)[\'"]\]\[[\'"](.+)[\'"]]\s+=\s+[\'"].*[\'"];\s+\/\/(.+)/', fgets($file_handle), $matches)) {
|
||||
$comment[$matches[0]][$matches[1]] = $matches[2];
|
||||
}
|
||||
}
|
||||
fclose($file_handle);
|
||||
|
||||
//open the language file for writing
|
||||
$lang_file = fopen($lang_path, 'w');
|
||||
date_default_timezone_set('UTC');
|
||||
fwrite($lang_file, "<?php\n#This file was last reorganized on " . date("jS \of F Y h:i:s A e") . "\n");
|
||||
if (!$no_sort) {
|
||||
if ($app_path == 'resources') {
|
||||
$temp_A['language-name'] = $text['language-name'];
|
||||
unset($text['language-name']);
|
||||
foreach ($this->languages as $language) {
|
||||
$temp_B["language-$language"] = $text["language-$language"];
|
||||
unset($text["language-$language"]);
|
||||
}
|
||||
$temp_C["language-en-us"] = $temp_B["language-en-us"];
|
||||
unset($temp_B["language-en-us"]);
|
||||
ksort($temp_B);
|
||||
$temp_B = array_merge($temp_C, $temp_B);
|
||||
ksort($text);
|
||||
$text = array_merge($temp_A, $temp_B, $text);
|
||||
unset($temp_A, $temp_B, $temp_C);
|
||||
} else {
|
||||
ksort($text);
|
||||
}
|
||||
} else {
|
||||
if ($app_path == 'resources') {
|
||||
foreach ($this->languages as $language) {
|
||||
$label = array_shift($text["language-$language"]);
|
||||
if (empty($label))
|
||||
$label = $language;
|
||||
$text["language-$language"]['en-us'] = $label;
|
||||
}
|
||||
}
|
||||
}
|
||||
$last_lang_label = "";
|
||||
foreach ($text as $lang_label => $lang_codes) {
|
||||
|
||||
//behave differently if we are one of the special language-* tags
|
||||
if (preg_match('/\Alanguage-(\w{2}|\w{2}-\w{2})\z/', $lang_label, $lang_code)) {
|
||||
if ($lang_label == 'language-en-us')
|
||||
fwrite($lang_file, "\n");
|
||||
$target_lang = $lang_code[1];
|
||||
if (strlen($target_lang) == 2) {
|
||||
if (array_key_exists($target_lang, $this->legacy_map)) {
|
||||
$target_lang = $this->legacy_map[$target_lang];
|
||||
}
|
||||
}
|
||||
$spacer = "";
|
||||
if (strlen($target_lang) == 11)
|
||||
$spacer = " ";
|
||||
$language_name = $this->escape_str(array_shift($text[$lang_label]));
|
||||
if (empty($language_name))
|
||||
$language_name = $this->escape_str($target_lang);
|
||||
fwrite($lang_file, "\$text['language-$target_lang'$spacer]['en-us'] = \"$language_name\";\n");
|
||||
} else {
|
||||
|
||||
//put a line break in between the last tag if it has changed
|
||||
if ($last_lang_label != $lang_label)
|
||||
fwrite($lang_file, "\n");
|
||||
foreach ($this->languages as $lang_code) {
|
||||
$value = "";
|
||||
$append = "";
|
||||
$spacer = "";
|
||||
$target_lang = $lang_code;
|
||||
if (strlen($lang_code) == 2) {
|
||||
if (array_key_exists($lang_code, $this->legacy_map)) {
|
||||
$target_lang = $this->legacy_map[$lang_code];
|
||||
}
|
||||
}
|
||||
if (strlen($target_lang) == 2)
|
||||
$spacer = " ";
|
||||
if (array_key_exists($lang_code, $text[$lang_label]))
|
||||
$value = $text[$lang_label][$lang_code];
|
||||
if (empty($value) and array_key_exists($target_lang, $this->legacy_map)) {
|
||||
$value = $text[$lang_label][$this->legacy_map[$target_lang]];
|
||||
}
|
||||
$base_code = substr($target_lang, 0, 2);
|
||||
if (!empty($value)
|
||||
and array_key_exists($base_code, $this->legacy_map)
|
||||
and $this->legacy_map[$base_code] != $target_lang
|
||||
and $value == $text[$lang_label][$this->legacy_map[$base_code]]
|
||||
) {
|
||||
$append = " //copied from " . $this->legacy_map[$base_code];
|
||||
}
|
||||
if (empty($value)) {
|
||||
foreach ($this->languages as $lang_code) {
|
||||
if (substr($lang_code, 0, 2) == $base_code and !empty($text[$lang_label][$lang_code])) {
|
||||
$value = $text[$lang_label][$lang_code];
|
||||
$append = " //copied from $lang_code";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($append) && array_key_exists($comment[$lang_label], $lang_code)) {
|
||||
$append = " //$comment[$lang_label][$lang_code]";
|
||||
}
|
||||
fwrite($lang_file, "\$text['$lang_label']['$target_lang'$spacer] = \"" . $this->escape_str($value) . "\";$append\n");
|
||||
}
|
||||
}
|
||||
$last_lang_label = $lang_label;
|
||||
}
|
||||
|
||||
//close the language file
|
||||
fwrite($lang_file, "\n?>\n");
|
||||
fclose($lang_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes special characters in a string for use in a SQL query.
|
||||
*
|
||||
* @param string $string The input string to be escaped. Defaults to an empty string if not provided.
|
||||
*
|
||||
* @return string The escaped string.
|
||||
*/
|
||||
private function escape_str($string = '') {
|
||||
//perform initial escape
|
||||
$string = addslashes(stripslashes($string));
|
||||
//swap \' as we don't need to escape those
|
||||
return preg_replace("/\\\'/", "'", $string);
|
||||
//escape " as we write our strings double quoted
|
||||
return preg_replace("/\"/", '\"', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get totals of language usage across all languages and applications.
|
||||
*
|
||||
* This method retrieves the total number of translations, menu items,
|
||||
* and application descriptions for each language, as well as a total count
|
||||
* for each category.
|
||||
*
|
||||
* @return array A nested array containing the total counts for languages, menu items, and app descriptions
|
||||
*/
|
||||
public function language_totals() {
|
||||
|
||||
//setup variables
|
||||
$language_totals = [];
|
||||
$language_totals['languages']['total'] = 0;
|
||||
$language_totals['menu_items']['total'] = 0;
|
||||
$language_totals['app_descriptions']['total'] = 0;
|
||||
foreach ($this->languages as $language_code) {
|
||||
$language_totals[$language_code] = 0;
|
||||
}
|
||||
|
||||
//retrieve all the languages
|
||||
$text = [];
|
||||
$files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
|
||||
foreach ($files as $file) {
|
||||
include $file;
|
||||
}
|
||||
include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
|
||||
|
||||
//check every tag
|
||||
foreach ($text as $label_name => $values) {
|
||||
$language_totals['languages']['total']++;
|
||||
foreach ($this->languages as $language_code) {
|
||||
if (!empty($values[$language_code]))
|
||||
$language_totals['languages'][$language_code]++;
|
||||
}
|
||||
}
|
||||
unset($text);
|
||||
|
||||
//retrieve all the menus
|
||||
$x = 0;
|
||||
$files = glob($_SERVER["PROJECT_ROOT"] . "/*/*");
|
||||
foreach ($files as $file) {
|
||||
if (file_exists($file . "/app_menu.php"))
|
||||
include $file . "/app_menu.php";
|
||||
if (file_exists($file . "/app_config.php"))
|
||||
include $file . "/app_config.php";
|
||||
$x++;
|
||||
}
|
||||
|
||||
//check every tag
|
||||
foreach ($apps as $app) {
|
||||
$language_totals['app_descriptions']['total']++;
|
||||
foreach ($app['menu'] as $menu_item) {
|
||||
$language_totals['menu_items']['total']++;
|
||||
foreach ($this->languages as $language_code) {
|
||||
if (!empty($menu_item['title'][$language_code]))
|
||||
$language_totals['menu_items'][$language_code]++;
|
||||
}
|
||||
}
|
||||
foreach ($this->languages as $language_code) {
|
||||
if (!empty($app['description'][$language_code])) {
|
||||
$language_totals['app_descriptions'][$language_code]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $language_totals;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,78 +32,42 @@
|
||||
class token {
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
*/
|
||||
* Called when the object is created
|
||||
*/
|
||||
//public $code;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the token
|
||||
*
|
||||
* @var string $key
|
||||
*/
|
||||
public function create($key) {
|
||||
|
||||
//clear previously validated tokens
|
||||
$this->clear_validated();
|
||||
$this->clear_validated();
|
||||
|
||||
//allow only specific characters
|
||||
$key = preg_replace('[^a-zA-Z0-9\-_@.\/]', '', $key);
|
||||
$key = preg_replace('[^a-zA-Z0-9\-_@.\/]', '', $key);
|
||||
|
||||
//create a token for the key submitted
|
||||
$token = [
|
||||
'name'=>hash_hmac('sha256', $key, bin2hex(random_bytes(32))),
|
||||
'hash'=>hash_hmac('sha256', $key, bin2hex(random_bytes(32))),
|
||||
'validated'=>false
|
||||
];
|
||||
$token = [
|
||||
'name' => hash_hmac('sha256', $key, bin2hex(random_bytes(32))),
|
||||
'hash' => hash_hmac('sha256', $key, bin2hex(random_bytes(32))),
|
||||
'validated' => false,
|
||||
];
|
||||
|
||||
//save in the token session array
|
||||
$_SESSION['tokens'][$key][] = $token;
|
||||
$_SESSION['tokens'][$key][] = $token;
|
||||
|
||||
//send the hash
|
||||
return $token;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* validate the token
|
||||
* @var string $key
|
||||
* @var string $value
|
||||
*/
|
||||
public function validate($key, $value = '') {
|
||||
|
||||
//allow only specific characters
|
||||
$key = preg_replace('[^a-zA-Z0-9]', '', $key);
|
||||
|
||||
//get the token name
|
||||
if (!empty($_SESSION['tokens']) && is_array($_SESSION['tokens'][$key]) && @sizeof($_SESSION['tokens'][$key]) != 0) {
|
||||
foreach ($_SESSION['tokens'][$key] as $t => $token) {
|
||||
$token_name = $token['name'];
|
||||
if (isset($_REQUEST[$token_name])) {
|
||||
$value = $_REQUEST[$token_name];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//limit the value to specific characters
|
||||
$value = preg_replace('[^a-zA-Z0-9]', '', $value);
|
||||
|
||||
//compare the hashed tokens
|
||||
if (!empty($_SESSION['tokens']) && is_array($_SESSION['tokens'][$key]) && @sizeof($_SESSION['tokens'][$key]) != 0) {
|
||||
foreach ($_SESSION['tokens'][$key] as $t => $token) {
|
||||
if (hash_equals($token['hash'], $value)) {
|
||||
$_SESSION['tokens'][$key][$t]['validated'] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return $token;
|
||||
|
||||
}
|
||||
|
||||
@@ -124,6 +88,44 @@ class token {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validate the token
|
||||
*
|
||||
* @var string $key
|
||||
* @var string $value
|
||||
*/
|
||||
public function validate($key, $value = '') {
|
||||
|
||||
//allow only specific characters
|
||||
$key = preg_replace('[^a-zA-Z0-9]', '', $key);
|
||||
|
||||
//get the token name
|
||||
if (!empty($_SESSION['tokens']) && is_array($_SESSION['tokens'][$key]) && @sizeof($_SESSION['tokens'][$key]) != 0) {
|
||||
foreach ($_SESSION['tokens'][$key] as $t => $token) {
|
||||
$token_name = $token['name'];
|
||||
if (isset($_REQUEST[$token_name])) {
|
||||
$value = $_REQUEST[$token_name];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//limit the value to specific characters
|
||||
$value = preg_replace('[^a-zA-Z0-9]', '', $value);
|
||||
|
||||
//compare the hashed tokens
|
||||
if (!empty($_SESSION['tokens']) && is_array($_SESSION['tokens'][$key]) && @sizeof($_SESSION['tokens'][$key]) != 0) {
|
||||
foreach ($_SESSION['tokens'][$key] as $t => $token) {
|
||||
if (hash_equals($token['hash'], $value)) {
|
||||
$_SESSION['tokens'][$key][$t]['validated'] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -147,5 +149,3 @@ echo " <input type='hidden' name='".$token['name']."' value='".$token['hash'].
|
||||
//note: can use $_SERVER['PHP_SELF'] instead of actual file path
|
||||
|
||||
*/
|
||||
|
||||
?>
|
||||
@@ -25,54 +25,60 @@
|
||||
Matthew Vale <github@mafoo.org>
|
||||
*/
|
||||
|
||||
class tones {
|
||||
class tones {
|
||||
|
||||
/**
|
||||
* declare private variables
|
||||
*/
|
||||
private $music_list;
|
||||
private $recordings_list;
|
||||
private $default_tone_label;
|
||||
private $database;
|
||||
/**
|
||||
* declare private variables
|
||||
*/
|
||||
private $music_list;
|
||||
private $recordings_list;
|
||||
private $default_tone_label;
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
*/
|
||||
public function __construct(array $setting_array = []) {
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
$text = $language->get();
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*
|
||||
* This method initializes the object with setting_array and session data.
|
||||
*
|
||||
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||
*/
|
||||
public function __construct(array $setting_array = []) {
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
$text = $language->get();
|
||||
|
||||
//connect to the database
|
||||
$this->database = $setting_array['database'] ?? database::new();
|
||||
}
|
||||
|
||||
/**
|
||||
* tones_list function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tones_list() {
|
||||
//get the tones
|
||||
$sql = "select * from v_vars ";
|
||||
$sql .= "where var_category = 'Tones' ";
|
||||
$sql .= "order by var_name asc ";
|
||||
$tones = $this->database->select($sql, null, 'all');
|
||||
if (!empty($tones)) {
|
||||
foreach ($tones as $tone) {
|
||||
$tone = $tone['var_name'];
|
||||
if (isset($text['label-'.$tone])) {
|
||||
$label = $text['label-'.$tone];
|
||||
}
|
||||
else {
|
||||
$label = $tone;
|
||||
}
|
||||
$tone_list[$tone] = $label;
|
||||
}
|
||||
}
|
||||
unset($sql, $tones, $tone);
|
||||
|
||||
//return the tones
|
||||
return $tone_list ?? [];
|
||||
}
|
||||
//connect to the database
|
||||
$this->database = $setting_array['database'] ?? database::new();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of tone names with their corresponding labels.
|
||||
*
|
||||
* This method fetches tone data from the database and formats it for display.
|
||||
*
|
||||
* @return array An array of tone names as keys and their labels as values. If no tones are found, an empty array
|
||||
* is returned.
|
||||
*/
|
||||
public function tones_list() {
|
||||
//get the tones
|
||||
$sql = "select * from v_vars ";
|
||||
$sql .= "where var_category = 'Tones' ";
|
||||
$sql .= "order by var_name asc ";
|
||||
$tones = $this->database->select($sql, null, 'all');
|
||||
if (!empty($tones)) {
|
||||
foreach ($tones as $tone) {
|
||||
$tone = $tone['var_name'];
|
||||
if (isset($text['label-' . $tone])) {
|
||||
$label = $text['label-' . $tone];
|
||||
} else {
|
||||
$label = $tone;
|
||||
}
|
||||
$tone_list[$tone] = $label;
|
||||
}
|
||||
}
|
||||
unset($sql, $tones, $tone);
|
||||
|
||||
//return the tones
|
||||
return $tone_list ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,26 @@
|
||||
/*
|
||||
* user class - used to store user groups, permissions, and other values
|
||||
*/
|
||||
|
||||
class user {
|
||||
|
||||
public $domain_uuid;
|
||||
public $domain_name;
|
||||
public $username;
|
||||
public $user_email;
|
||||
public $contact_uuid;
|
||||
private $database;
|
||||
public $domain_uuid;
|
||||
public $domain_name;
|
||||
private $user_uuid;
|
||||
private $permissions;
|
||||
private $groups;
|
||||
public $username;
|
||||
public $user_email;
|
||||
public $contact_uuid;
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
*
|
||||
* This method initializes the object with setting_array and session data.
|
||||
*
|
||||
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||
*/
|
||||
public function __construct(database $database, $domain_uuid, $user_uuid) {
|
||||
|
||||
//set the database variable
|
||||
@@ -30,7 +38,7 @@ class user {
|
||||
$this->user_uuid = $user_uuid;
|
||||
}
|
||||
|
||||
//set the user groups, permission and details
|
||||
//set the user groups, permission, and details
|
||||
if (isset($domain_uuid) && is_uuid($domain_uuid) && isset($user_uuid) && is_uuid($user_uuid)) {
|
||||
$this->set_groups();
|
||||
$this->set_permissions();
|
||||
@@ -41,6 +49,16 @@ class user {
|
||||
/*
|
||||
* set_details method sets the user assigned details
|
||||
*/
|
||||
/**
|
||||
* Sets the user details based on the domain UUID and user UUID.
|
||||
*
|
||||
* This method queries the database to retrieve the user's details,
|
||||
* including their domain name, username, email address, and contact UUID.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool True if the query is successful, false otherwise.
|
||||
*/
|
||||
public function set_details() {
|
||||
$sql = "select d.domain_name, u.username, u.user_email, u.contact_uuid ";
|
||||
$sql .= "from v_users as u, v_domains as d ";
|
||||
@@ -62,6 +80,11 @@ class user {
|
||||
/*
|
||||
* get_user_uuid method gets the user_uuid
|
||||
*/
|
||||
/**
|
||||
* Retrieves the user's UUID.
|
||||
*
|
||||
* @return string The user's unique identifier in UUID format.
|
||||
*/
|
||||
public function get_user_uuid() {
|
||||
return $this->user_uuid;
|
||||
}
|
||||
@@ -69,31 +92,55 @@ class user {
|
||||
/*
|
||||
* set_permissions method sets the user assigned permissions
|
||||
*/
|
||||
public function set_permissions() {
|
||||
$this->permissions = new permissions($this->database, $this->domain_uuid, $this->user_uuid);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_permissions method gets the user assigned permissions
|
||||
*/
|
||||
/**
|
||||
* Retrieves the permissions associated with this entity.
|
||||
*
|
||||
* @return array An array of permission objects or identifiers.
|
||||
* @access public
|
||||
*/
|
||||
public function get_permissions() {
|
||||
return $this->permissions->get_permissions();
|
||||
}
|
||||
|
||||
/*
|
||||
* get_permissions method gets the user assigned permissions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the user's permissions.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function set_permissions() {
|
||||
$this->permissions = new permissions($this->database, $this->domain_uuid, $this->user_uuid);
|
||||
}
|
||||
|
||||
/*
|
||||
* set_groups method sets the user assigned groups
|
||||
*/
|
||||
public function set_groups() {
|
||||
$this->groups = new groups($this->database, $this->domain_uuid, $this->user_uuid);
|
||||
|
||||
/**
|
||||
* Retrieves the user's groups.
|
||||
*
|
||||
* @return array An array of group objects that the user belongs to.
|
||||
*/
|
||||
public function get_groups() {
|
||||
return $this->groups->get_groups();
|
||||
}
|
||||
|
||||
/*
|
||||
* get_groups method gets the user assigned groups
|
||||
*/
|
||||
public function get_groups() {
|
||||
return $this->groups->get_groups();
|
||||
|
||||
/**
|
||||
* Sets the user's group assignments.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_groups() {
|
||||
$this->groups = new groups($this->database, $this->domain_uuid, $this->user_uuid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Filename.......: class_vcard.php
|
||||
* Author.........: Troy Wolf [troy@troywolf.com]
|
||||
* Last Modified..: 2005/07/14 13:30:00
|
||||
* Description....: A class to generate vCards for contact data.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class to generate vCards for contact data.
|
||||
*
|
||||
* @author Troy Wolf [troy@troywolf.com]
|
||||
*/
|
||||
class vcard {
|
||||
var $log;
|
||||
var $data; //array of this vcard's contact data
|
||||
@@ -14,51 +21,54 @@ class vcard {
|
||||
var $card;
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
* Constructor for initializing the object.
|
||||
*
|
||||
* @access public
|
||||
* @return bool True on successful initialization.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->log = "New vcard() called<br />";
|
||||
$this->data = array(
|
||||
"display_name"=>null
|
||||
,"first_name"=>null
|
||||
,"last_name"=>null
|
||||
,"additional_name"=>null
|
||||
,"name_prefix"=>null
|
||||
,"name_suffix"=>null
|
||||
,"nickname"=>null
|
||||
,"title"=>null
|
||||
,"role"=>null
|
||||
,"department"=>null
|
||||
,"company"=>null
|
||||
,"work_po_box"=>null
|
||||
,"work_extended_address"=>null
|
||||
,"work_address"=>null
|
||||
,"work_city"=>null
|
||||
,"work_state"=>null
|
||||
,"work_postal_code"=>null
|
||||
,"work_country"=>null
|
||||
,"home_po_box"=>null
|
||||
,"home_extended_address"=>null
|
||||
,"home_address"=>null
|
||||
,"home_city"=>null
|
||||
,"home_state"=>null
|
||||
,"home_postal_code"=>null
|
||||
,"home_country"=>null
|
||||
,"voice_tel"=>null
|
||||
,"work_tel"=>null
|
||||
,"home_tel"=>null
|
||||
,"cell_tel"=>null
|
||||
,"fax_tel"=>null
|
||||
,"pager_tel"=>null
|
||||
,"email1"=>null
|
||||
,"email2"=>null
|
||||
,"url"=>null
|
||||
,"photo"=>null
|
||||
,"birthday"=>null
|
||||
,"timezone"=>null
|
||||
,"sort_string"=>null
|
||||
,"note"=>null
|
||||
);
|
||||
$this->log = "New vcard() called<br />";
|
||||
$this->data = [
|
||||
"display_name" => null
|
||||
, "first_name" => null
|
||||
, "last_name" => null
|
||||
, "additional_name" => null
|
||||
, "name_prefix" => null
|
||||
, "name_suffix" => null
|
||||
, "nickname" => null
|
||||
, "title" => null
|
||||
, "role" => null
|
||||
, "department" => null
|
||||
, "company" => null
|
||||
, "work_po_box" => null
|
||||
, "work_extended_address" => null
|
||||
, "work_address" => null
|
||||
, "work_city" => null
|
||||
, "work_state" => null
|
||||
, "work_postal_code" => null
|
||||
, "work_country" => null
|
||||
, "home_po_box" => null
|
||||
, "home_extended_address" => null
|
||||
, "home_address" => null
|
||||
, "home_city" => null
|
||||
, "home_state" => null
|
||||
, "home_postal_code" => null
|
||||
, "home_country" => null
|
||||
, "voice_tel" => null
|
||||
, "work_tel" => null
|
||||
, "home_tel" => null
|
||||
, "cell_tel" => null
|
||||
, "fax_tel" => null
|
||||
, "pager_tel" => null
|
||||
, "email1" => null
|
||||
, "email2" => null
|
||||
, "url" => null
|
||||
, "photo" => null
|
||||
, "birthday" => null
|
||||
, "timezone" => null
|
||||
, "sort_string" => null
|
||||
, "note" => null,
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,109 +76,169 @@ class vcard {
|
||||
build() method checks all the values, builds appropriate defaults for
|
||||
missing values, generates the vcard data string.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Downloads the vCard data as a file.
|
||||
*
|
||||
* @access public
|
||||
* @return bool True on successful download, false otherwise.
|
||||
*/
|
||||
function download() {
|
||||
$this->log .= "vcard download() called<br />";
|
||||
if (!$this->card) {
|
||||
$this->build();
|
||||
}
|
||||
if (!$this->filename) {
|
||||
$this->filename = trim($this->data['display_name']);
|
||||
}
|
||||
$this->filename = str_replace(" ", "_", $this->filename);
|
||||
header("Content-type: text/directory");
|
||||
header("Content-Disposition: attachment; filename=" . $this->filename . ".vcf");
|
||||
header("Pragma: public");
|
||||
echo $this->card;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
download() method streams the vcard to the browser client.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds the vCard.
|
||||
*
|
||||
* @access public
|
||||
* @return string The built vCard as a string.
|
||||
*/
|
||||
function build() {
|
||||
$this->log .= "vcard build() called<br />";
|
||||
/*
|
||||
For many of the values, if they are not passed in, we set defaults or
|
||||
build them based on other values.
|
||||
*/
|
||||
if (!$this->class) { $this->class = "PUBLIC"; }
|
||||
if (!$this->data['display_name']) {
|
||||
$this->data['display_name'] = trim($this->data['first_name']." ".$this->data['last_name']);
|
||||
if (!$this->class) {
|
||||
$this->class = "PUBLIC";
|
||||
}
|
||||
if (!$this->data['display_name']) {
|
||||
$this->data['display_name'] = trim($this->data['first_name'] . " " . $this->data['last_name']);
|
||||
}
|
||||
if (!$this->data['sort_string']) {
|
||||
$this->data['sort_string'] = $this->data['last_name'];
|
||||
}
|
||||
if (!$this->data['sort_string']) {
|
||||
$this->data['sort_string'] = $this->data['company'];
|
||||
}
|
||||
if (!$this->data['timezone']) {
|
||||
$this->data['timezone'] = date("O");
|
||||
}
|
||||
if (!$this->revision_date) {
|
||||
$this->revision_date = date('Y-m-d H:i:s');
|
||||
}
|
||||
if (!$this->data['sort_string']) { $this->data['sort_string'] = $this->data['last_name']; }
|
||||
if (!$this->data['sort_string']) { $this->data['sort_string'] = $this->data['company']; }
|
||||
if (!$this->data['timezone']) { $this->data['timezone'] = date("O"); }
|
||||
if (!$this->revision_date) { $this->revision_date = date('Y-m-d H:i:s'); }
|
||||
|
||||
$this->card = "BEGIN:VCARD\r\n";
|
||||
$this->card .= "VERSION:3.0\r\n";
|
||||
//$this->card .= "CLASS:".$this->class."\r\n";
|
||||
//$this->card .= "PRODID:-//class_vcard from TroyWolf.com//NONSGML Version 1//EN\r\n";
|
||||
// $this->card .= "REV:".$this->revision_date."\r\n";
|
||||
$this->card .= "FN:".$this->data['display_name']."\r\n";
|
||||
$this->card .= "FN:" . $this->data['display_name'] . "\r\n";
|
||||
$this->card .= "N:";
|
||||
$this->card .= $this->data['last_name'].";";
|
||||
$this->card .= $this->data['last_name'] . ";";
|
||||
$this->card .= $this->data['first_name'];
|
||||
if (!empty($this->data['additional_name'])) {
|
||||
$this->card .= ";".$this->data['additional_name'];
|
||||
$this->card .= ";" . $this->data['additional_name'];
|
||||
}
|
||||
if (!empty($this->data['name_prefix'])) {
|
||||
$this->card .= ";".$this->data['name_prefix'];
|
||||
$this->card .= ";" . $this->data['name_prefix'];
|
||||
}
|
||||
if (!empty($this->data['name_suffix'])) {
|
||||
$this->card .= ";".$this->data['name_suffix'];
|
||||
$this->card .= ";" . $this->data['name_suffix'];
|
||||
}
|
||||
$this->card .= "\r\n";
|
||||
if ($this->data['nickname']) { $this->card .= "NICKNAME:".$this->data['contact_nickname']."\r\n"; }
|
||||
if ($this->data['title']) { $this->card .= "TITLE:".$this->data['title']."\r\n"; }
|
||||
if ($this->data['company']) { $this->card .= "ORG:".$this->data['company']; }
|
||||
if ($this->data['department']) { $this->card .= ";".$this->data['department']; }
|
||||
if ($this->data['nickname']) {
|
||||
$this->card .= "NICKNAME:" . $this->data['contact_nickname'] . "\r\n";
|
||||
}
|
||||
if ($this->data['title']) {
|
||||
$this->card .= "TITLE:" . $this->data['title'] . "\r\n";
|
||||
}
|
||||
if ($this->data['company']) {
|
||||
$this->card .= "ORG:" . $this->data['company'];
|
||||
}
|
||||
if ($this->data['department']) {
|
||||
$this->card .= ";" . $this->data['department'];
|
||||
}
|
||||
$this->card .= "\r\n";
|
||||
|
||||
$vcard_address_type_values = array('work','home','dom','intl','postal','parcel','pref');
|
||||
$vcard_address_type_values = ['work', 'home', 'dom', 'intl', 'postal', 'parcel', 'pref'];
|
||||
foreach ($vcard_address_type_values as $vcard_address_type_value) {
|
||||
if (!empty($this->data[$vcard_address_type_value.'_po_box'])
|
||||
|| !empty($this->data[$vcard_address_type_value.'_extended_address'])
|
||||
|| !empty($this->data[$vcard_address_type_value.'_address'])
|
||||
|| !empty($this->data[$vcard_address_type_value.'_city'])
|
||||
|| !empty($this->data[$vcard_address_type_value.'_state'])
|
||||
|| !empty($this->data[$vcard_address_type_value.'_postal_code'])
|
||||
|| !empty($this->data[$vcard_address_type_value.'_country'])) {
|
||||
$this->card .= "ADR;TYPE=".$vcard_address_type_value.":";
|
||||
if (!empty($this->data[$vcard_address_type_value.'_po_box'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_po_box'].";";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_po_box'])
|
||||
|| !empty($this->data[$vcard_address_type_value . '_extended_address'])
|
||||
|| !empty($this->data[$vcard_address_type_value . '_address'])
|
||||
|| !empty($this->data[$vcard_address_type_value . '_city'])
|
||||
|| !empty($this->data[$vcard_address_type_value . '_state'])
|
||||
|| !empty($this->data[$vcard_address_type_value . '_postal_code'])
|
||||
|| !empty($this->data[$vcard_address_type_value . '_country'])) {
|
||||
$this->card .= "ADR;TYPE=" . $vcard_address_type_value . ":";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_po_box'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_po_box'] . ";";
|
||||
}
|
||||
if (!empty($this->data[$vcard_address_type_value.'_extended_address'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_extended_address'].";";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_extended_address'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_extended_address'] . ";";
|
||||
}
|
||||
if (!empty($this->data[$vcard_address_type_value.'_address'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_address'].";";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_address'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_address'] . ";";
|
||||
}
|
||||
if (!empty($this->data[$vcard_address_type_value.'_city'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_city'].";";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_city'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_city'] . ";";
|
||||
}
|
||||
if (!empty($this->data[$vcard_address_type_value.'_state'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_state'].";";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_state'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_state'] . ";";
|
||||
}
|
||||
if (!empty($this->data[$vcard_address_type_value.'_postal_code'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_postal_code'].";";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_postal_code'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_postal_code'] . ";";
|
||||
}
|
||||
if (!empty($this->data[$vcard_address_type_value.'_country'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value.'_country']."";
|
||||
if (!empty($this->data[$vcard_address_type_value . '_country'])) {
|
||||
$this->card .= $this->data[$vcard_address_type_value . '_country'] . "";
|
||||
}
|
||||
$this->card .= "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->data['email1']) { $this->card .= "EMAIL;PREF=1:".$this->data['email1']."\r\n"; }
|
||||
if ($this->data['email2']) { $this->card .= "EMAIL;PREF=2:".$this->data['email2']."\r\n"; }
|
||||
if ($this->data['voice_tel']) { $this->card .= "TEL;TYPE=voice:".$this->data['voice_tel']."\r\n"; }
|
||||
if ($this->data['work_tel']) { $this->card .= "TEL;TYPE=work:".$this->data['work_tel']."\r\n"; }
|
||||
if ($this->data['home_tel']) { $this->card .= "TEL;TYPE=home:".$this->data['home_tel']."\r\n"; }
|
||||
if ($this->data['cell_tel']) { $this->card .= "TEL;TYPE=cell:".$this->data['cell_tel']."\r\n"; }
|
||||
if ($this->data['fax_tel']) { $this->card .= "TEL;TYPE=fax:".$this->data['fax_tel']."\r\n"; }
|
||||
if ($this->data['pager_tel']) { $this->card .= "TEL;TYPE=pager:".$this->data['pager_tel']."\r\n"; }
|
||||
if ($this->data['url']) { $this->card .= "URL:".$this->data['url']."\r\n"; }
|
||||
if ($this->data['birthday']) { $this->card .= "BDAY:".$this->data['birthday']."\r\n"; }
|
||||
if ($this->data['role']) { $this->card .= "ROLE:".$this->data['role']."\r\n"; }
|
||||
if ($this->data['note']) { $this->card .= "NOTE:".$this->data['note']."\r\n"; }
|
||||
$this->card .= "TZ:".$this->data['timezone']."\r\n";
|
||||
if ($this->data['email1']) {
|
||||
$this->card .= "EMAIL;PREF=1:" . $this->data['email1'] . "\r\n";
|
||||
}
|
||||
if ($this->data['email2']) {
|
||||
$this->card .= "EMAIL;PREF=2:" . $this->data['email2'] . "\r\n";
|
||||
}
|
||||
if ($this->data['voice_tel']) {
|
||||
$this->card .= "TEL;TYPE=voice:" . $this->data['voice_tel'] . "\r\n";
|
||||
}
|
||||
if ($this->data['work_tel']) {
|
||||
$this->card .= "TEL;TYPE=work:" . $this->data['work_tel'] . "\r\n";
|
||||
}
|
||||
if ($this->data['home_tel']) {
|
||||
$this->card .= "TEL;TYPE=home:" . $this->data['home_tel'] . "\r\n";
|
||||
}
|
||||
if ($this->data['cell_tel']) {
|
||||
$this->card .= "TEL;TYPE=cell:" . $this->data['cell_tel'] . "\r\n";
|
||||
}
|
||||
if ($this->data['fax_tel']) {
|
||||
$this->card .= "TEL;TYPE=fax:" . $this->data['fax_tel'] . "\r\n";
|
||||
}
|
||||
if ($this->data['pager_tel']) {
|
||||
$this->card .= "TEL;TYPE=pager:" . $this->data['pager_tel'] . "\r\n";
|
||||
}
|
||||
if ($this->data['url']) {
|
||||
$this->card .= "URL:" . $this->data['url'] . "\r\n";
|
||||
}
|
||||
if ($this->data['birthday']) {
|
||||
$this->card .= "BDAY:" . $this->data['birthday'] . "\r\n";
|
||||
}
|
||||
if ($this->data['role']) {
|
||||
$this->card .= "ROLE:" . $this->data['role'] . "\r\n";
|
||||
}
|
||||
if ($this->data['note']) {
|
||||
$this->card .= "NOTE:" . $this->data['note'] . "\r\n";
|
||||
}
|
||||
$this->card .= "TZ:" . $this->data['timezone'] . "\r\n";
|
||||
$this->card .= "END:VCARD";
|
||||
}
|
||||
|
||||
/*
|
||||
download() method streams the vcard to the browser client.
|
||||
*/
|
||||
function download() {
|
||||
$this->log .= "vcard download() called<br />";
|
||||
if (!$this->card) { $this->build(); }
|
||||
if (!$this->filename) { $this->filename = trim($this->data['display_name']); }
|
||||
$this->filename = str_replace(" ", "_", $this->filename);
|
||||
header("Content-type: text/directory");
|
||||
header("Content-Disposition: attachment; filename=".$this->filename.".vcf");
|
||||
header("Pragma: public");
|
||||
echo $this->card;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,120 +2,80 @@
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author MaximAL
|
||||
* @since 2019-02-13 Added `$onePhase` parameters to get only positive waveform data and image
|
||||
* @since 2018-10-22 Added `getWaveformData()` method and `$soxCommand` configuration
|
||||
* @since 2016-11-21
|
||||
* @date 2016-11-21
|
||||
* @time 19:08
|
||||
* @link http://maximals.ru
|
||||
* @link http://sijeko.ru
|
||||
* @link https://github.com/maximal/audio-waveform-php
|
||||
* @author MaximAL
|
||||
* @since 2019-02-13 Added `$onePhase` parameters to get only positive waveform data and image
|
||||
* @since 2018-10-22 Added `getWaveformData()` method and `$soxCommand` configuration
|
||||
* @since 2016-11-21
|
||||
* @date 2016-11-21
|
||||
* @time 19:08
|
||||
* @link http://maximals.ru
|
||||
* @link http://sijeko.ru
|
||||
* @link https://github.com/maximal/audio-waveform-php
|
||||
* @copyright © MaximAL, Sijeko 2016-2019
|
||||
*
|
||||
* @modified fusionate
|
||||
* @since 2024-02-07 Added option to return image in base64 format by setting $filename to 'base64'
|
||||
* @since 2024-02-08 Added `$singleAxis` parameter to combine channels (if stereo) into single axis
|
||||
* @since 2024-02-08 Added `$colorA` and `$colorB` parameters to allow different colors for each channel
|
||||
* @since 2024-02-08 Rename `$onePhase` parameter to `$singlePhase` and change to public static variable for class
|
||||
* @since 2024-02-08 Modified singleAxis so channel 2 would display as negative waveform data when singlePhase enabled
|
||||
* @modified fusionate
|
||||
* @since 2024-02-07 Added option to return image in base64 format by setting $filename to 'base64'
|
||||
* @since 2024-02-08 Added `$singleAxis` parameter to combine channels (if stereo) into single axis
|
||||
* @since 2024-02-08 Added `$colorA` and `$colorB` parameters to allow different colors for each channel
|
||||
* @since 2024-02-08 Rename `$onePhase` parameter to `$singlePhase` and change to public static variable for class
|
||||
* @since 2024-02-08 Modified singleAxis so channel 2 would display as negative waveform data when singlePhase
|
||||
* enabled
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace maximal\audio;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Waveform class allows you to get waveform data and images from audio files
|
||||
*
|
||||
* @package maximal\audio
|
||||
*/
|
||||
class Waveform
|
||||
{
|
||||
protected $filename;
|
||||
protected $info;
|
||||
protected $channels;
|
||||
protected $samples;
|
||||
protected $sampleRate;
|
||||
protected $duration;
|
||||
|
||||
class Waveform {
|
||||
public static $linesPerPixel = 8;
|
||||
public static $samplesPerLine = 512;
|
||||
public static $singlePhase; // set `true` to get positive waveform phase only, `false` to get both positive and negative waveform phases
|
||||
public static $singleAxis; // combine double or single phases to use same axis
|
||||
public static $singlePhase;
|
||||
public static $singleAxis;
|
||||
public static $color = [95, 95, 95, 0.5];
|
||||
public static $colorA;
|
||||
public static $colorB;
|
||||
public static $backgroundColor = [245, 245, 245, 1];
|
||||
public static $axisColor = [0, 0, 0, 0.1]; // set `true` to get positive waveform phase only, `false` to get both positive and negative waveform phases
|
||||
public static $soxCommand = 'sox'; // combine double or single phases to use same axis
|
||||
|
||||
// Colors in CSS `rgba(red, green, blue, opacity)` format
|
||||
public static $color = [95, 95, 95, 0.5];
|
||||
public static $colorA; // color of left channel (1)
|
||||
public static $colorB; // color of right channel (2)
|
||||
public static $backgroundColor = [245, 245, 245, 1];
|
||||
public static $axisColor = [0, 0, 0, 0.1];
|
||||
protected $filename;
|
||||
protected $info; // color of left channel (1)
|
||||
protected $channels; // color of right channel (2)
|
||||
protected $samples;
|
||||
protected $sampleRate;
|
||||
|
||||
// SoX command: 'sox', '/usr/local/bin/sox' etc
|
||||
public static $soxCommand = 'sox';
|
||||
protected $duration;
|
||||
|
||||
|
||||
public function __construct($filename)
|
||||
{
|
||||
/**
|
||||
* Initializes a new instance of this class with the specified filename.
|
||||
*
|
||||
* @param string $filename The name of the file associated with this instance.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($filename) {
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
public function getInfo()
|
||||
{
|
||||
$out = null;
|
||||
$ret = null;
|
||||
exec(self::$soxCommand . ' --i ' . escapeshellarg($this->filename) . ' 2>&1', $out, $ret);
|
||||
$str = implode('|', $out);
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/Channels?\s*\:\s*(\d+)/ui', $str, $match)) {
|
||||
$this->channels = intval($match[1]);
|
||||
}
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/Sample\s*Rate\s*\:\s*(\d+)/ui', $str, $match)) {
|
||||
$this->sampleRate = intval($match[1]);
|
||||
}
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/Duration.*[^\d](\d+)\s*samples?/ui', $str, $match)) {
|
||||
$this->samples = intval($match[1]);
|
||||
}
|
||||
|
||||
if ($this->samples && $this->sampleRate) {
|
||||
$this->duration = 1.0 * $this->samples / $this->sampleRate;
|
||||
}
|
||||
|
||||
if ($ret !== 0) {
|
||||
throw new \Exception('Failed to get audio info.' . PHP_EOL . 'Error: ' . implode(PHP_EOL, $out) . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
public function getSampleRate()
|
||||
{
|
||||
if (!$this->sampleRate) {
|
||||
$this->getInfo();
|
||||
}
|
||||
return $this->sampleRate;
|
||||
}
|
||||
|
||||
public function getChannels()
|
||||
{
|
||||
if (!$this->channels) {
|
||||
$this->getInfo();
|
||||
}
|
||||
return $this->channels;
|
||||
}
|
||||
|
||||
public function getSamples()
|
||||
{
|
||||
if (!$this->samples) {
|
||||
$this->getInfo();
|
||||
}
|
||||
return $this->samples;
|
||||
}
|
||||
|
||||
public function getDuration()
|
||||
{
|
||||
/**
|
||||
* Retrieves the duration of the current media file.
|
||||
*
|
||||
* If the duration has not been retrieved yet, it will be fetched from the media server.
|
||||
*
|
||||
* @return float The duration of the media file in seconds.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getDuration() {
|
||||
if (!$this->duration) {
|
||||
$this->getInfo();
|
||||
}
|
||||
@@ -124,14 +84,15 @@ class Waveform
|
||||
|
||||
/**
|
||||
* Get waveform from the audio file.
|
||||
*
|
||||
* @param string $filename Image file name
|
||||
* @param int $width Width of the image file in pixels
|
||||
* @param int $height Height of the image file in pixels
|
||||
* @param int $width Width of the image file in pixels
|
||||
* @param int $height Height of the image file in pixels
|
||||
*
|
||||
* @return bool Returns `true` on success or `false` on failure, when generating an image file, or a base64 string.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getWaveform($filename, $width, $height)
|
||||
{
|
||||
public function getWaveform($filename, $width, $height) {
|
||||
// Calculating parameters
|
||||
$needChannels = $this->getChannels() > 1 ? 2 : 1;
|
||||
$data = $this->getWaveformData($width, self::$singlePhase ?? false);
|
||||
@@ -159,7 +120,7 @@ class Waveform
|
||||
$center1 = $center2 = $height / 2;
|
||||
} else {
|
||||
if (self::$singlePhase ?? false) {
|
||||
$center1 = $needChannels === 2 ? $height / 2 - 1: $height - 1;
|
||||
$center1 = $needChannels === 2 ? $height / 2 - 1 : $height - 1;
|
||||
$center2 = $needChannels === 2 ? $height - 1 : null;
|
||||
} else {
|
||||
$center1 = $needChannels === 2 ? ($height / 2 - 1) / 2 : $height / 2;
|
||||
@@ -218,14 +179,31 @@ class Waveform
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a collection of channels.
|
||||
*
|
||||
* If no channels have been loaded yet, the {@link getInfo()} method is called to load them first.
|
||||
*
|
||||
* @return array A collection of channel objects.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getChannels() {
|
||||
if (!$this->channels) {
|
||||
$this->getInfo();
|
||||
}
|
||||
return $this->channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get waveform data from the audio file.
|
||||
*
|
||||
* @param int $width Desired width of the image file in pixels
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getWaveformData($width)
|
||||
{
|
||||
public function getWaveformData($width) {
|
||||
// Calculating parameters
|
||||
$needChannels = $this->getChannels() > 1 ? 2 : 1;
|
||||
$samplesPerPixel = self::$samplesPerLine * self::$linesPerPixel;
|
||||
@@ -249,7 +227,7 @@ class Waveform
|
||||
$pipes = null;
|
||||
$proc = proc_open($command, $outputs, $pipes);
|
||||
if (!$proc) {
|
||||
throw new \Exception('Failed to run `sox` command');
|
||||
throw new Exception('Failed to run `sox` command');
|
||||
}
|
||||
|
||||
$lines1 = [];
|
||||
@@ -260,26 +238,26 @@ class Waveform
|
||||
$channel2 = [];
|
||||
foreach ($data as $index => $sample) {
|
||||
if ($needChannels === 2 && $index % 2 === 0) {
|
||||
$channel2 []= $sample;
|
||||
$channel2 [] = $sample;
|
||||
} else {
|
||||
$channel1 []= $sample;
|
||||
$channel1 [] = $sample;
|
||||
}
|
||||
}
|
||||
if (self::$singlePhase ?? false) {
|
||||
// Rectifying to get positive values only
|
||||
$lines1 []= abs(min($channel1));
|
||||
$lines1 []= abs(max($channel1));
|
||||
$lines1 [] = abs(min($channel1));
|
||||
$lines1 [] = abs(max($channel1));
|
||||
if ($needChannels === 2) {
|
||||
$lines2 []= abs(min($channel2));
|
||||
$lines2 []= abs(max($channel2));
|
||||
$lines2 [] = abs(min($channel2));
|
||||
$lines2 [] = abs(max($channel2));
|
||||
}
|
||||
} else {
|
||||
// Two phases
|
||||
$lines1 []= min($channel1);
|
||||
$lines1 []= max($channel1);
|
||||
$lines1 [] = min($channel1);
|
||||
$lines1 [] = max($channel1);
|
||||
if ($needChannels === 2) {
|
||||
$lines2 []= min($channel2);
|
||||
$lines2 []= max($channel2);
|
||||
$lines2 [] = min($channel2);
|
||||
$lines2 [] = max($channel2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,14 +266,92 @@ class Waveform
|
||||
$ret = proc_close($proc);
|
||||
|
||||
if ($ret !== 0) {
|
||||
throw new \Exception('Failed to run `sox` command. Error:' . PHP_EOL . $err);
|
||||
throw new Exception('Failed to run `sox` command. Error:' . PHP_EOL . $err);
|
||||
}
|
||||
|
||||
return ['lines1' => $lines1, 'lines2' => $lines2];
|
||||
}
|
||||
|
||||
public static function rgbaToColor($img, $rgba)
|
||||
{
|
||||
/**
|
||||
* Retrieves the sample rate associated with this instance.
|
||||
*
|
||||
* If the sample rate has not been previously retrieved, it will be obtained
|
||||
* by calling getInfo(). The sample rate is then cached for future retrieval.
|
||||
*
|
||||
* @return int|null The sample rate in Hz, or null if unable to retrieve the information.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getSampleRate() {
|
||||
if (!$this->sampleRate) {
|
||||
$this->getInfo();
|
||||
}
|
||||
return $this->sampleRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves information about the audio file associated with this instance.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getInfo() {
|
||||
$out = null;
|
||||
$ret = null;
|
||||
exec(self::$soxCommand . ' --i ' . escapeshellarg($this->filename) . ' 2>&1', $out, $ret);
|
||||
$str = implode('|', $out);
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/Channels?\s*\:\s*(\d+)/ui', $str, $match)) {
|
||||
$this->channels = intval($match[1]);
|
||||
}
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/Sample\s*Rate\s*\:\s*(\d+)/ui', $str, $match)) {
|
||||
$this->sampleRate = intval($match[1]);
|
||||
}
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/Duration.*[^\d](\d+)\s*samples?/ui', $str, $match)) {
|
||||
$this->samples = intval($match[1]);
|
||||
}
|
||||
|
||||
if ($this->samples && $this->sampleRate) {
|
||||
$this->duration = 1.0 * $this->samples / $this->sampleRate;
|
||||
}
|
||||
|
||||
if ($ret !== 0) {
|
||||
throw new Exception('Failed to get audio info.' . PHP_EOL . 'Error: ' . implode(PHP_EOL, $out) . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a collection of sample data.
|
||||
*
|
||||
* If no samples have been retrieved yet, this method will call getInfo() to populate the internal samples list.
|
||||
*
|
||||
* @return int The collection of sample data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getSamples() {
|
||||
if (!$this->samples) {
|
||||
$this->getInfo();
|
||||
}
|
||||
return $this->samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGBA color to a PHP image color with alpha channel.
|
||||
*
|
||||
* @param resource $img The PHP image resource to convert the color for.
|
||||
* @param array $rgba An array containing the red, green, blue and alpha values of the color.
|
||||
*
|
||||
* @return int The allocated color index.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function rgbaToColor($img, $rgba) {
|
||||
return imagecolorallocatealpha($img, $rgba[0], $rgba[1], $rgba[2], round((1 - $rgba[3]) * 127));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* xml class
|
||||
*/
|
||||
class xml {
|
||||
|
||||
/**
|
||||
* xml class
|
||||
* Sanitizes a string by removing any PHP-style placeholders and encoding special characters.
|
||||
*
|
||||
* @param string $string The input string to be sanitized.
|
||||
*
|
||||
* @return string The sanitized string with special characters encoded.
|
||||
*/
|
||||
class xml {
|
||||
|
||||
/**
|
||||
* Escapes xml special characters to html entities and sanitze switch special chars.
|
||||
* @param mixed $string
|
||||
* @return void
|
||||
*/
|
||||
static function sanitize($string) {
|
||||
$string = preg_replace('/\$\{[^}]+\}/', '', $string);
|
||||
return htmlspecialchars($string, ENT_XML1);
|
||||
}
|
||||
|
||||
static function sanitize($string) {
|
||||
$string = preg_replace('/\$\{[^}]+\}/', '', $string);
|
||||
return htmlspecialchars($string, ENT_XML1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user