From dc22e87fc2e0d9003c511b821f4bd91785e2b769 Mon Sep 17 00:00:00 2001 From: frytimo Date: Fri, 17 Jan 2025 15:48:11 -0400 Subject: [PATCH 01/89] fix dashboard php warnings (#7218) --- .../resources/dashboard/registrations.php | 10 +++------- core/dashboard/index.php | 6 +++--- core/dashboard/resources/dashboard/icon.php | 5 +---- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/app/registrations/resources/dashboard/registrations.php b/app/registrations/resources/dashboard/registrations.php index 6883af3d3d..44ea55ed3f 100644 --- a/app/registrations/resources/dashboard/registrations.php +++ b/app/registrations/resources/dashboard/registrations.php @@ -12,10 +12,7 @@ $text = $language->get($_SESSION['domain']['language']['code'], dirname($dashboard_url)); //get the dashboard label - $dashboard_label = $text['title-'.$dashboard_key]; - if (empty($dashboard_label)) { - $dashboard_label = $dashboard_name; - } + $dashboard_label = $text['title-'.$dashboard_key] ?? $dashboard_name; //prepare variables $dashboard_target = ($dashboard_target == 'new') ? '_blank' : '_self'; @@ -25,9 +22,7 @@ } //channel count - if ($esl == null) { - $esl = event_socket::create(); - } + $esl = event_socket::create(); //registration count if ($esl->is_connected() && file_exists($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH."/app/registrations/")) { @@ -41,6 +36,7 @@ //get the total enabled extensions $sql = "select count(*) as count from v_extensions "; $sql .= "where enabled = 'true' "; + $parameters = null; if (!permission_exists("registration_all")) { $sql .= "and domain_uuid = :domain_uuid "; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; diff --git a/core/dashboard/index.php b/core/dashboard/index.php index c9b92880dc..9e28e1f689 100644 --- a/core/dashboard/index.php +++ b/core/dashboard/index.php @@ -187,7 +187,7 @@ //determine initial state all button to display $expanded_all = true; - if (is_array($dashboard) && @sizeof($dashboard) != 0) { + if (!empty($dashboard)) { foreach ($dashboard as $row) { if ($row['dashboard_details_state'] == 'contracted' || $row['dashboard_details_state'] == 'hidden' || $row['dashboard_details_state'] == 'disabled') { $expanded_all = false; } } @@ -531,8 +531,8 @@ function toggle_grid_row_end_all() { $dashboard_content_text_align = $row['dashboard_content_text_align'] ?? ''; $dashboard_content_details = $row['dashboard_content_details'] ?? ''; $dashboard_chart_type = $row['dashboard_chart_type'] ?? "doughnut"; - $dashboard_label_text_color = $row['dashboard_label_text_color'] ?? $settings->get('theme', 'dashboard_label_text_color'); - $dashboard_number_text_color = $row['dashboard_number_text_color'] ?? $settings->get('theme', 'dashboard_number_text_color'); + $dashboard_label_text_color = $row['dashboard_label_text_color'] ?? $settings->get('theme', 'dashboard_label_text_color', ''); + $dashboard_number_text_color = $row['dashboard_number_text_color'] ?? $settings->get('theme', 'dashboard_number_text_color', ''); $dashboard_details_state = $row['dashboard_details_state'] ?? "expanded"; $dashboard_row_span = $row['dashboard_row_span'] ?? 2; diff --git a/core/dashboard/resources/dashboard/icon.php b/core/dashboard/resources/dashboard/icon.php index 6cbba3f718..5ad649d4c4 100644 --- a/core/dashboard/resources/dashboard/icon.php +++ b/core/dashboard/resources/dashboard/icon.php @@ -12,10 +12,7 @@ $text = $language->get($_SESSION['domain']['language']['code'], dirname($dashboard_url)); //get the dashboard label - $dashboard_label = $text['title-'.$dashboard_key]; - if (empty($dashboard_label)) { - $dashboard_label = $dashboard_name; - } + $dashboard_label = $text['title-'.$dashboard_key] ?? $dashboard_name; //prepare variables $dashboard_target = ($dashboard_target == 'new') ? '_blank' : '_self'; From 50125527de189d6becd93d8803d9cfc0fa27d4a5 Mon Sep 17 00:00:00 2001 From: frytimo Date: Fri, 17 Jan 2025 15:48:49 -0400 Subject: [PATCH 02/89] fix php warning for ini set (#7217) The ini setting can only be modified when the session has not already started. This moves the ini_set function call inside the if block --- resources/header.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/header.php b/resources/header.php index d044c9b18e..80c5499234 100644 --- a/resources/header.php +++ b/resources/header.php @@ -28,8 +28,10 @@ require_once __DIR__ . "/require.php"; //start the session - ini_set("session.cookie_httponly", true); - if (!isset($_SESSION)) { session_start(); } + if (!isset($_SESSION)) { + ini_set("session.cookie_httponly", true); + session_start(); + } //set the domains session if (!isset($_SESSION['domains'])) { From 62039c300afcf35d12e6b2c42ab05e85330ca914 Mon Sep 17 00:00:00 2001 From: frytimo Date: Fri, 17 Jan 2025 16:39:17 -0400 Subject: [PATCH 03/89] fix menu php warning when restoring default menu (#7219) --- resources/classes/menu.php | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/classes/menu.php b/resources/classes/menu.php index 0b3db46e28..5def1ec9de 100644 --- a/resources/classes/menu.php +++ b/resources/classes/menu.php @@ -445,6 +445,7 @@ if (!class_exists('menu')) { //item exists in the database if ($menu_item_exists) { + $parent_menu_item_protected = 'false'; //get parent_menu_item_protected foreach ($menu_items as $item) { if ($item['uuid'] == $menu['parent_uuid']) { From b6386ada324d3650d55b3fac9deced55e7786a51 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Fri, 17 Jan 2025 23:30:06 -0700 Subject: [PATCH 04/89] Add table xml_cdr_extensions --- app/xml_cdr/app_config.php | 94 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/app/xml_cdr/app_config.php b/app/xml_cdr/app_config.php index 98f5944920..c01ea17d31 100644 --- a/app/xml_cdr/app_config.php +++ b/app/xml_cdr/app_config.php @@ -267,6 +267,21 @@ $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; $apps[$x]['permissions'][$y]['groups'][] = "admin"; $y++; + $apps[$x]['permissions'][$y]['name'] = 'xml_cdr_extension_view'; + $apps[$x]['permissions'][$y]['groups'][] = 'superadmin'; + $y++; + $apps[$x]['permissions'][$y]['name'] = 'xml_cdr_extension_add'; + $apps[$x]['permissions'][$y]['groups'][] = 'superadmin'; + $y++; + $apps[$x]['permissions'][$y]['name'] = 'xml_cdr_extension_edit'; + $apps[$x]['permissions'][$y]['groups'][] = 'superadmin'; + $y++; + $apps[$x]['permissions'][$y]['name'] = 'xml_cdr_extension_delete'; + $apps[$x]['permissions'][$y]['groups'][] = 'superadmin'; + $y++; + $apps[$x]['permissions'][$y]['name'] = 'xml_cdr_extension_all'; + $apps[$x]['permissions'][$y]['groups'][] = 'superadmin'; + $y++; //default settings $y=0; @@ -856,6 +871,85 @@ $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + //xml cdr extensions + $y++; + $apps[$x]['db'][$y]['table']['name'] = 'v_xml_cdr_extensions'; + $apps[$x]['db'][$y]['table']['parent'] = ''; + $z = 0; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'xml_cdr_extension_uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'primary'; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'domain_uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign'; + $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_domains'; + $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'domain_uuid'; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'xml_cdr_uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['key']['type'] = "foreign"; + $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = "v_xml_cdr"; + $apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = "domain_uuid"; + $apps[$x]['db'][$y]['fields'][$z]['search_by'] = ''; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'extension_uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['search_by'] = ''; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'start_stamp'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['search_by'] = '1'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'end_stamp'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['search_by'] = '1'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'duration'; + $apps[$x]['db'][$y]['fields'][$z]['type'] = 'numeric'; + $apps[$x]['db'][$y]['fields'][$z]['search_by'] = ''; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'insert_date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'insert_user'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'update_date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = 'update_user'; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid'; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text'; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ''; + //schema details $y++; $apps[$x]['db'][$y]['table']['name'] = "v_xml_cdr_json"; From 8b59ef881b580d7d05419206a61f0657eff38980 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Sat, 18 Jan 2025 15:47:56 -0700 Subject: [PATCH 05/89] Use the settings array to pass database connection Improve efficiency by using one database connection --- .../resources/classes/destinations.php | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/app/destinations/resources/classes/destinations.php b/app/destinations/resources/classes/destinations.php index 6b05c30c64..2e5fea96de 100644 --- a/app/destinations/resources/classes/destinations.php +++ b/app/destinations/resources/classes/destinations.php @@ -52,22 +52,33 @@ if (!class_exists('destinations')) { private $list_page; private $table; private $uuid_prefix; + private $database; private $settings; /** * Called when the object is created */ - public function __construct($settings = null) { + public function __construct($setting_array = []) { + + //open a database connection + if (empty($setting_array['database'])) { + $this->database = database::new(); + } else { + $this->database = $setting_array['database']; + } + + //get the settings object + if (empty($setting_array['settings'])) { + $this->settings = new settings(); + } else { + $this->settings = $setting_array['settings']; + } + //set the domain details if (is_null($this->domain_uuid)) { $this->domain_uuid = $_SESSION['domain_uuid']; } - //get the email queue settings - if (!isset($settings)) { - $this->settings = new settings(); - } - //assign private variables $this->app_name = 'destinations'; $this->app_uuid = '5ec89622-b19c-3559-64f0-afde802ab139'; @@ -180,8 +191,7 @@ if (!class_exists('destinations')) { $sql = "select domain_name from v_domains "; $sql .= "where domain_uuid = :domain_uuid "; $parameters['domain_uuid'] = $this->domain_uuid; - $database = new database; - $this->domain_name = $database->select($sql, $parameters, 'column'); + $this->domain_name = $this->database->select($sql, $parameters, 'column'); //initialize variable $response = ''; @@ -252,8 +262,7 @@ if (!class_exists('destinations')) { } $sql .= "order by ".trim($row['order_by']); $sql = str_replace("\${domain_uuid}", $this->domain_uuid, $sql); - $database = new database; - $result = $database->select($sql, null, 'all'); + $result = $this->database->select($sql, null, 'all'); $this->destinations[$x]['result']['sql'] = $sql; $this->destinations[$x]['result']['data'] = $result; @@ -550,9 +559,6 @@ if (!class_exists('destinations')) { //set the global variables global $db_type; - //connect to the database - $database = new database; - //set default values $destination_name = ''; $destination_id = ''; @@ -561,7 +567,7 @@ if (!class_exists('destinations')) { $sql = "select domain_name from v_domains "; $sql .= "where domain_uuid = :domain_uuid "; $parameters['domain_uuid'] = $this->domain_uuid; - $this->domain_name = $database->select($sql, $parameters, 'column'); + $this->domain_name = $this->database->select($sql, $parameters, 'column'); //get the destinations if (!is_array($this->destinations)) { @@ -625,7 +631,7 @@ if (!class_exists('destinations')) { } $sql .= "order by ".trim($row['order_by']); $sql = str_replace("\${domain_uuid}", $this->domain_uuid, $sql); - $result = $database->select($sql, null, 'all'); + $result = $this->database->select($sql, null, 'all'); $this->destinations[$x]['result']['sql'] = $sql; $this->destinations[$x]['result']['data'] = $result; @@ -764,14 +770,11 @@ if (!class_exists('destinations')) { //set the global variables global $db_type; - //connect to the database - $database = new database; - //get the domain_name $sql = "select domain_name from v_domains "; $sql .= "where domain_uuid = :domain_uuid "; $parameters['domain_uuid'] = $this->domain_uuid; - $this->domain_name = $database->select($sql, $parameters, 'column'); + $this->domain_name = $this->database->select($sql, $parameters, 'column'); //get the destinations if (!is_array($this->destinations)) { @@ -836,7 +839,7 @@ if (!class_exists('destinations')) { } $sql .= "order by ".trim($row['order_by']); $sql = str_replace("\${domain_uuid}", $this->domain_uuid, $sql); - $result = $database->select($sql, null, 'all'); + $result = $this->database->select($sql, null, 'all'); $this->destinations[$x]['result']['sql'] = $sql; $this->destinations[$x]['result']['data'] = $result; @@ -1063,8 +1066,7 @@ if (!class_exists('destinations')) { $sql = "select dialplan_uuid, destination_context from v_destinations "; $sql .= "where destination_uuid = :destination_uuid "; $parameters['destination_uuid'] = $record['uuid']; - $database = new database; - $row = $database->select($sql, $parameters, 'row'); + $row = $this->database->select($sql, $parameters, 'row'); unset($sql, $parameters); //include dialplan in array @@ -1086,10 +1088,9 @@ if (!class_exists('destinations')) { $p->add('dialplan_detail_delete', 'temp'); //execute delete - $database = new database; - $database->app_name = $this->app_name; - $database->app_uuid = $this->app_uuid; - $database->delete($array); + $this->database->app_name = $this->app_name; + $this->database->app_uuid = $this->app_uuid; + $this->database->delete($array); unset($array); //revoke temporary permissions @@ -1255,8 +1256,7 @@ if (!class_exists('destinations')) { if (!(!empty($_GET['show']) && $_GET['show'] === 'all' && permission_exists('destination_summary_all'))) { $parameters['domain_uuid'] = $this->domain_uuid; } - $database = new database; - $summary = $database->select($sql, $parameters, 'all'); + $summary = $this->database->select($sql, $parameters, 'all'); unset($parameters); //if (!empty($this->start_stamp_begin) && !empty($this->start_stamp_end)) { From e58a55df97843bbcca04e5e32e9bb1f1b971cda5 Mon Sep 17 00:00:00 2001 From: fusionate Date: Mon, 20 Jan 2025 09:10:04 -0700 Subject: [PATCH 06/89] Password Reset: Adjustment to re-enable password match indication. --- resources/login.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/login.php b/resources/login.php index 4e0c033ac8..19e64870f8 100644 --- a/resources/login.php +++ b/resources/login.php @@ -412,7 +412,7 @@ echo "
".$text['label-password_reset']."
\n"; echo "
\n"; echo " \n"; - echo " \n"; + //echo " \n"; //echo "
\n"; echo "
\n"; echo "
"; @@ -424,7 +424,7 @@ echo " \n"; echo " \n"; + +if ($dashboard_details_state != 'disabled') { +echo "
\n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; + $row_style[false] = "row_style0"; + $row_style[true] = "row_style1"; + $c = true; + foreach ($services as $name => $enabled) { + echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; + $c = !$c; + } +echo "
".($text['label-service'] ?? 'Service')."".($text['label-running'] ?? 'Running')."
$name" . ($enabled ? $text['label-yes'] ?? 'Yes' : $text['label-no'] ?? 'No') . "
\n"; +echo "
\n"; +} +echo "\n"; From aa75be76e77af88cc222f890006e505bb10f7325 Mon Sep 17 00:00:00 2001 From: fusionate Date: Tue, 28 Jan 2025 11:58:32 -0700 Subject: [PATCH 21/89] Yealink App: Fix UUID in a previous commit. This was preventing the App Defaults to run properly, because the database was rejecting the UUID value. --- app/yealink/app_config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/yealink/app_config.php b/app/yealink/app_config.php index ed32e50259..31ad1f0320 100644 --- a/app/yealink/app_config.php +++ b/app/yealink/app_config.php @@ -272,7 +272,7 @@ $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "false"; $apps[$x]['default_settings'][$y]['default_setting_description'] = "URL for Yealink Super Search XML configuration file"; $y++; - $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "9c704e81-cbb4-4cb3-ab1c-427755008714c"; + $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "9c704e81-cbb4-4cb3-ab1c-427755008714"; $apps[$x]['default_settings'][$y]['default_setting_category'] = "provision"; $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "yealink_t33g_wallpaper"; $apps[$x]['default_settings'][$y]['default_setting_name'] = "text"; From 7c887184ffecb4da6bdb1f2ece0425049c29addc Mon Sep 17 00:00:00 2001 From: frytimo Date: Tue, 28 Jan 2025 15:17:04 -0400 Subject: [PATCH 22/89] adjust system service dashboard widget to not show by default (#7233) --- app/system/resources/dashboard/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/system/resources/dashboard/config.php b/app/system/resources/dashboard/config.php index bdaa3f7d0a..933ea2363a 100644 --- a/app/system/resources/dashboard/config.php +++ b/app/system/resources/dashboard/config.php @@ -70,7 +70,7 @@ $array['dashboard'][$x]['dashboard_column_span'] = '1'; $array['dashboard'][$x]['dashboard_row_span'] = '2'; $array['dashboard'][$x]['dashboard_details_state'] = 'hidden'; $array['dashboard'][$x]['dashboard_order'] = '110'; -$array['dashboard'][$x]['dashboard_enabled'] = 'true'; +$array['dashboard'][$x]['dashboard_enabled'] = 'false'; $array['dashboard'][$x]['dashboard_description'] = 'A list of showing the count of active and inactive services'; $y = 0; $array['dashboard'][$x]['dashboard_groups'][$y]['dashboard_group_uuid'] = '719d8a56-00b2-437e-83c0-a9e5005a53c5'; From 14288772d57d87188f32538798615ae01a33d969 Mon Sep 17 00:00:00 2001 From: fusionate Date: Tue, 28 Jan 2025 12:53:32 -0700 Subject: [PATCH 23/89] Yealink App: Replace an invalid UUID. --- app/yealink/app_config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/yealink/app_config.php b/app/yealink/app_config.php index 31ad1f0320..cff1b28fe1 100644 --- a/app/yealink/app_config.php +++ b/app/yealink/app_config.php @@ -288,7 +288,7 @@ $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "false"; $apps[$x]['default_settings'][$y]['default_setting_description'] = "Wallpaper to load on to T33G screen"; $y++; - $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "9ddc080dd-0157-4eea-90b7-ca288a938d43"; + $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "ab97779a-8d32-4ab4-a88f-4ea1433d00ba"; $apps[$x]['default_settings'][$y]['default_setting_category'] = "provision"; $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "yealink_t46s_wallpaper"; $apps[$x]['default_settings'][$y]['default_setting_name'] = "text"; From a4f83539baa5434d37fc77fe9fe9b9dddca83cb9 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Tue, 28 Jan 2025 12:54:09 -0700 Subject: [PATCH 24/89] Update login.php --- resources/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/login.php b/resources/login.php index 19e64870f8..b4227bf727 100644 --- a/resources/login.php +++ b/resources/login.php @@ -62,7 +62,7 @@ //set the email address $email = $_REQUEST['email']; - //see if email existsesources/login.php?action=request + //see if email exists $sql = "select "; $sql .= "user_uuid, "; $sql .= "username, "; From b8b796316e74a754db2566bd5a48beeaaac19c9f Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Tue, 28 Jan 2025 15:35:02 -0700 Subject: [PATCH 25/89] Add method column_exists to the database class --- resources/classes/database.php | 84 +++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/resources/classes/database.php b/resources/classes/database.php index 37d6bd0f0d..f745b8a489 100644 --- a/resources/classes/database.php +++ b/resources/classes/database.php @@ -297,7 +297,6 @@ //driver and type point to the same value $this->driver = $config->get('database.0.type', 'pgsql'); - $this->driver = $config->get('database.0.type', 'pgsql'); $this->type = $config->get('database.0.type', 'pgsql'); $this->host = $config->get('database.0.host', '127.0.0.1'); $this->port = $config->get('database.0.port', '5432'); @@ -787,6 +786,89 @@ } } + /** + * Checks if the column exists in the database. + *

Note:
+ * Tables and Column names must be sanitized. Otherwise, a warning will be + * emitted and false will be returned.

+ * @param type $table_name Sanitized name of the table to search for. + * @param type $column_name Sanitized name of the column to search for. + * @return boolean Returns true if the column exists and false if it does not. + * @depends connect() + */ + public function column_exists ($table_name, $column_name) { + //sanitize the table name + if (self::sanitize($table_name) != $table_name) { + trigger_error('Table Name must be sanitized', E_USER_WARNING); + return false; + } + + //sanitize the column name + if (self::sanitize($column_name) != $column_name) { + trigger_error('Column Name must be sanitized', E_USER_WARNING); + return false; + } + + //connect to the database if needed + if (!$this->db) { + $this->connect(); + } + + //if unable to connect to the database + if (!$this->db) { + $backtrace = debug_backtrace(); + echo "Connection Failed
\n"; + echo "line number ".__line__."
\n"; + echo "
";
+					print_r($backtrace);
+					echo "
"; + return false; + } + + //check the sqlite database to see if the column exists + //if ($this->db_type == "sqlite") { + // $table_info = $this->table_info($table_name); + // if ($this->sqlite_column_exists($table_info, $column_name)) { + // return true; + // } + // else { + // return false; + // } + //} + + //check the postgresql database to see if the column exists + if ($this->type == "pgsql") { + $sql = "SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$table_name' limit 1) AND attname = '$column_name'; "; + } + + //check the mysql database to see if the column exists + if ($this->type == "mysql") { + //$sql .= "SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = '$db_name' and TABLE_NAME = '$table_name' and COLUMN_NAME = '$column_name' "; + $sql = "show columns from $table_name where field = '$column_name' "; + } + + //return the results from the sql query + if (empty($sql)) { + return false; + } + else { + $prep_statement = $this->db->prepare($sql); + $prep_statement->execute(); + $result = $prep_statement->fetchAll(PDO::FETCH_NAMED); + if (!$result) { + return false; + } + if (count($result) > 0) { + return true; + } + else { + return false; + } + unset ($prep_statement); + } + + } + /** * Queries {@link database::table_info()} to return the fields. * @access public From 42a1625daa83ce87671d7a7f504ab77efbe55c4a Mon Sep 17 00:00:00 2001 From: fusionate Date: Tue, 28 Jan 2025 15:54:35 -0700 Subject: [PATCH 26/89] Contact - Phone: Prevent duplicate speed dial numbers. --- core/contacts/app_languages.php | 25 +++++++++++++++++++++++++ core/contacts/contact_edit.php | 28 +++++++++++++++++++++++++++- core/contacts/contact_phone_edit.php | 26 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/core/contacts/app_languages.php b/core/contacts/app_languages.php index e8825a4c77..0a86f3826a 100644 --- a/core/contacts/app_languages.php +++ b/core/contacts/app_languages.php @@ -1793,6 +1793,31 @@ $text['message-uploaded']['zh-cn'] = "文件已上传"; $text['message-uploaded']['ja-jp'] = "ファイルがアップロードされました"; $text['message-uploaded']['ko-kr'] = "업로드된 파일"; +$text['message-speed_dial_exists']['en-us'] = "Speed Dial Number Already Exists"; +$text['message-speed_dial_exists']['en-gb'] = "Speed Dial Number Already Exists"; +$text['message-speed_dial_exists']['ar-eg'] = "رقم الاتصال السريع موجود بالفعل"; +$text['message-speed_dial_exists']['de-at'] = "Kurzwahlnummer existiert bereits"; +$text['message-speed_dial_exists']['de-ch'] = "Kurzwahlnummer existiert bereits"; +$text['message-speed_dial_exists']['de-de'] = "Kurzwahlnummer existiert bereits"; +$text['message-speed_dial_exists']['es-cl'] = "El número de marcación rápida ya existe"; +$text['message-speed_dial_exists']['es-mx'] = "El número de marcación rápida ya existe"; +$text['message-speed_dial_exists']['fr-ca'] = "Le numéro abrégé existe déjà"; +$text['message-speed_dial_exists']['fr-fr'] = "Le numéro de numérotation rapide existe déjà"; +$text['message-speed_dial_exists']['he-il'] = "מספר חיוג מהיר כבר קיים"; +$text['message-speed_dial_exists']['it-it'] = "Il numero di selezione rapida esiste già"; +$text['message-speed_dial_exists']['ka-ge'] = "სწრაფი აკრეფის ნომერი უკვე არსებობს"; +$text['message-speed_dial_exists']['nl-nl'] = "Snelkiesnummer bestaat al"; +$text['message-speed_dial_exists']['pl-pl'] = "Numer szybkiego wybierania już istnieje"; +$text['message-speed_dial_exists']['pt-br'] = "Número de discagem rápida já existe"; +$text['message-speed_dial_exists']['pt-pt'] = "O número de marcação rápida já existe"; +$text['message-speed_dial_exists']['ro-ro'] = "Numărul de apelare rapidă există deja"; +$text['message-speed_dial_exists']['ru-ru'] = "Номер быстрого набора уже существует"; +$text['message-speed_dial_exists']['sv-se'] = "Snabbuppringningsnummer finns redan"; +$text['message-speed_dial_exists']['uk-ua'] = "Номер швидкого набору вже існує"; +$text['message-speed_dial_exists']['zh-cn'] = "快速拨号号码已存在"; +$text['message-speed_dial_exists']['ja-jp'] = "短縮ダイヤル番号は既に存在します"; +$text['message-speed_dial_exists']['ko-kr'] = "단축번호가 이미 존재합니다"; + $text['label-voice']['en-us'] = "Voice"; $text['label-voice']['en-gb'] = "Voice"; $text['label-voice']['ar-eg'] = "صوت"; diff --git a/core/contacts/contact_edit.php b/core/contacts/contact_edit.php index d8d1767eab..75e7caf809 100644 --- a/core/contacts/contact_edit.php +++ b/core/contacts/contact_edit.php @@ -367,7 +367,33 @@ if (!empty($contact_phones)) { foreach ($contact_phones as $row) { if (!empty($row['phone_number'])) { - //add the speed dial + + //if speed dial number already exists, empty before save + if (!empty($row["phone_speed_dial"])) { + $phone_speed_dial_exists = false; + if (is_numeric($row["phone_speed_dial"])) { + $sql = "select count(contact_phone_uuid) "; + $sql .= "from v_contact_phones "; + $sql .= "where phone_speed_dial = :phone_speed_dial "; + $sql .= "and domain_uuid = :domain_uuid "; + if ($action == "update" && is_uuid($row["contact_phone_uuid"])) { + $sql .= "and contact_phone_uuid <> :contact_phone_uuid "; + $parameters['contact_phone_uuid'] = $row["contact_phone_uuid"]; + } + $parameters['phone_speed_dial'] = $row["phone_speed_dial"]; + $parameters['domain_uuid'] = $_SESSION['domain_uuid']; + $database = new database; + if (!empty($database->execute($sql, $parameters, 'column'))) { + $phone_speed_dial_exists = true; + } + unset($sql, $parameters); + } + if (!is_numeric($row["phone_speed_dial"]) || $phone_speed_dial_exists) { + message::add($text['message-speed_dial_exists'],'negative'); + unset($row["phone_speed_dial"]); + } + } + $array['contacts'][0]['contact_phones'][$y]['domain_uuid'] = $_SESSION['domain_uuid']; $array['contacts'][0]['contact_phones'][$y]['contact_uuid'] = $contact_uuid; $array['contacts'][0]['contact_phones'][$y]['contact_phone_uuid'] = $row["contact_phone_uuid"]; diff --git a/core/contacts/contact_phone_edit.php b/core/contacts/contact_phone_edit.php index c999eb7aec..acb196b05f 100644 --- a/core/contacts/contact_phone_edit.php +++ b/core/contacts/contact_phone_edit.php @@ -155,6 +155,32 @@ unset($sql, $parameters); } + //if speed dial number already exists, empty before save + if (!empty($phone_speed_dial)) { + $phone_speed_dial_exists = false; + if (is_numeric($phone_speed_dial)) { + $sql = "select count(contact_phone_uuid) "; + $sql .= "from v_contact_phones "; + $sql .= "where phone_speed_dial = :phone_speed_dial "; + $sql .= "and domain_uuid = :domain_uuid "; + if ($action == "update") { + $sql .= "and contact_uuid <> :contact_uuid "; + $parameters['contact_uuid'] = $contact_uuid; + } + $parameters['phone_speed_dial'] = $phone_speed_dial; + $parameters['domain_uuid'] = $domain_uuid; + $database = new database; + if (!empty($database->execute($sql, $parameters, 'column'))) { + $phone_speed_dial_exists = true; + } + unset($sql, $parameters); + } + if (!is_numeric($phone_speed_dial) || $phone_speed_dial_exists) { + message::add($text['message-speed_dial_exists'],'negative'); + unset($phone_speed_dial); + } + } + //add the phone if ($action == "add" && permission_exists('contact_phone_add')) { $contact_phone_uuid = uuid(); From fe0680f9b17a8903b97d80c93b42897c03dbc154 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Tue, 28 Jan 2025 15:59:04 -0700 Subject: [PATCH 27/89] Handle columns in the table that may not exist The old v_device_keys column device_profile_uuid is deprecated. It will exist on systems that were upgraded from an older version before the change was made. The app default code here moves data from the old format to the newer one. This is useful for upgrades. Newer installs will not have this deprecated field in the device_keys and device_settings table. --- app/devices/app_defaults.php | 145 ++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/app/devices/app_defaults.php b/app/devices/app_defaults.php index 9dde91d806..1df2f32a0b 100644 --- a/app/devices/app_defaults.php +++ b/app/devices/app_defaults.php @@ -77,86 +77,90 @@ if ($domains_processed == 1) { unset($sql, $device_keys); //set the device profile keys - $sql = "select count(*) from v_device_profile_keys "; - $num_rows = $database->select($sql, null, 'column'); - if ($num_rows == 0) { - //get the device profile keys from device_keys table - $sql = "select * from v_device_keys "; - $sql .= "where device_profile_uuid is not null "; - $device_profile_keys = $database->select($sql, null, 'all'); + if ($database->column_exists('v_device_keys', 'device_profile_uuid')) { + $sql = "select count(*) from v_device_profile_keys "; + $num_rows = $database->select($sql, null, 'column'); + if ($num_rows == 0) { + //get the device profile keys from device_keys table + $sql = "select * from v_device_keys "; + $sql .= "where device_profile_uuid is not null "; + $device_profile_keys = $database->select($sql, null, 'all'); - //loop through the device_keys to build the data array - if (!empty($device_profile_keys)) { - foreach ($device_profile_keys as $index => $row) { - $array['device_profile_keys'][$index]['device_profile_key_uuid'] = $row["device_key_uuid"]; - $array['device_profile_keys'][$index]['domain_uuid'] = $row["domain_uuid"]; - $array['device_profile_keys'][$index]['device_profile_uuid'] = $row["device_profile_uuid"]; - $array['device_profile_keys'][$index]['profile_key_id'] = $row["device_key_id"]; - $array['device_profile_keys'][$index]['profile_key_category'] = $row["device_key_category"]; - $array['device_profile_keys'][$index]['profile_key_vendor'] = $row["device_key_vendor"]; - $array['device_profile_keys'][$index]['profile_key_type'] = $row["device_key_type"]; - $array['device_profile_keys'][$index]['profile_key_line'] = $row["device_key_line"]; - $array['device_profile_keys'][$index]['profile_key_value'] = $row["device_key_value"]; - $array['device_profile_keys'][$index]['profile_key_extension'] = $row["device_key_extension"]; - $array['device_profile_keys'][$index]['profile_key_protected'] = $row["device_key_protected"]; - $array['device_profile_keys'][$index]['profile_key_label'] = $row["device_key_label"]; - $array['device_profile_keys'][$index]['profile_key_icon'] = $row["device_key_icon"]; + //loop through the device_keys to build the data array + if (!empty($device_profile_keys)) { + foreach ($device_profile_keys as $index => $row) { + $array['device_profile_keys'][$index]['device_profile_key_uuid'] = $row["device_key_uuid"]; + $array['device_profile_keys'][$index]['domain_uuid'] = $row["domain_uuid"]; + $array['device_profile_keys'][$index]['device_profile_uuid'] = $row["device_profile_uuid"]; + $array['device_profile_keys'][$index]['profile_key_id'] = $row["device_key_id"]; + $array['device_profile_keys'][$index]['profile_key_category'] = $row["device_key_category"]; + $array['device_profile_keys'][$index]['profile_key_vendor'] = $row["device_key_vendor"]; + $array['device_profile_keys'][$index]['profile_key_type'] = $row["device_key_type"]; + $array['device_profile_keys'][$index]['profile_key_line'] = $row["device_key_line"]; + $array['device_profile_keys'][$index]['profile_key_value'] = $row["device_key_value"]; + $array['device_profile_keys'][$index]['profile_key_extension'] = $row["device_key_extension"]; + $array['device_profile_keys'][$index]['profile_key_protected'] = $row["device_key_protected"]; + $array['device_profile_keys'][$index]['profile_key_label'] = $row["device_key_label"]; + $array['device_profile_keys'][$index]['profile_key_icon'] = $row["device_key_icon"]; + } + } + + //save the array + if (!empty($array)) { + $p = permissions::new(); + $p->add('device_profile_key_add', 'temp'); + + $database->app_name = 'devices'; + $database->app_uuid = '4efa1a1a-32e7-bf83-534b-6c8299958a8e'; + $database->save($array); + $response = $database->message; + unset($array); + + $p->delete('device_profile_key_add', 'temp'); } } - - //save the array - if (!empty($array)) { - $p = permissions::new(); - $p->add('device_profile_key_add', 'temp'); - - $database->app_name = 'devices'; - $database->app_uuid = '4efa1a1a-32e7-bf83-534b-6c8299958a8e'; - $database->save($array); - $response = $database->message; - unset($array); - - $p->delete('device_profile_key_add', 'temp'); - } + unset($sql, $device_profile_keys); } - unset($sql, $device_profile_keys); //set the device profile settings - $sql = "select count(*) from v_device_profile_settings "; - $num_rows = $database->select($sql, null, 'column'); - if ($num_rows == 0) { - //get the device profile keys from device_keys table - $sql = "select * from v_device_settings "; - $sql .= "where device_profile_uuid is not null "; - $device_profile_keys = $database->select($sql, null, 'all'); + if ($database->column_exists('v_device_settings', 'device_profile_uuid')) { + $sql = "select count(*) from v_device_profile_settings "; + $num_rows = $database->select($sql, null, 'column'); + if ($num_rows == 0) { + //get the device profile keys from device_keys table + $sql = "select * from v_device_settings "; + $sql .= "where device_profile_uuid is not null "; + $device_profile_keys = $database->select($sql, null, 'all'); - //loop through the device_keys to build the data array - if (!empty($device_profile_keys)) { - foreach ($device_profile_keys as $index => $row) { - $array['device_profile_settings'][$index]['device_profile_setting_uuid'] = $row["device_setting_uuid"]; - $array['device_profile_settings'][$index]['domain_uuid'] = $row["domain_uuid"]; - $array['device_profile_settings'][$index]['device_profile_uuid'] = $row["device_profile_uuid"]; - $array['device_profile_settings'][$index]['profile_setting_name'] = $row["device_setting_subcategory"]; - $array['device_profile_settings'][$index]['profile_setting_value'] = $row["device_setting_value"]; - $array['device_profile_settings'][$index]['profile_setting_enabled'] = $row["device_setting_enabled"]; - $array['device_profile_settings'][$index]['profile_setting_description'] = $row["device_setting_description"]; + //loop through the device_keys to build the data array + if (!empty($device_profile_keys)) { + foreach ($device_profile_keys as $index => $row) { + $array['device_profile_settings'][$index]['device_profile_setting_uuid'] = $row["device_setting_uuid"]; + $array['device_profile_settings'][$index]['domain_uuid'] = $row["domain_uuid"]; + $array['device_profile_settings'][$index]['device_profile_uuid'] = $row["device_profile_uuid"]; + $array['device_profile_settings'][$index]['profile_setting_name'] = $row["device_setting_subcategory"]; + $array['device_profile_settings'][$index]['profile_setting_value'] = $row["device_setting_value"]; + $array['device_profile_settings'][$index]['profile_setting_enabled'] = $row["device_setting_enabled"]; + $array['device_profile_settings'][$index]['profile_setting_description'] = $row["device_setting_description"]; + } + } + + //save the array + if (!empty($array)) { + $p = permissions::new(); + $p->add('device_profile_setting_add', 'temp'); + + $database->app_name = 'devices'; + $database->app_uuid = '4efa1a1a-32e7-bf83-534b-6c8299958a8e'; + $database->save($array); + $response = $database->message; + unset($array); + + $p->delete('device_profile_setting_add', 'temp'); } } - - //save the array - if (!empty($array)) { - $p = permissions::new(); - $p->add('device_profile_setting_add', 'temp'); - - $database->app_name = 'devices'; - $database->app_uuid = '4efa1a1a-32e7-bf83-534b-6c8299958a8e'; - $database->save($array); - $response = $database->message; - unset($array); - - $p->delete('device_profile_setting_add', 'temp'); - } + unset($sql, $device_profile_keys); } - unset($sql, $device_profile_keys); //add device vendor functions to the database $sql = "select count(*) from v_device_vendors; "; @@ -247,6 +251,7 @@ if ($domains_processed == 1) { $sql = "update v_device_lines set label = display_name where label is null;\n"; $database->execute($sql); unset($sql); + } ?> From 9106c7fbfef0b91c5d52d09d6dd002ccaeb7ed48 Mon Sep 17 00:00:00 2001 From: fusionate Date: Tue, 28 Jan 2025 16:11:21 -0700 Subject: [PATCH 28/89] Contact - Phone: Adjust to even check same contact for duplicate speed dial numbers. --- core/contacts/contact_phone_edit.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/contacts/contact_phone_edit.php b/core/contacts/contact_phone_edit.php index acb196b05f..f204491500 100644 --- a/core/contacts/contact_phone_edit.php +++ b/core/contacts/contact_phone_edit.php @@ -163,9 +163,9 @@ $sql .= "from v_contact_phones "; $sql .= "where phone_speed_dial = :phone_speed_dial "; $sql .= "and domain_uuid = :domain_uuid "; - if ($action == "update") { - $sql .= "and contact_uuid <> :contact_uuid "; - $parameters['contact_uuid'] = $contact_uuid; + if ($action == "update" && is_uuid($contact_phone_uuid)) { + $sql .= "and contact_phone_uuid <> :contact_phone_uuid "; + $parameters['contact_phone_uuid'] = $contact_phone_uuid; } $parameters['phone_speed_dial'] = $phone_speed_dial; $parameters['domain_uuid'] = $domain_uuid; From 3144036ae04044ec31e370dd90c0449fe158fbd2 Mon Sep 17 00:00:00 2001 From: frytimo Date: Tue, 28 Jan 2025 19:20:43 -0400 Subject: [PATCH 29/89] add new menu upgrade option to reset file permissions (#7232) * add new menu upgrade option to reset file permissions --- core/upgrade/app_languages.php | 187 ++++++++++++++++++++++++++++----- core/upgrade/upgrade_menu.php | 68 +++++++++++- 2 files changed, 224 insertions(+), 31 deletions(-) diff --git a/core/upgrade/app_languages.php b/core/upgrade/app_languages.php index 351841051e..74b3d9c625 100644 --- a/core/upgrade/app_languages.php +++ b/core/upgrade/app_languages.php @@ -594,6 +594,33 @@ $text['label-upgrade_permissions']['zh-cn'] = "权限默认值"; $text['label-upgrade_permissions']['ja-jp'] = "許可のデフォルト"; $text['label-upgrade_permissions']['ko-kr'] = "권한 기본값"; +$text['label-update_filesystem_permissions']['en-us'] = "Filesystem Permissions"; +$text['label-update_filesystem_permissions']['en-gb'] = "Filesystem Permissions"; +$text['label-update_filesystem_permissions']['ar-eg'] = ""; +$text['label-update_filesystem_permissions']['de-at'] = ""; +$text['label-update_filesystem_permissions']['de-ch'] = ""; +$text['label-update_filesystem_permissions']['de-de'] = ""; +$text['label-update_filesystem_permissions']['el-gr'] = ""; +$text['label-update_filesystem_permissions']['es-cl'] = ""; +$text['label-update_filesystem_permissions']['es-mx'] = ""; +$text['label-update_filesystem_permissions']['fr-ca'] = ""; +$text['label-update_filesystem_permissions']['fr-fr'] = ""; +$text['label-update_filesystem_permissions']['he-il'] = ""; +$text['label-update_filesystem_permissions']['it-it'] = ""; +$text['label-update_filesystem_permissions']['ka-ge'] = ""; +$text['label-update_filesystem_permissions']['nl-nl'] = ""; +$text['label-update_filesystem_permissions']['pl-pl'] = ""; +$text['label-update_filesystem_permissions']['pt-br'] = ""; +$text['label-update_filesystem_permissions']['pt-pt'] = ""; +$text['label-update_filesystem_permissions']['ro-ro'] = ""; +$text['label-update_filesystem_permissions']['ru-ru'] = ""; +$text['label-update_filesystem_permissions']['sv-se'] = ""; +$text['label-update_filesystem_permissions']['uk-ua'] = ""; +$text['label-update_filesystem_permissions']['tr-tr'] = ""; +$text['label-update_filesystem_permissions']['zh-cn'] = ""; +$text['label-update_filesystem_permissions']['ja-jp'] = ""; +$text['label-update_filesystem_permissions']['ko-kr'] = ""; + $text['label-upgrade_menu']['en-us'] = "Menu Defaults"; $text['label-upgrade_menu']['en-gb'] = "Menu Defaults"; $text['label-upgrade_menu']['ar-eg'] = "افتراضيات القائمة"; @@ -1242,6 +1269,87 @@ $text['description-upgrade_permissions']['zh-cn'] = "还原默认组权限。"; $text['description-upgrade_permissions']['ja-jp'] = "デフォルトのグループ許可を復元します。"; $text['description-upgrade_permissions']['ko-kr'] = "기본 그룹 권한을 복원합니다."; +$text['description-update_filesystem_permissions']['en-us'] = 'Update the filesystem permissions to use user www-data'; +$text['description-update_filesystem_permissions']['en-gb'] = 'Update the filesystem permissions to use user www-data'; +$text['description-update_filesystem_permissions']['ar-eg'] = 'تحديث أذونات نظام الملفات لاستخدام بيانات المستخدم www-data'; +$text['description-update_filesystem_permissions']['de-at'] = 'Aktualisieren Sie die Dateisystemberechtigungen, um den Benutzer www-data zu verwenden'; +$text['description-update_filesystem_permissions']['de-ch'] = 'Aktualisieren Sie die Dateisystemberechtigungen, um den Benutzer www-data zu verwenden'; +$text['description-update_filesystem_permissions']['de-de'] = 'Aktualisieren Sie die Dateisystemberechtigungen, um den Benutzer www-data zu verwenden'; +$text['description-update_filesystem_permissions']['el-gr'] = 'Ενημερώστε τα δικαιώματα του συστήματος αρχείων για να χρησιμοποιήσετε τα www-data χρήστη'; +$text['description-update_filesystem_permissions']['es-cl'] = 'Actualice los permisos del sistema de archivos para utilizar el usuario www-data'; +$text['description-update_filesystem_permissions']['es-mx'] = 'Actualice los permisos del sistema de archivos para utilizar el usuario www-data'; +$text['description-update_filesystem_permissions']['fr-ca'] = 'Mettre à jour les autorisations du système de fichiers pour utiliser l'utilisateur www-data'; +$text['description-update_filesystem_permissions']['fr-fr'] = 'Mettre à jour les autorisations du système de fichiers pour utiliser l'utilisateur www-data'; +$text['description-update_filesystem_permissions']['he-il'] = 'עדכן את הרשאות מערכת הקבצים כדי להשתמש ב-www-data של המשתמש'; +$text['description-update_filesystem_permissions']['it-it'] = 'Aggiornare i permessi del file system per utilizzare l'utente www-data'; +$text['description-update_filesystem_permissions']['ka-ge'] = 'განაახლეთ ფაილური სისტემის ნებართვები მომხმარებლის www-data-ის გამოსაყენებლად'; +$text['description-update_filesystem_permissions']['nl-nl'] = 'Werk de bestandssysteemmachtigingen bij om de gebruiker www-data te gebruiken'; +$text['description-update_filesystem_permissions']['pl-pl'] = 'Zaktualizuj uprawnienia systemu plików, aby użyć użytkownika www-data'; +$text['description-update_filesystem_permissions']['pt-br'] = 'Atualize as permissões do sistema de arquivos para usar o usuário www-data'; +$text['description-update_filesystem_permissions']['pt-pt'] = 'Atualize as permissões do sistema de arquivos para usar o usuário www-data'; +$text['description-update_filesystem_permissions']['ro-ro'] = 'Actualizați permisiunile sistemului de fișiere pentru a utiliza www-data utilizatorului'; +$text['description-update_filesystem_permissions']['ru-ru'] = 'Обновите разрешения файловой системы для использования пользователя www-data'; +$text['description-update_filesystem_permissions']['sv-se'] = 'Uppdatera filsystemets behörigheter för att använda användarens www-data'; +$text['description-update_filesystem_permissions']['uk-ua'] = 'Оновіть дозволи файлової системи, щоб використовувати дані користувача www'; +$text['description-update_filesystem_permissions']['tr-tr'] = 'Dosya sistemi izinlerini www-data kullanıcısını kullanacak şekilde güncelleyin'; +$text['description-update_filesystem_permissions']['zh-cn'] = '更新文件系统权限以使用用户 www-data'; +$text['description-update_filesystem_permissions']['ja-jp'] = 'ユーザーwww-dataを使用するためにファイルシステムの権限を更新します'; +$text['description-update_filesystem_permissions']['ko-kr'] = '사용자 www-data를 사용하기 위해 파일 시스템 권한을 업데이트합니다.'; + +$text['label-header1']['en-us'] = 'Root account or sudo account must be used for this option'; +$text['label-header1']['en-gb'] = 'Root account or sudo account must be used for this option'; +$text['label-header1']['ar-eg'] = 'يجب استخدام حساب الجذر أو حساب sudo لهذا الخيار'; +$text['label-header1']['de-at'] = 'Für diese Option muss ein Root-Konto oder ein Sudo-Konto verwendet werden.'; +$text['label-header1']['de-ch'] = 'Für diese Option muss ein Root-Konto oder ein Sudo-Konto verwendet werden.'; +$text['label-header1']['de-de'] = 'Für diese Option muss ein Root-Konto oder ein Sudo-Konto verwendet werden.'; +$text['label-header1']['el-gr'] = 'Για αυτήν την επιλογή πρέπει να χρησιμοποιηθεί λογαριασμός ρίζας ή λογαριασμός sudo'; +$text['label-header1']['es-cl'] = 'Se debe utilizar una cuenta raíz o una cuenta sudo para esta opción'; +$text['label-header1']['es-mx'] = 'Se debe utilizar una cuenta raíz o una cuenta sudo para esta opción'; +$text['label-header1']['fr-ca'] = 'Un compte root ou un compte sudo doit être utilisé pour cette option'; +$text['label-header1']['fr-fr'] = 'Un compte root ou un compte sudo doit être utilisé pour cette option'; +$text['label-header1']['he-il'] = 'יש להשתמש בחשבון שורש או חשבון sudo עבור אפשרות זו'; +$text['label-header1']['it-it'] = 'Per questa opzione è necessario utilizzare un account root o un account sudo'; +$text['label-header1']['ka-ge'] = 'Root ან sudo ანგარიში უნდა იყოს გამოყენებული ამ ვარიანტისთვის'; +$text['label-header1']['nl-nl'] = 'Voor deze optie moet een root-account of sudo-account worden gebruikt'; +$text['label-header1']['pl-pl'] = 'Do tej opcji należy użyć konta root lub sudo'; +$text['label-header1']['pt-br'] = 'A conta root ou sudo deve ser usada para esta opção'; +$text['label-header1']['pt-pt'] = 'A conta root ou sudo deve ser usada para esta opção'; +$text['label-header1']['ro-ro'] = 'Contul root sau contul sudo trebuie utilizat pentru această opțiune'; +$text['label-header1']['ru-ru'] = 'Для этой опции необходимо использовать учетную запись root или sudo.'; +$text['label-header1']['sv-se'] = 'Root-konto eller sudo-konto måste användas för detta alternativ'; +$text['label-header1']['uk-ua'] = 'Для цієї опції необхідно використовувати обліковий запис root або sudo'; +$text['label-header1']['tr-tr'] = 'Bu seçenek için kök hesap veya sudo hesabı kullanılmalıdır'; +$text['label-header1']['zh-cn'] = '此选项必须使用 root 帐户或 sudo 帐户'; +$text['label-header1']['ja-jp'] = 'このオプションにはルートアカウントまたはsudoアカウントを使用する必要があります'; +$text['label-header1']['ko-kr'] = '이 옵션에는 루트 계정 또는 sudo 계정을 사용해야 합니다.'; + +$text['label-header2']['en-us'] = 'This option is used for resetting the permissions on the file system after executing commands using the root user account'; +$text['label-header2']['en-gb'] = 'This option is used for resetting the permissions on the file system after executing commands using the root user account'; +$text['label-header2']['ar-eg'] = 'يستخدم هذا الخيار لإعادة تعيين الأذونات على نظام الملفات بعد تنفيذ الأوامر باستخدام حساب المستخدم الجذر'; +$text['label-header2']['de-at'] = 'Diese Option wird zum Zurücksetzen der Berechtigungen für das Dateisystem verwendet, nachdem Befehle mit dem Root-Benutzerkonto ausgeführt wurden.'; +$text['label-header2']['de-ch'] = 'Diese Option wird zum Zurücksetzen der Berechtigungen für das Dateisystem verwendet, nachdem Befehle mit dem Root-Benutzerkonto ausgeführt wurden.'; +$text['label-header2']['de-de'] = 'Diese Option wird zum Zurücksetzen der Berechtigungen für das Dateisystem verwendet, nachdem Befehle mit dem Root-Benutzerkonto ausgeführt wurden.'; +$text['label-header2']['el-gr'] = 'Αυτή η επιλογή χρησιμοποιείται για την επαναφορά των δικαιωμάτων στο σύστημα αρχείων μετά την εκτέλεση εντολών χρησιμοποιώντας τον λογαριασμό χρήστη root'; +$text['label-header2']['es-cl'] = 'Esta opción se utiliza para restablecer los permisos en el sistema de archivos después de ejecutar comandos utilizando la cuenta de usuario root'; +$text['label-header2']['es-mx'] = 'Esta opción se utiliza para restablecer los permisos en el sistema de archivos después de ejecutar comandos utilizando la cuenta de usuario root'; +$text['label-header2']['fr-ca'] = 'Cette option est utilisée pour réinitialiser les autorisations sur le système de fichiers après l'exécution de commandes à l'aide du compte utilisateur root'; +$text['label-header2']['fr-fr'] = 'Cette option est utilisée pour réinitialiser les autorisations sur le système de fichiers après l'exécution de commandes à l'aide du compte utilisateur root'; +$text['label-header2']['he-il'] = 'אפשרות זו משמשת לאיפוס ההרשאות במערכת הקבצים לאחר ביצוע פקודות באמצעות חשבון המשתמש השורש'; +$text['label-header2']['it-it'] = 'Questa opzione viene utilizzata per reimpostare i permessi sul file system dopo l'esecuzione di comandi utilizzando l'account utente root'; +$text['label-header2']['ka-ge'] = 'ეს პარამეტრი გამოიყენება ფაილურ სისტემაზე ნებართვების გადატვირთვისთვის ბრძანებების შესრულების შემდეგ root მომხმარებლის ანგარიშის გამოყენებით'; +$text['label-header2']['nl-nl'] = 'Deze optie wordt gebruikt om de machtigingen op het bestandssysteem opnieuw in te stellen na het uitvoeren van opdrachten met behulp van het root-gebruikersaccount'; +$text['label-header2']['pl-pl'] = 'Ta opcja służy do resetowania uprawnień w systemie plików po wykonaniu poleceń przy użyciu konta użytkownika root'; +$text['label-header2']['pt-br'] = 'Esta opção é usada para redefinir as permissões no sistema de arquivos após executar comandos usando a conta de usuário root'; +$text['label-header2']['pt-pt'] = 'Esta opção é usada para redefinir as permissões no sistema de arquivos após executar comandos usando a conta de usuário root'; +$text['label-header2']['ro-ro'] = 'Această opțiune este utilizată pentru resetarea permisiunilor pe sistemul de fișiere după executarea comenzilor folosind contul de utilizator root'; +$text['label-header2']['ru-ru'] = 'Эта опция используется для сброса прав доступа к файловой системе после выполнения команд с использованием учетной записи пользователя root.'; +$text['label-header2']['sv-se'] = 'Det här alternativet används för att återställa behörigheterna på filsystemet efter att ha kört kommandon med root-användarkontot'; +$text['label-header2']['uk-ua'] = 'Цей параметр використовується для скидання дозволів на файлову систему після виконання команд за допомогою облікового запису користувача root'; +$text['label-header2']['tr-tr'] = 'Bu seçenek, kök kullanıcı hesabını kullanarak komutları yürüttükten sonra dosya sistemindeki izinleri sıfırlamak için kullanılır'; +$text['label-header2']['zh-cn'] = '此选项用于在使用 root 用户帐户执行命令后重置文件系统的权限'; +$text['label-header2']['ja-jp'] = 'このオプションは、ルートユーザーアカウントを使用してコマンドを実行した後にファイルシステムの権限をリセットするために使用されます。'; +$text['label-header2']['ko-kr'] = '이 옵션은 root 사용자 계정을 사용하여 명령을 실행한 후 파일 시스템의 권한을 재설정하는 데 사용됩니다.'; + $text['description-upgrade_menu']['en-us'] = "Restores the default items in the menu."; $text['description-upgrade_menu']['en-gb'] = "Restores the default items in the menu."; $text['description-upgrade_menu']['ar-eg'] = ""; @@ -1431,32 +1539,59 @@ $text['label-all_of_the_above']['zh-cn'] = "上述所有的"; $text['label-all_of_the_above']['ja-jp'] = "上記のすべて"; $text['label-all_of_the_above']['ko-kr'] = "무엇보다도"; -$text['description-all_of_the_above']['en-us'] = "Performs an upgrade using options 1a, 2, 2b, 3, 4, and 5 in succession."; -$text['description-all_of_the_above']['en-gb'] = "Performs an upgrade using options 1a, 2, 2b, 3, 4, and 5 in succession."; -$text['description-all_of_the_above']['ar-eg'] = "إجراء ترقية باستخدام الخيارات 1أ، و2، و2ب، و3، و4، و5 على التوالي."; -$text['description-all_of_the_above']['de-at'] = "Führt ein Upgrade mit den Optionen 1a, 2, 2b, 3, 4 und 5 nacheinander durch."; -$text['description-all_of_the_above']['de-ch'] = "Führt ein Upgrade mit den Optionen 1a, 2, 2b, 3, 4 und 5 nacheinander durch."; -$text['description-all_of_the_above']['de-de'] = "Führt ein Upgrade mit den Optionen 1a, 2, 2b, 3, 4 und 5 nacheinander durch."; -$text['description-all_of_the_above']['el-gr'] = "Εκτελεί μια αναβάθμιση χρησιμοποιώντας τις επιλογές 1a, 2, 2b, 3, 4 και 5 διαδοχικά."; -$text['description-all_of_the_above']['es-cl'] = "Realiza una actualización utilizando las opciones 1a, 2, 2b, 3, 4 y 5 en sucesión."; -$text['description-all_of_the_above']['es-mx'] = "Realiza una actualización utilizando las opciones 1a, 2, 2b, 3, 4 y 5 en sucesión."; -$text['description-all_of_the_above']['fr-ca'] = "Effectue une mise à niveau en utilisant successivement les options 1a, 2, 2b, 3, 4 et 5."; -$text['description-all_of_the_above']['fr-fr'] = "Effectue une mise à niveau en utilisant successivement les options 1a, 2, 2b, 3, 4 et 5."; -$text['description-all_of_the_above']['he-il'] = "מבצע שדרוג באמצעות אפשרויות 1a, 2, 2b, 3, 4 ו-5 ברצף."; -$text['description-all_of_the_above']['it-it'] = "Esegue un aggiornamento utilizzando le opzioni 1a, 2, 2b, 3, 4 e 5 in successione."; -$text['description-all_of_the_above']['ka-ge'] = "შეასრულებს განახლებას არჩევნებით 1ა, 2, 2ბ, 3, 4 და 5 ამ მიმდევრობით."; -$text['description-all_of_the_above']['nl-nl'] = "Voert een upgrade uit met achtereenvolgens de opties 1a, 2, 2b, 3, 4 en 5."; -$text['description-all_of_the_above']['pl-pl'] = "Wykonuje aktualizację, korzystając kolejno z opcji 1a, 2, 2b, 3, 4 i 5."; -$text['description-all_of_the_above']['pt-br'] = "Executa uma atualização usando as opções 1a, 2, 2b, 3, 4 e 5 em sucessão."; -$text['description-all_of_the_above']['pt-pt'] = "Executa uma atualização usando as opções 1a, 2, 2b, 3, 4 e 5 em sucessão."; -$text['description-all_of_the_above']['ro-ro'] = "Efectuează o actualizare folosind opțiunile 1a, 2, 2b, 3, 4 și 5 succesiv."; -$text['description-all_of_the_above']['ru-ru'] = "Выполняет обновление, последовательно используя параметры 1a, 2, 2b, 3, 4 и 5."; -$text['description-all_of_the_above']['sv-se'] = "Utför en uppgradering med alternativ 1a, 2, 2b, 3, 4 och 5 i följd."; -$text['description-all_of_the_above']['uk-ua'] = "Виконує оновлення, використовуючи послідовно параметри 1a, 2, 2b, 3, 4 і 5."; -$text['description-all_of_the_above']['tr-tr'] = "Art arda 1a, 2, 2b, 3, 4 ve 5 seçeneklerini kullanarak yükseltme gerçekleştirir."; -$text['description-all_of_the_above']['zh-cn'] = "连续使用选项 1a、2、2b、3、4 和 5 执行升级。"; -$text['description-all_of_the_above']['ja-jp'] = "オプション 1a、2、2b、3、4、および 5 を連続して使用してアップグレードを実行します。"; -$text['description-all_of_the_above']['ko-kr'] = "옵션 1a, 2, 2b, 3, 4, 5를 차례로 사용하여 업그레이드를 수행합니다."; +$text['label-not_running_as_root']['en-us'] = 'Not root user - operation skipped'; +$text['label-not_running_as_root']['en-gb'] = 'Not root user - operation skipped'; +$text['label-not_running_as_root']['ar-eg'] = 'ليس مستخدمًا جذريًا - تم تخطي العملية'; +$text['label-not_running_as_root']['de-at'] = 'Kein Root-Benutzer – Vorgang übersprungen'; +$text['label-not_running_as_root']['de-ch'] = 'Kein Root-Benutzer – Vorgang übersprungen'; +$text['label-not_running_as_root']['de-de'] = 'Kein Root-Benutzer – Vorgang übersprungen'; +$text['label-not_running_as_root']['el-gr'] = 'Δεν είναι χρήστης root - η λειτουργία παραβλέφθηκε'; +$text['label-not_running_as_root']['es-cl'] = 'No es usuario root: se omitió la operación'; +$text['label-not_running_as_root']['es-mx'] = 'No es usuario root: se omitió la operación'; +$text['label-not_running_as_root']['fr-ca'] = 'Pas d'utilisateur root - opération ignorée'; +$text['label-not_running_as_root']['fr-fr'] = 'Pas d'utilisateur root - opération ignorée'; +$text['label-not_running_as_root']['he-il'] = 'לא משתמש שורש - הפעולה דילגה'; +$text['label-not_running_as_root']['it-it'] = 'Utente non root: operazione saltata'; +$text['label-not_running_as_root']['ka-ge'] = 'არ არის root მომხმარებელი - ოპერაცია გამოტოვებულია'; +$text['label-not_running_as_root']['nl-nl'] = 'Geen rootgebruiker - bewerking overgeslagen'; +$text['label-not_running_as_root']['pl-pl'] = 'Nie użytkownik root - operacja pominięta'; +$text['label-not_running_as_root']['pt-br'] = 'Usuário não root - operação ignorada'; +$text['label-not_running_as_root']['pt-pt'] = 'Usuário não root - operação ignorada'; +$text['label-not_running_as_root']['ro-ro'] = 'Nu utilizatorul root - operația a fost omisă'; +$text['label-not_running_as_root']['ru-ru'] = 'Не пользователь root — операция пропущена'; +$text['label-not_running_as_root']['sv-se'] = 'Inte root-användare - åtgärden hoppades över'; +$text['label-not_running_as_root']['uk-ua'] = 'Не root користувач - операцію пропущено'; +$text['label-not_running_as_root']['tr-tr'] = 'Kök kullanıcı değil - işlem atlandı'; +$text['label-not_running_as_root']['zh-cn'] = '非 root 用户 – 操作已跳过'; +$text['label-not_running_as_root']['ja-jp'] = 'ルートユーザーではありません - 操作はスキップされました'; +$text['label-not_running_as_root']['ko-kr'] = '루트 사용자가 아닙니다. 작업이 건너뛰어졌습니다.'; + +$text['description-all_of_the_above']['en-us'] = 'Performs an upgrade using options 1a, 2, 2b, 3, 4, 5, and 6 in succession.'; +$text['description-all_of_the_above']['en-gb'] = 'Performs an upgrade using options 1a, 2, 2b, 3, 4, 5, and 6 in succession.'; +$text['description-all_of_the_above']['ar-eg'] = 'يقوم بإجراء ترقية باستخدام الخيارات 1أ، 2، 2ب، 3، 4، 5، و6 على التوالي.'; +$text['description-all_of_the_above']['de-at'] = 'Führt ein Upgrade nacheinander mit den Optionen 1a, 2, 2b, 3, 4, 5 und 6 durch.'; +$text['description-all_of_the_above']['de-ch'] = 'Führt ein Upgrade nacheinander mit den Optionen 1a, 2, 2b, 3, 4, 5 und 6 durch.'; +$text['description-all_of_the_above']['de-de'] = 'Führt ein Upgrade nacheinander mit den Optionen 1a, 2, 2b, 3, 4, 5 und 6 durch.'; +$text['description-all_of_the_above']['el-gr'] = 'Εκτελεί μια αναβάθμιση χρησιμοποιώντας τις επιλογές 1a, 2, 2b, 3, 4, 5 και 6 διαδοχικά.'; +$text['description-all_of_the_above']['es-cl'] = 'Realiza una actualización utilizando las opciones 1a, 2, 2b, 3, 4, 5 y 6 en sucesión.'; +$text['description-all_of_the_above']['es-mx'] = 'Realiza una actualización utilizando las opciones 1a, 2, 2b, 3, 4, 5 y 6 en sucesión.'; +$text['description-all_of_the_above']['fr-ca'] = 'Effectue une mise à niveau en utilisant successivement les options 1a, 2, 2b, 3, 4, 5 et 6.'; +$text['description-all_of_the_above']['fr-fr'] = 'Effectue une mise à niveau en utilisant successivement les options 1a, 2, 2b, 3, 4, 5 et 6.'; +$text['description-all_of_the_above']['he-il'] = 'מבצע שדרוג באמצעות אפשרויות 1a, 2, 2b, 3, 4, 5 ו-6 ברצף.'; +$text['description-all_of_the_above']['it-it'] = 'Esegue un aggiornamento utilizzando le opzioni 1a, 2, 2b, 3, 4, 5 e 6 in successione.'; +$text['description-all_of_the_above']['ka-ge'] = 'განაახლებს ზედიზედ 1a, 2, 2b, 3, 4, 5 და 6 ვარიანტების გამოყენებით.'; +$text['description-all_of_the_above']['nl-nl'] = 'Voert een upgrade uit met behulp van opties 1a, 2, 2b, 3, 4, 5 en 6 achtereenvolgens.'; +$text['description-all_of_the_above']['pl-pl'] = 'Wykonuje aktualizację, korzystając kolejno z opcji 1a, 2, 2b, 3, 4, 5 i 6.'; +$text['description-all_of_the_above']['pt-br'] = 'Executa uma atualização usando as opções 1a, 2, 2b, 3, 4, 5 e 6 em sucessão.'; +$text['description-all_of_the_above']['pt-pt'] = 'Executa uma atualização usando as opções 1a, 2, 2b, 3, 4, 5 e 6 em sucessão.'; +$text['description-all_of_the_above']['ro-ro'] = 'Efectuează o actualizare folosind opțiunile 1a, 2, 2b, 3, 4, 5 și 6 succesiv.'; +$text['description-all_of_the_above']['ru-ru'] = 'Выполняет обновление, последовательно используя опции 1a, 2, 2b, 3, 4, 5 и 6.'; +$text['description-all_of_the_above']['sv-se'] = 'Utför en uppgradering med alternativ 1a, 2, 2b, 3, 4, 5 och 6 i följd.'; +$text['description-all_of_the_above']['uk-ua'] = 'Виконує оновлення, використовуючи послідовно параметри 1a, 2, 2b, 3, 4, 5 і 6.'; +$text['description-all_of_the_above']['tr-tr'] = '1a, 2, 2b, 3, 4, 5 ve 6 seçeneklerini sırayla kullanarak yükseltme gerçekleştirir.'; +$text['description-all_of_the_above']['zh-cn'] = '连续使用选项 1a、2、2b、3、4、5 和 6 执行升级。'; +$text['description-all_of_the_above']['ja-jp'] = 'オプション 1a、2、2b、3、4、5、6 を順番に使用してアップグレードを実行します。'; +$text['description-all_of_the_above']['ko-kr'] = '옵션 1a, 2, 2b, 3, 4, 5, 6을 연속으로 사용하여 업그레이드를 수행합니다.'; $text['label-update_external_repositories']['en-us'] = "Update External Repositories"; $text['label-update_external_repositories']['en-gb'] = "Update External Repositories"; diff --git a/core/upgrade/upgrade_menu.php b/core/upgrade/upgrade_menu.php index d31cf558ab..84c2115aca 100644 --- a/core/upgrade/upgrade_menu.php +++ b/core/upgrade/upgrade_menu.php @@ -33,7 +33,8 @@ defined('STDIN') or die('Unauthorized'); require_once dirname(__DIR__, 2) . "/resources/require.php"; //create a database connection using default config -$database = new database(); +$config = config::load(); +$database = database::new(['config' => $config]); //load global defaults $settings = new settings(['database' => $database]); @@ -58,7 +59,7 @@ $display_type = 'text'; show_upgrade_menu(); function show_upgrade_menu() { - global $text, $software_name; + global $text, $software_name, $settings; //error_reporting(E_ALL); $line = str_repeat('-', strlen($text['title-cli_upgrade']) + 2); while (true) { @@ -76,7 +77,8 @@ function show_upgrade_menu() { echo "3) {$text['label-upgrade_apps']} - {$text['description-upgrade_apps']}\n"; echo "4) {$text['label-upgrade_menu']} - {$text['description-upgrade_menu']}\n"; echo "5) {$text['label-upgrade_permissions']} - {$text['description-upgrade_permissions']}\n"; - echo "6) {$text['label-all_of_the_above']} - {$text['description-all_of_the_above']}\n"; + echo "6) {$text['label-update_filesystem_permissions']} - {$text['description-update_filesystem_permissions']}\n"; + echo "7) {$text['label-all_of_the_above']} - {$text['description-all_of_the_above']}\n"; echo "0) Exit\n"; echo "\n"; echo "Choice: "; @@ -108,11 +110,15 @@ function show_upgrade_menu() { do_upgrade_permissions(); break; case 6: + do_filesystem_permissions($text, $settings); + break; + case 7: do_upgrade_code(); do_upgrade_schema(); do_upgrade_domains(); do_upgrade_menu(); do_upgrade_permissions(); + do_filesystem_permissions($text, $settings); break; case 8: break; @@ -122,6 +128,58 @@ function show_upgrade_menu() { } } +function do_filesystem_permissions($text, settings $settings) { + + echo ($text['label-header1'] ?? "Root account or sudo account must be used for this option") . "\n"; + echo ($text['label-header2'] ?? "This option is used for resetting the permissions on the filesystem after executing commands using the root user account") . "\n"; + if (is_root_user()) { + $directories = []; + //get the fusionpbx folder + $project_root = dirname(__DIR__, 2); + //adjust the project root + $directories[] = $project_root; + //adjust the /etc/freeswitch + $directories[] = $settings->get('switch', 'conf', null); + $directories[] = $settings->get('switch', 'call_center', null); //normally in conf but can be different + $directories[] = $settings->get('switch', 'dialplan', null); //normally in conf but can be different + $directories[] = $settings->get('switch', 'directory', null); //normally in conf but can be different + $directories[] = $settings->get('switch', 'languages', null); //normally in conf but can be different + $directories[] = $settings->get('switch', 'sip_profiles', null); //normally in conf but can be different + //adjust the /usr/share/freeswitch/{scripts,sounds} + $directories[] = $settings->get('switch', 'scripts', null); + $directories[] = $settings->get('switch', 'sounds', null); + //adjust the /var/lib/freeswitch/{db,recordings,storage,voicemail} + $directories[] = $settings->get('switch', 'db', null); + $directories[] = $settings->get('switch', 'recordings', null); + $directories[] = $settings->get('switch', 'storage', null); + $directories[] = $settings->get('switch', 'voicemail', null); //normally included in storage but can be different + //only set the xml_cdr directory permissions + $log_directory = $settings->get('switch', 'log', null); + if ($log_directory !== null) { + $directories[] = $log_directory . '/xml_cdr'; + } + //execute chown command for each directory + foreach ($directories as $dir) { + if ($dir !== null) { + //notify user + echo "chown -R www-data:www-data $dir\n"; + //execute + exec("chown -R www-data:www-data $dir"); + } + } + } else { + echo ($text['label-not_running_as_root'] ?? "Not root user - operation skipped")."\n"; + } +} + +function is_root_user(): bool { + return posix_getuid() === 0; +} + +function current_user(): ?string { + return posix_getpwuid(posix_getuid())['name'] ?? null; +} + //show the upgrade type function show_software_version() { echo software::version() . "\n"; @@ -334,8 +392,8 @@ function load_config_php() { $conf .= "xml_handler.reg_as_number_alias = false\n"; $conf .= "xml_handler.number_as_presence_id = true\n"; $conf .= "\n"; - $conf .= "#error reporting hide show all errors except notices and warnings\n"; - $conf .= "error.reporting = 'E_ALL ^ E_NOTICE ^ E_WARNING'\n"; + $conf .= "#error reporting hide all errors\n"; + $conf .= "error.reporting = user\n"; //write the config file $file_handle = fopen($config_file, "w"); From 964865ae632ffb76d604b79a584d769a318f7b1f Mon Sep 17 00:00:00 2001 From: chansizzle <14916599+chansizzle@users.noreply.github.com> Date: Tue, 28 Jan 2025 16:22:02 -0700 Subject: [PATCH 30/89] add xml statistics mouse over text and use languages variables (#7211) * add xml statistics mouse over text and use languages variables * add xml statistics mouse over text and use languages variables * xml statistics - remove English words from non-English languages --- app/xml_cdr/app_languages.php | 130 +++++++++++++++++++++++++++++ app/xml_cdr/xml_cdr_statistics.php | 6 +- 2 files changed, 133 insertions(+), 3 deletions(-) diff --git a/app/xml_cdr/app_languages.php b/app/xml_cdr/app_languages.php index a293590e66..19dde926d7 100644 --- a/app/xml_cdr/app_languages.php +++ b/app/xml_cdr/app_languages.php @@ -243,6 +243,32 @@ $text['label-name']['zh-cn'] = "姓名"; $text['label-name']['ja-jp'] = "名前"; $text['label-name']['ko-kr'] = "이름"; +$text['label-volume']['en-us'] = "Volume"; +$text['label-volume']['en-gb'] = "Volume"; +$text['label-volume']['ar-eg'] = ""; +$text['label-volume']['de-at'] = ""; +$text['label-volume']['de-ch'] = ""; +$text['label-volume']['de-de'] = ""; +$text['label-volume']['el-gr'] = ""; +$text['label-volume']['es-cl'] = ""; +$text['label-volume']['es-mx'] = ""; +$text['label-volume']['fr-ca'] = ""; +$text['label-volume']['fr-fr'] = ""; +$text['label-volume']['he-il'] = ""; +$text['label-volume']['it-it'] = ""; +$text['label-volume']['nl-nl'] = ""; +$text['label-volume']['pl-pl'] = ""; +$text['label-volume']['pt-br'] = ""; +$text['label-volume']['pt-pt'] = ""; +$text['label-volume']['ro-ro'] = ""; +$text['label-volume']['ru-ru'] = ""; +$text['label-volume']['sv-se'] = ""; +$text['label-volume']['uk-ua'] = ""; +$text['label-volume']['tr-tr'] = ""; +$text['label-volume']['zh-cn'] = ""; +$text['label-volume']['ja-jp'] = ""; +$text['label-volume']['ko-kr'] = ""; + $text['label-minutes']['en-us'] = "Minutes"; $text['label-minutes']['en-gb'] = "Minutes"; $text['label-minutes']['ar-eg'] = "دقائق"; @@ -3240,6 +3266,32 @@ $text['label-answer']['zh-cn'] = "回答"; $text['label-answer']['ja-jp'] = "答え"; $text['label-answer']['ko-kr'] = "答え"; +$text['label-asr']['en-us'] = "ASR"; +$text['label-asr']['en-gb'] = "ASR"; +$text['label-asr']['ar-eg'] = ""; +$text['label-asr']['de-at'] = ""; +$text['label-asr']['de-ch'] = ""; +$text['label-asr']['de-de'] = ""; +$text['label-asr']['el-gr'] = ""; +$text['label-asr']['es-cl'] = ""; +$text['label-asr']['es-mx'] = ""; +$text['label-asr']['fr-ca'] = ""; +$text['label-asr']['fr-fr'] = ""; +$text['label-asr']['he-il'] = ""; +$text['label-asr']['it-it'] = ""; +$text['label-asr']['nl-nl'] = ""; +$text['label-asr']['pl-pl'] = ""; +$text['label-asr']['pt-br'] = ""; +$text['label-asr']['pt-pt'] = ""; +$text['label-asr']['ro-ro'] = ""; +$text['label-asr']['ru-ru'] = ""; +$text['label-asr']['sv-se'] = ""; +$text['label-asr']['uk-ua'] = ""; +$text['label-asr']['tr-tr'] = ""; +$text['label-asr']['zh-cn'] = ""; +$text['label-asr']['ja-jp'] = ""; +$text['label-asr']['ko-kr'] = ""; + $text['label-aloc']['en-us'] = "ALOC"; $text['label-aloc']['en-gb'] = "ALOC"; $text['label-aloc']['ar-eg'] = "ALOC"; @@ -3672,6 +3724,84 @@ $text['description-mos']['zh-cn'] = "平均意见得分"; $text['description-mos']['ja-jp'] = "平均意見スコア"; $text['description-mos']['ko-kr'] = "평균 의견 점수"; +$text['description-volume']['en-us'] = "Inbound, Outbound, and Local"; +$text['description-volume']['en-gb'] = "Inbound, Outbound, and Local"; +$text['description-volume']['ar-eg'] = ""; +$text['description-volume']['de-at'] = ""; +$text['description-volume']['de-ch'] = ""; +$text['description-volume']['de-de'] = ""; +$text['description-volume']['el-gr'] = ""; +$text['description-volume']['es-cl'] = ""; +$text['description-volume']['es-mx'] = ""; +$text['description-volume']['fr-ca'] = ""; +$text['description-volume']['fr-fr'] = ""; +$text['description-volume']['he-il'] = ""; +$text['description-volume']['it-it'] = ""; +$text['description-volume']['nl-nl'] = ""; +$text['description-volume']['pl-pl'] = ""; +$text['description-volume']['pt-br'] = ""; +$text['description-volume']['pt-pt'] = ""; +$text['description-volume']['ro-ro'] = ""; +$text['description-volume']['ru-ru'] = ""; +$text['description-volume']['sv-se'] = ""; +$text['description-volume']['uk-ua'] = ""; +$text['description-volume']['tr-tr'] = ""; +$text['description-volume']['zh-cn'] = ""; +$text['description-volume']['ja-jp'] = ""; +$text['description-volume']['ko-kr'] = ""; + +$text['description-calls-per-minute']['en-us'] = "average minutes / calls per minute answered"; +$text['description-calls-per-minute']['en-gb'] = "average minutes / calls per minute answered"; +$text['description-calls-per-minute']['ar-eg'] = ""; +$text['description-calls-per-minute']['de-at'] = ""; +$text['description-calls-per-minute']['de-ch'] = ""; +$text['description-calls-per-minute']['de-de'] = ""; +$text['description-calls-per-minute']['el-gr'] = ""; +$text['description-calls-per-minute']['es-cl'] = ""; +$text['description-calls-per-minute']['es-mx'] = ""; +$text['description-calls-per-minute']['fr-ca'] = ""; +$text['description-calls-per-minute']['fr-fr'] = ""; +$text['description-calls-per-minute']['he-il'] = ""; +$text['description-calls-per-minute']['it-it'] = ""; +$text['description-calls-per-minute']['nl-nl'] = ""; +$text['description-calls-per-minute']['pl-pl'] = ""; +$text['description-calls-per-minute']['pt-br'] = ""; +$text['description-calls-per-minute']['pt-pt'] = ""; +$text['description-calls-per-minute']['ro-ro'] = ""; +$text['description-calls-per-minute']['ru-ru'] = ""; +$text['description-calls-per-minute']['sv-se'] = ""; +$text['description-calls-per-minute']['uk-ua'] = ""; +$text['description-calls-per-minute']['tr-tr'] = ""; +$text['description-calls-per-minute']['zh-cn'] = ""; +$text['description-calls-per-minute']['ja-jp'] = ""; +$text['description-calls-per-minute']['ko-kr'] = ""; + +$text['description-asr']['en-us'] = "Answer-Seizure Ratio (% of calls answered)"; +$text['description-asr']['en-gb'] = "Answer-Seizure Ratio (% of calls answered)"; +$text['description-asr']['ar-eg'] = ""; +$text['description-asr']['de-at'] = ""; +$text['description-asr']['de-ch'] = ""; +$text['description-asr']['de-de'] = ""; +$text['description-asr']['el-gr'] = ""; +$text['description-asr']['es-cl'] = ""; +$text['description-asr']['es-mx'] = ""; +$text['description-asr']['fr-ca'] = ""; +$text['description-asr']['fr-fr'] = ""; +$text['description-asr']['he-il'] = ""; +$text['description-asr']['it-it'] = ""; +$text['description-asr']['nl-nl'] = ""; +$text['description-asr']['pl-pl'] = ""; +$text['description-asr']['pt-br'] = ""; +$text['description-asr']['pt-pt'] = ""; +$text['description-asr']['ro-ro'] = ""; +$text['description-asr']['ru-ru'] = ""; +$text['description-asr']['sv-se'] = ""; +$text['description-asr']['uk-ua'] = ""; +$text['description-asr']['tr-tr'] = ""; +$text['description-asr']['zh-cn'] = ""; +$text['description-asr']['ja-jp'] = ""; +$text['description-asr']['ko-kr'] = ""; + $text['description-aloc']['en-us'] = "Average Length of Call"; $text['description-aloc']['en-gb'] = "Average Length of Call"; $text['description-aloc']['ar-eg'] = "متوسط طول المحادثة"; diff --git a/app/xml_cdr/xml_cdr_statistics.php b/app/xml_cdr/xml_cdr_statistics.php index 37b7247804..c90285e111 100644 --- a/app/xml_cdr/xml_cdr_statistics.php +++ b/app/xml_cdr/xml_cdr_statistics.php @@ -281,11 +281,11 @@ echo " ".$text['label-hours']."\n"; echo " ".$text['label-date']."\n"; echo " ".$text['label-time']."\n"; - echo " Volume\n"; + echo " ".$text['label-volume']."\n"; echo " ".$text['label-minutes']."\n"; - echo " ".$text['label-calls-per-minute']."\n"; + echo " ".$text['label-calls-per-minute']."\n"; echo " ".$text['label-missed']."\n"; - echo " ASR\n"; + echo " ".$text['label-asr']."\n"; echo " ".$text['label-aloc']."\n"; echo "\n"; From bb1006aca86b7cf8ddd50f6ea94b2229332dd38e Mon Sep 17 00:00:00 2001 From: denisent <120752864+denisent@users.noreply.github.com> Date: Tue, 28 Jan 2025 15:26:32 -0800 Subject: [PATCH 31/89] Add serial number to the device edit page (#7234) * add device serial number * add device serial number field * add device serial number field --- app/devices/app_config.php | 8 ++++++ app/devices/app_languages.php | 52 +++++++++++++++++++++++++++++++++++ app/devices/device_edit.php | 18 ++++++++++++ 3 files changed, 78 insertions(+) diff --git a/app/devices/app_config.php b/app/devices/app_config.php index da31452c5a..a346b9fd38 100644 --- a/app/devices/app_config.php +++ b/app/devices/app_config.php @@ -224,6 +224,9 @@ $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; $apps[$x]['permissions'][$y]['groups'][] = "admin"; $y++; + $apps[$x]['permissions'][$y]['name'] = "device_serial_number"; + $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; + $y++; $apps[$x]['permissions'][$y]['name'] = "device_model"; //$apps[$x]['permissions'][$y]['groups'][] = "superadmin"; $y++; @@ -462,6 +465,11 @@ $apps[$x]['db'][$y]['fields'][$z]['search'] = 'true'; $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = "device_serial_number"; + $apps[$x]['db'][$y]['fields'][$z]['type'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['search'] = 'true'; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + $z++; $apps[$x]['db'][$y]['fields'][$z]['name']['text'] = "device_model"; $apps[$x]['db'][$y]['fields'][$z]['name']['deprecated'] = "phone_model"; $apps[$x]['db'][$y]['fields'][$z]['type'] = "text"; diff --git a/app/devices/app_languages.php b/app/devices/app_languages.php index a1893028e9..1fe1aa92be 100644 --- a/app/devices/app_languages.php +++ b/app/devices/app_languages.php @@ -3198,6 +3198,32 @@ $text['label-device_location']['zh-cn'] = "地点"; $text['label-device_location']['ja-jp'] = "位置"; $text['label-device_location']['ko-kr'] = "위치"; +$text['label-device_serial_number']['en-us'] = "Serial Number"; +$text['label-device_serial_number']['en-gb'] = "Serial Number"; +$text['label-device_serial_number']['ar-eg'] = ""; +$text['label-device_serial_number']['de-at'] = ""; +$text['label-device_serial_number']['de-ch'] = ""; +$text['label-device_serial_number']['de-de'] = ""; +$text['label-device_serial_number']['el-gr'] = ""; +$text['label-device_serial_number']['es-cl'] = ""; +$text['label-device_serial_number']['es-mx'] = ""; +$text['label-device_serial_number']['fr-ca'] = ""; +$text['label-device_serial_number']['fr-fr'] = ""; +$text['label-device_serial_number']['he-il'] = ""; +$text['label-device_serial_number']['it-it'] = ""; +$text['label-device_serial_number']['ka-ge'] = ""; +$text['label-device_serial_number']['nl-nl'] = ""; +$text['label-device_serial_number']['pl-pl'] = ""; +$text['label-device_serial_number']['pt-br'] = ""; +$text['label-device_serial_number']['pt-pt'] = ""; +$text['label-device_serial_number']['ro-ro'] = ""; +$text['label-device_serial_number']['ru-ru'] = ""; +$text['label-device_serial_number']['sv-se'] = ""; +$text['label-device_serial_number']['uk-ua'] = ""; +$text['label-device_serial_number']['zh-cn'] = ""; +$text['label-device_serial_number']['ja-jp'] = ""; +$text['label-device_serial_number']['ko-kr'] = ""; + $text['label-device_key_vendor']['en-us'] = "Vendor"; $text['label-device_key_vendor']['en-gb'] = "Vendor"; $text['label-device_key_vendor']['ar-eg'] = "البائع"; @@ -6634,6 +6660,32 @@ $text['description-device_location']['zh-cn'] = "输入设备位置。"; $text['description-device_location']['ja-jp'] = "デバイスの場所を入力します。"; $text['description-device_location']['ko-kr'] = "장치 위치를 입력합니다."; +$text['description-device_serial_number']['en-us'] = "Enter the device serial number."; +$text['description-device_serial_number']['en-gb'] = "Enter the device serial number."; +$text['description-device_serial_number']['ar-eg'] = ""; +$text['description-device_serial_number']['de-at'] = ""; +$text['description-device_serial_number']['de-ch'] = ""; +$text['description-device_serial_number']['de-de'] = ""; +$text['description-device_serial_number']['el-gr'] = ""; +$text['description-device_serial_number']['es-cl'] = ""; +$text['description-device_serial_number']['es-mx'] = ""; +$text['description-device_serial_number']['fr-ca'] = ""; +$text['description-device_serial_number']['fr-fr'] = ""; +$text['description-device_serial_number']['he-il'] = ""; +$text['description-device_serial_number']['it-it'] = ""; +$text['description-device_serial_number']['ka-ge'] = ""; +$text['description-device_serial_number']['nl-nl'] = ""; +$text['description-device_serial_number']['pl-pl'] = ""; +$text['description-device_serial_number']['pt-br'] = ""; +$text['description-device_serial_number']['pt-pt'] = ""; +$text['description-device_serial_number']['ro-ro'] = ""; +$text['description-device_serial_number']['ru-ru'] = ""; +$text['description-device_serial_number']['sv-se'] = ""; +$text['description-device_serial_number']['uk-ua'] = ""; +$text['description-device_serial_number']['zh-cn'] = ""; +$text['description-device_serial_number']['ja-jp'] = ""; +$text['description-device_serial_number']['ko-kr'] = ""; + $text['description-device_time_zone']['en-us'] = "Enter the time zone."; $text['description-device_time_zone']['en-gb'] = "Enter the time zone."; $text['description-device_time_zone']['ar-eg'] = "أدخل المنطقة الزمنية"; diff --git a/app/devices/device_edit.php b/app/devices/device_edit.php index f058c0becb..b8cedfff56 100644 --- a/app/devices/device_edit.php +++ b/app/devices/device_edit.php @@ -124,6 +124,7 @@ $device_password = $_POST["device_password"]; $device_vendor = $_POST["device_vendor"]; $device_location = $_POST["device_location"]; + $device_serial_number = $_POST["device_serial_number"]; $device_uuid_alternate = $_POST["device_uuid_alternate"] ?? null; $device_model = $_POST["device_model"] ?? null; $device_firmware_version = $_POST["device_firmware_version"] ?? null; @@ -269,6 +270,9 @@ if (permission_exists('device_location')) { $array['devices'][0]['device_location'] = $device_location; } + if (permission_exists('device_serial_number')) { + $array['devices'][0]['device_serial_number'] = $device_serial_number; + } if (permission_exists('device_alternate')) { $array['devices'][0]['device_uuid_alternate'] = is_uuid($device_uuid_alternate) ? $device_uuid_alternate : null; } @@ -521,6 +525,7 @@ $device_password = $row["device_password"]; $device_vendor = $row["device_vendor"]; $device_location = $row["device_location"]; + $device_serial_number = $row["device_serial_number"]; $device_uuid_alternate = $row["device_uuid_alternate"]; $device_model = $row["device_model"]; $device_firmware_version = $row["device_firmware_version"]; @@ -1915,6 +1920,19 @@ echo "\n"; } + if (permission_exists('device_serial_number')) { + echo "\n"; + echo "\n"; + echo " ".$text['label-device_serial_number']."\n"; + echo "\n"; + echo "\n"; + echo " \n"; + echo "
\n"; + echo $text['description-device_serial_number']."\n"; + echo "\n"; + echo "\n"; + } + if (permission_exists('device_model')) { echo "\n"; echo "\n"; From b2349060b591d8c59589112c4cb26d85f2691c86 Mon Sep 17 00:00:00 2001 From: Alex <40072887+alexdcrane@users.noreply.github.com> Date: Tue, 28 Jan 2025 16:39:35 -0700 Subject: [PATCH 32/89] Fix number text and background color not applying (#7235) * Fix number text and background color not applying * Update registrations.php * Update voicemails.php * Update missed_calls.php * Update recent_calls.php * Update domains.php --- app/registrations/resources/dashboard/registrations.php | 2 +- app/voicemails/resources/dashboard/voicemails.php | 2 +- app/xml_cdr/resources/dashboard/missed_calls.php | 2 +- app/xml_cdr/resources/dashboard/recent_calls.php | 2 +- core/dashboard/index.php | 2 ++ core/domains/resources/dashboard/domains.php | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/registrations/resources/dashboard/registrations.php b/app/registrations/resources/dashboard/registrations.php index 44ea55ed3f..417174b3a0 100644 --- a/app/registrations/resources/dashboard/registrations.php +++ b/app/registrations/resources/dashboard/registrations.php @@ -55,7 +55,7 @@ echo " ".escape($dashboard_label).""; echo "
\n"; echo " \n"; - echo " ".$active_registrations." / ".($active_registrations + $inactive_registrations)."\n"; + echo " ".$active_registrations." / ".($active_registrations + $inactive_registrations)."\n"; echo "
\n"; echo " \n"; if (empty($dashboard_details_state) || $dashboard_details_state != "disabled") { diff --git a/app/voicemails/resources/dashboard/voicemails.php b/app/voicemails/resources/dashboard/voicemails.php index 9c5b571c08..d3665ae467 100644 --- a/app/voicemails/resources/dashboard/voicemails.php +++ b/app/voicemails/resources/dashboard/voicemails.php @@ -111,7 +111,7 @@ echo "\n"; echo "
\n"; echo " \n"; - echo " ".$messages['new']."\n"; + echo " ".$messages['new']."\n"; echo "
\n"; echo "
"; } diff --git a/app/xml_cdr/resources/dashboard/missed_calls.php b/app/xml_cdr/resources/dashboard/missed_calls.php index 80b3378c2d..d52fd832c1 100644 --- a/app/xml_cdr/resources/dashboard/missed_calls.php +++ b/app/xml_cdr/resources/dashboard/missed_calls.php @@ -149,7 +149,7 @@ echo "\n"; echo "
\n"; echo " \n"; - echo " ".$num_rows."\n"; + echo " ".$num_rows."\n"; echo "
\n"; echo "
"; } diff --git a/app/xml_cdr/resources/dashboard/recent_calls.php b/app/xml_cdr/resources/dashboard/recent_calls.php index 8de16e74cb..135b4fd8a7 100644 --- a/app/xml_cdr/resources/dashboard/recent_calls.php +++ b/app/xml_cdr/resources/dashboard/recent_calls.php @@ -147,7 +147,7 @@ echo "
\n"; echo "
\n"; echo " \n"; - echo " ".$num_rows."\n"; + echo " ".$num_rows."\n"; echo "
\n"; echo "
"; } diff --git a/core/dashboard/index.php b/core/dashboard/index.php index 9e28e1f689..606832bbff 100644 --- a/core/dashboard/index.php +++ b/core/dashboard/index.php @@ -533,6 +533,7 @@ function toggle_grid_row_end_all() { $dashboard_chart_type = $row['dashboard_chart_type'] ?? "doughnut"; $dashboard_label_text_color = $row['dashboard_label_text_color'] ?? $settings->get('theme', 'dashboard_label_text_color', ''); $dashboard_number_text_color = $row['dashboard_number_text_color'] ?? $settings->get('theme', 'dashboard_number_text_color', ''); + $dashboard_number_background_color = $row['dashboard_number_background_color'] ?? $settings->get('theme', 'dashboard_number_background_color', ''); $dashboard_details_state = $row['dashboard_details_state'] ?? "expanded"; $dashboard_row_span = $row['dashboard_row_span'] ?? 2; @@ -558,6 +559,7 @@ function toggle_grid_row_end_all() { $dashboard_chart_type = preg_replace($text_pattern, '', $dashboard_chart_type); $dashboard_label_text_color = preg_replace($text_pattern, '', $dashboard_label_text_color); $dashboard_number_text_color = preg_replace($text_pattern, '', $dashboard_number_text_color); + $dashboard_number_background_color = preg_replace($text_pattern, '', $dashboard_number_background_color); $dashboard_details_state = preg_replace($text_pattern, '', $dashboard_details_state); $dashboard_row_span = preg_replace($number_pattern, '', $dashboard_row_span); $dashboard_path = preg_replace($text_pattern, '', strtolower($row['dashboard_path'])); diff --git a/core/domains/resources/dashboard/domains.php b/core/domains/resources/dashboard/domains.php index 190ebb6cd0..7a789b33c0 100644 --- a/core/domains/resources/dashboard/domains.php +++ b/core/domains/resources/dashboard/domains.php @@ -37,7 +37,7 @@ echo " ".escape($dashboard_label).""; echo "
\n"; echo " \n"; - echo " ".$domain_count."\n"; + echo " ".$domain_count."\n"; echo "
\n"; echo " \n"; if (empty($dashboard_details_state) || $dashboard_details_state != "disabled") { From 77f9161408b9958bca67313e7d27bb6f82994b9c Mon Sep 17 00:00:00 2001 From: simplecoder732 <128755293+eliweaver732@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:57:50 -0500 Subject: [PATCH 33/89] Add a voicemail deletion queue (#7221) * Add a deleted messages option to voicemail. Messages are only deleted after a certain amount of time instead of immediately. The queue can be turned off or on with the default setting "use_deletion_queue" in the "voicemail" category. Changed deleted phrase and added a deleted messages count phrase Added a program to delete messages that are due for deletion. Also small changes to phrases. * Added a remove_deleted_messages function that runs on voicemail main menu log in. With this method, the deletion queue is handled per mailbox vs system-wide as in the cron-triggered script. It also allows us to adjust the retention hours on a per-domain basis. --- .../resources/conf/languages/en/vm/sounds.xml | 19 +++ .../conf/languages/en/vm/voicemail.xml | 36 ++++++ .../resources/scripts/app/voicemail/index.lua | 17 +++ .../functions/listen_to_recording.lua | 13 +- .../resources/functions/main_menu.lua | 31 +++++ .../resources/functions/menu_messages.lua | 6 +- .../resources/functions/message_saved.lua | 14 +- .../functions/remove_deleted_messages.lua | 92 ++++++++++++++ .../resources/scripts/delete_messages.lua | 120 ++++++++++++++++++ app/voicemails/app_config.php | 18 ++- 10 files changed, 356 insertions(+), 10 deletions(-) create mode 100644 app/switch/resources/scripts/app/voicemail/resources/functions/remove_deleted_messages.lua create mode 100644 app/switch/resources/scripts/app/voicemail/resources/scripts/delete_messages.lua diff --git a/app/switch/resources/conf/languages/en/vm/sounds.xml b/app/switch/resources/conf/languages/en/vm/sounds.xml index 250cb96e1d..14866b7383 100644 --- a/app/switch/resources/conf/languages/en/vm/sounds.xml +++ b/app/switch/resources/conf/languages/en/vm/sounds.xml @@ -104,6 +104,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/switch/resources/conf/languages/en/vm/voicemail.xml b/app/switch/resources/conf/languages/en/vm/voicemail.xml index 0daec58637..3218186ccc 100644 --- a/app/switch/resources/conf/languages/en/vm/voicemail.xml +++ b/app/switch/resources/conf/languages/en/vm/voicemail.xml @@ -65,6 +65,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -96,6 +121,17 @@ + + + + + + + + + + + diff --git a/app/switch/resources/scripts/app/voicemail/index.lua b/app/switch/resources/scripts/app/voicemail/index.lua index ebbe781fef..253bfcb43b 100644 --- a/app/switch/resources/scripts/app/voicemail/index.lua +++ b/app/switch/resources/scripts/app/voicemail/index.lua @@ -246,6 +246,22 @@ end end + use_deletion_queue = 'false'; + if (settings['voicemail']['use_deletion_queue'] ~= nil) then + if (settings['voicemail']['use_deletion_queue']['boolean'] ~= nil) then + use_deletion_queue = settings['voicemail']['use_deletion_queue']['boolean']; + end + end + + deletion_queue_retention_hours = "24"; + if (settings['voicemail'] ~= nil) then + if (settings['voicemail']['deletion_queue_retention_hours'] ~= nil) then + if (settings['voicemail']['deletion_queue_retention_hours']['numeric'] ~= nil) then + deletion_queue_retention_hours = settings['voicemail']['deletion_queue_retention_hours']['numeric']; + end + end + end + end if (settings['voicemail']) then @@ -363,6 +379,7 @@ require "app.voicemail.resources.functions.mwi_notify"; require "app.voicemail.resources.functions.blf_notify"; require "app.voicemail.resources.functions.tutorial"; + require "app.voicemail.resources.functions.remove_deleted_messages"; --send a message waiting event if (voicemail_action == "mwi") then diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/listen_to_recording.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/listen_to_recording.lua index 635e160b10..3fc0cfd5f5 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/listen_to_recording.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/listen_to_recording.lua @@ -233,7 +233,11 @@ --post listen options if (session:ready()) then if (string.len(dtmf_digits) == 0) then - dtmf_digits = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", "phrase:voicemail_listen_file_options:1:2:3:5:7:8:9:0", "", "^[\\d\\*#]$"); + if (use_deletion_queue == "true" and message_status == "deleted") then + dtmf_digits = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", "phrase:voicemail_listen_file_options:deleted:1:2:3:5:7:8:9:0", "", "^[\\d\\*#]$"); + else + dtmf_digits = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", "phrase:voicemail_listen_file_options:1:2:3:5:7:8:9:0", "", "^[\\d\\*#]$"); + end end end @@ -264,7 +268,12 @@ message_saved(voicemail_id, uuid); return_call(caller_id_number); elseif (dtmf_digits == "7") then - delete_recording(voicemail_id, uuid); + if (use_deletion_queue == "true" and message_status ~= "deleted") then + message_saved(voicemail_id, uuid, "deleted"); + session:execute("playback", "phrase:voicemail_ack:deleted"); + else + delete_recording(voicemail_id, uuid); + end message_waiting(voicemail_id, domain_uuid); --fix for extensions that start with 0 (Ex: 0712) if (voicemail_id_copy ~= voicemail_id and voicemail_id_copy ~= nil) then diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/main_menu.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/main_menu.lua index c69593b248..ea289054f1 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/main_menu.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/main_menu.lua @@ -38,6 +38,11 @@ session:execute("sleep", "1000"); end + --remove deleted messages in queue + if (use_deletion_queue == "true") then + remove_deleted_messages(voicemail_id); + end + --new voicemail count if (session:ready()) then local sql = [[SELECT count(*) as new_messages FROM v_voicemail_messages @@ -70,6 +75,24 @@ dtmf_digits = session:playAndGetDigits(0, 1, 1, 300, "#", "phrase:voicemail_saved_message_count:" .. saved_messages .. ":saved", "", "\\d+"); end end + --deleted messages + if (session:ready()) then + deleted_messages = 0; + if (string.len(dtmf_digits) == 0 and use_deletion_queue == "true") then + sql = [[SELECT count(*) as deleted_messages FROM v_voicemail_messages + WHERE domain_uuid = :domain_uuid + AND voicemail_uuid = :voicemail_uuid + AND message_status = 'deleted' ]]; + local params = {domain_uuid = domain_uuid, voicemail_uuid = voicemail_uuid}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params, function(row) + deleted_messages = row["deleted_messages"]; + end); + dtmf_digits = session:playAndGetDigits(0, 1, 1, 300, "#", "phrase:voicemail_deleted_message_count:" .. deleted_messages .. ":deleted", "", "\\d+"); + end + end --to listen to new message if (session:ready() and new_messages ~= '0') then @@ -83,6 +106,12 @@ dtmf_digits = session:playAndGetDigits(0, 1, 1, 100, "#", "phrase:voicemail_main_menu:saved:2", "", "\\d+"); end end + --deleted messages + if (session:ready() and deleted_messages ~= '0') then + if (string.len(dtmf_digits) == 0) then + dtmf_digits = session:playAndGetDigits(0, 1, 1, 100, "#", "phrase:voicemail_main_menu:deleted:3", "", "\\d+"); + end + end --for advanced options if (session:ready()) then if (string.len(dtmf_digits) == 0) then @@ -101,6 +130,8 @@ menu_messages("new"); elseif (dtmf_digits == "2") then menu_messages("saved"); + elseif (dtmf_digits == "3" and use_deletion_queue == "true") then + menu_messages("deleted"); elseif (dtmf_digits == "5") then timeouts = 0; advanced(); diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/menu_messages.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/menu_messages.lua index c106823065..e17990a8aa 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/menu_messages.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/menu_messages.lua @@ -38,7 +38,7 @@ --session:flushDigits(); --set the message number message_number = 0; - --message_status new,saved + --message_status new,any if (session:ready()) then if (voicemail_id ~= nil) then --get the voicemail_id @@ -58,8 +58,8 @@ AND voicemail_uuid = :voicemail_uuid ]] if (message_status == "new") then sql = sql .. [[AND (message_status is null or message_status = '') ]]; - elseif (message_status == "saved") then - sql = sql .. [[AND message_status = 'saved' ]]; + else + sql = sql .. "AND message_status = '" .. message_status .. "' "; end sql = sql .. [[ORDER BY created_epoch ]]..message_order; local params = {domain_uuid = domain_uuid, voicemail_uuid = voicemail_uuid}; diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/message_saved.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/message_saved.lua index 15bec62635..d48ad0f472 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/message_saved.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/message_saved.lua @@ -24,11 +24,15 @@ -- POSSIBILITY OF SUCH DAMAGE. --save the message - function message_saved(voicemail_id, uuid) + function message_saved(voicemail_id, uuid, status) --clear the dtmf dtmf_digits = ''; --flush dtmf digits from the input buffer session:flushDigits(); + --set default status + if (status == nil) then + status = 'saved'; + end --get the voicemail_uuid local sql = [[SELECT * FROM v_voicemails WHERE domain_uuid = :domain_uuid @@ -38,18 +42,20 @@ db_voicemail_uuid = row["voicemail_uuid"]; end); --delete from the database - sql = [[UPDATE v_voicemail_messages SET message_status = 'saved' + sql = [[UPDATE v_voicemail_messages + SET message_status = :status, + update_date = now() WHERE domain_uuid = :domain_uuid AND voicemail_uuid = :voicemail_uuid AND voicemail_message_uuid = :uuid]]; - params = {domain_uuid = domain_uuid, voicemail_uuid = db_voicemail_uuid, uuid = uuid}; + params = {status = status, domain_uuid = domain_uuid, voicemail_uuid = db_voicemail_uuid, uuid = uuid}; if (debug["sql"]) then freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); end dbh:query(sql, params); --log to console if (debug["info"]) then - freeswitch.consoleLog("notice", "[voicemail][saved] id: " .. voicemail_id .. " message: "..uuid.."\n"); + freeswitch.consoleLog("notice", "[voicemail]["..status.."] id: " .. voicemail_id .. " message: "..uuid.."\n"); end --check the message waiting status message_waiting(voicemail_id, domain_uuid); diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/remove_deleted_messages.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/remove_deleted_messages.lua new file mode 100644 index 0000000000..1e8a94bc27 --- /dev/null +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/remove_deleted_messages.lua @@ -0,0 +1,92 @@ +-- Part of FusionPBX +-- Copyright (C) 2013-2025 +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--delete all deleted messages for a single mailbox + function remove_deleted_messages(voicemail_id) + --get the voicemail_uuid + local sql = [[SELECT * FROM v_voicemails + WHERE domain_uuid = :domain_uuid + AND voicemail_id = :voicemail_id]]; + local params = {domain_uuid = domain_uuid, voicemail_id = voicemail_id}; + dbh:query(sql, params, function(row) + db_voicemail_uuid = row["voicemail_uuid"]; + end); + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); + end + + --get messages + local sql = [[SELECT * FROM v_voicemail_messages + WHERE message_status = 'deleted' ]] + sql = sql .. "AND (update_date + interval '" .. deletion_queue_retention_hours .. " hours') < now() " + sql = sql .. [[AND voicemail_uuid = :voicemail_uuid + AND domain_uuid = :domain_uuid]]; + local params = {voicemail_uuid = db_voicemail_uuid, domain_uuid = domain_uuid} + messages_to_delete = {}; + dbh:query(sql, params, function(row) + table.insert(messages_to_delete, row); + end); + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); + end + + --flush dtmf digits from the input buffer + session:flushDigits(); + + total_messages = #messages_to_delete; + message_number = 1; + while message_number <= total_messages do + local message_row = messages_to_delete[message_number]; + local uuid = message_row["voicemail_message_uuid"]; + + --delete the file + os.remove(voicemail_dir.."/"..voicemail_id.."/intro_msg_"..uuid.."."..vm_message_ext); + os.remove(voicemail_dir.."/"..voicemail_id.."/intro_"..uuid.."."..vm_message_ext); + os.remove(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext); + --delete from the database + sql = [[DELETE FROM v_voicemail_messages + WHERE domain_uuid = :domain_uuid + AND voicemail_uuid = :voicemail_uuid + AND voicemail_message_uuid = :uuid]]; + params = {domain_uuid = domain_uuid, voicemail_uuid = db_voicemail_uuid, uuid = uuid}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + --log to console + if (debug["info"]) then + freeswitch.consoleLog("notice", "[voicemail][deleted] message: " .. uuid .. "\n"); + end + end + + + --clear the variable + db_voicemail_uuid = ''; + messages_to_delete = {}; + + --flush dtmf digits from the input buffer + session:flushDigits(); + +end diff --git a/app/switch/resources/scripts/app/voicemail/resources/scripts/delete_messages.lua b/app/switch/resources/scripts/app/voicemail/resources/scripts/delete_messages.lua new file mode 100644 index 0000000000..4deef47da6 --- /dev/null +++ b/app/switch/resources/scripts/app/voicemail/resources/scripts/delete_messages.lua @@ -0,0 +1,120 @@ +-- Part of FusionPBX +-- Copyright (C) 2013-2025 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--connect to the database + Database = require "resources.functions.database"; + dbh = Database.new('system'); + +--get settings + require "resources.functions.settings"; + settings = settings(); + +--set deletion_queue_retention_hours + if (settings['voicemail'] ~= nil) then + if (settings['voicemail']['deletion_queue_retention_hours'] ~= nil) then + if (settings['voicemail']['deletion_queue_retention_hours']['numeric'] ~= nil) then + retention_hours = settings['voicemail']['deletion_queue_retention_hours']['numeric']; + else + retention_hours = "24"; + end + end + end + +--set the voicemail_dir + if (settings['switch'] ~= nil) then + if (settings['switch']['voicemail'] ~= nil) then + if (settings['switch']['voicemail']['dir'] ~= nil) then + voicemail_dir = settings['switch']['voicemail']['dir'].."/default"; + end + end + end + +--get the voicemail extension + sql = "SELECT * FROM v_vars WHERE var_category = 'Defaults' AND var_name = 'vm_message_ext' AND var_enabled = 'true'"; + dbh:query(sql, function(row) + vm_message_ext = row["var_value"]; + end); + if (vm_message_ext == nil) then + vm_message_ext = "wav"; + end + +--get messages + sql = "SELECT * FROM v_voicemail_messages WHERE message_status = 'deleted' AND (update_date + interval '" .. retention_hours .. " hours') < now()"; + messages_to_delete = {}; + dbh:query(sql, function(row) + table.insert(messages_to_delete, row); + end); + +--delete the messages + total_messages = #messages_to_delete; + message_number = 1; + while message_number <= total_messages do + local message_row = messages_to_delete[message_number]; + local uuid = message_row["voicemail_message_uuid"]; + + --get domain_name + sql = [[SELECT * from v_domains + WHERE domain_uuid = :domain_uuid + ]]; + local params = {domain_uuid = message_row["domain_uuid"]}; + dbh:query(sql, params, function(row) + domain_name = row["domain_name"]; + end); + + --get voicemail_id + sql = [[SELECT * from v_voicemails + WHERE domain_uuid = :domain_uuid + AND voicemail_uuid = :voicemail_uuid + ]]; + local params = {domain_uuid = message_row["domain_uuid"], voicemail_uuid = message_row["voicemail_uuid"]}; + dbh:query(sql, params, function(row) + voicemail_id = row["voicemail_id"]; + end); + + --delete the file + os.remove(voicemail_dir.."/"..domain_name.."/"..voicemail_id.."/intro_msg_"..uuid.."."..vm_message_ext); + os.remove(voicemail_dir.."/"..domain_name.."/"..voicemail_id.."/intro_"..uuid.."."..vm_message_ext); + os.remove(voicemail_dir.."/"..domain_name.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext); + + --delete from the database + sql = [[DELETE FROM v_voicemail_messages + WHERE domain_uuid = :domain_uuid + AND voicemail_uuid = :voicemail_uuid + AND voicemail_message_uuid = :uuid]]; + local params = { + domain_uuid = message_row["domain_uuid"], + voicemail_uuid = message_row["voicemail_uuid"], + uuid = uuid + }; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + --log to console + if (debug["info"]) then + freeswitch.consoleLog("notice", "[voicemail][deleted] message: " .. uuid .. "\n"); + end + + end \ No newline at end of file diff --git a/app/voicemails/app_config.php b/app/voicemails/app_config.php index a34a4091f2..11d6f974b0 100644 --- a/app/voicemails/app_config.php +++ b/app/voicemails/app_config.php @@ -401,6 +401,22 @@ $apps[$x]['default_settings'][$y]['default_setting_value'] = "90"; $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true"; $apps[$x]['default_settings'][$y]['default_setting_description'] = "Number of days maintenance application will retain files."; + $y++; + $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "79d05433-a7ab-4641-ae5d-6eb7810eb560"; + $apps[$x]['default_settings'][$y]['default_setting_category'] = "voicemail"; + $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "use_deletion_queue"; + $apps[$x]['default_settings'][$y]['default_setting_name'] = "boolean"; + $apps[$x]['default_settings'][$y]['default_setting_value'] = "false"; + $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "false"; + $apps[$x]['default_settings'][$y]['default_setting_description'] = "Instead of deleting voicemails right away when pressing 7; queue them for deletion"; + $y++; + $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "b06cc9df-379e-4b45-8bda-d2d431506317"; + $apps[$x]['default_settings'][$y]['default_setting_category'] = "voicemail"; + $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "deletion_queue_retention_hours"; + $apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric"; + $apps[$x]['default_settings'][$y]['default_setting_value'] = "24"; + $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true"; + $apps[$x]['default_settings'][$y]['default_setting_description'] = "Number of hours the voicemail deletion queue will retain deleted voicemails"; //schema details $y=0; $apps[$x]['db'][$y]['table']['name'] = "v_voicemails"; @@ -735,4 +751,4 @@ $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; -?> \ No newline at end of file +?> From d6f9b252838c882bce71e5f150cc4ac2356338e7 Mon Sep 17 00:00:00 2001 From: frytimo Date: Tue, 28 Jan 2025 20:05:00 -0400 Subject: [PATCH 34/89] format schema class (#7145) - format schema class using autoformat --- resources/classes/schema.php | 1609 +++++++++++++++++----------------- 1 file changed, 799 insertions(+), 810 deletions(-) diff --git a/resources/classes/schema.php b/resources/classes/schema.php index d4f57e8518..3ec6c2c57f 100644 --- a/resources/classes/schema.php +++ b/resources/classes/schema.php @@ -1,931 +1,920 @@ - Copyright (C) 2013 - 2023 - All Rights Reserved. + The Initial Developer of the Original Code is + Mark J Crane + Copyright (C) 2013 - 2023 + All Rights Reserved. - Contributor(s): - Mark J Crane -*/ + Contributor(s): + Mark J Crane + */ //define the schema class if (!class_exists('schema')) { + class schema { //define variables - private $database; - public $apps; - public $db_type; - public $result; - public $data_types; + private $database; + public $apps; + public $db_type; + public $result; + public $data_types; //class constructor - public function __construct() { + public function __construct() { - //includes files - require dirname(__DIR__, 2) . "/resources/require.php"; + //includes files + require dirname(__DIR__, 2) . "/resources/require.php"; - //connect to the database - $this->database = database::new(); + //connect to the database + $this->database = database::new(); - //get the list of installed apps from the core and mod directories - $config_list = glob($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . "/*/*/app_config.php"); - $x=0; - foreach ($config_list as $config_path) { - try { - include($config_path); - } - catch (Exception $e) { - //echo 'Caught exception: ', $e->getMessage(), "\n"; - } - $x++; + //get the list of installed apps from the core and mod directories + $config_list = glob($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . "/*/*/app_config.php"); + $x = 0; + foreach ($config_list as $config_path) { + try { + include($config_path); + } catch (Exception $e) { + //echo 'Caught exception: ', $e->getMessage(), "\n"; } - $this->apps = $apps; + $x++; } + $this->apps = $apps; + } //create the database schema - public function sql() { - $sql = ''; - $sql_schema = ''; - foreach ($this->apps as $app) { - if (isset($app['db']) && count($app['db'])) { - foreach ($app['db'] as $row) { - //create the sql string - $table_name = $row['table']['name']; - $sql = "CREATE TABLE " . $row['table']['name'] . " (\n"; - $field_count = 0; - foreach ($row['fields'] as $field) { - if (!empty($field['deprecated']) and ($field['deprecated'] == "true")) { - //skip this field + public function sql() { + $sql = ''; + $sql_schema = ''; + foreach ($this->apps as $app) { + if (isset($app['db']) && count($app['db'])) { + foreach ($app['db'] as $row) { + //create the sql string + $table_name = $row['table']['name']; + $sql = "CREATE TABLE " . $row['table']['name'] . " (\n"; + $field_count = 0; + foreach ($row['fields'] as $field) { + if (!empty($field['deprecated']) and ($field['deprecated'] == "true")) { + //skip this field + } else { + if ($field_count > 0) { + $sql .= ",\n"; + } + if (is_array($field['name'])) { + $sql .= $field['name']['text'] . " "; + } else { + $sql .= $field['name'] . " "; + } + if (is_array($field['type'])) { + $sql .= $field['type'][$this->db_type]; + } else { + $sql .= $field['type']; + } + if (isset($field['key']) && isset($field['key']['type']) && ($field['key']['type'] == "primary")) { + $sql .= " PRIMARY KEY"; + } + if (isset($field['key']) && isset($field['key']['type']) && ($field['key']['type'] == "foreign")) { + if ($this->db_type == "pgsql") { + //$sql .= " references ".$field['key']['reference']['table']."(".$field['key']['reference']['field'].")"; } - else { - if ($field_count > 0 ) { $sql .= ",\n"; } - if (is_array($field['name'])) { - $sql .= $field['name']['text']." "; - } - else { - $sql .= $field['name']." "; - } - if (is_array($field['type'])) { - $sql .= $field['type'][$this->db_type]; - } - else { - $sql .= $field['type']; - } - if (isset($field['key']) && isset($field['key']['type']) && ($field['key']['type'] == "primary")) { - $sql .= " PRIMARY KEY"; - } - if (isset($field['key']) && isset($field['key']['type']) && ($field['key']['type'] == "foreign")) { - if ($this->db_type == "pgsql") { - //$sql .= " references ".$field['key']['reference']['table']."(".$field['key']['reference']['field'].")"; - } - if ($this->db_type == "sqlite") { - //$sql .= " references ".$field['key']['reference']['table']."(".$field['key']['reference']['field'].")"; - } - if ($this->db_type == "mysql") { - //$sql .= " references ".$field['key']['reference']['table']."(".$field['key']['reference']['field'].")"; - } - } - $field_count++; + if ($this->db_type == "sqlite") { + //$sql .= " references ".$field['key']['reference']['table']."(".$field['key']['reference']['field'].")"; + } + if ($this->db_type == "mysql") { + //$sql .= " references ".$field['key']['reference']['table']."(".$field['key']['reference']['field'].")"; } } - if ($this->db_type == "mysql") { - $sql .= ") ENGINE=INNODB;"; - } - else { - $sql .= ");"; - } - $this->result['sql'][] = $sql; - unset($sql); + $field_count++; + } } + if ($this->db_type == "mysql") { + $sql .= ") ENGINE=INNODB;"; + } else { + $sql .= ");"; + } + $this->result['sql'][] = $sql; + unset($sql); } } } + } //create the database schema - public function exec() { - foreach ($this->result['sql'] as $sql) { - //start the sql transaction - $this->database->beginTransaction(); - //execute the sql query - try { - $this->database->query($sql); - } - catch (PDOException $error) { - echo "error: " . $error->getMessage() . " sql: $sql
"; - } - //complete the transaction - $this->database->commit(); + public function exec() { + foreach ($this->result['sql'] as $sql) { + //start the sql transaction + $this->database->beginTransaction(); + //execute the sql query + try { + $this->database->query($sql); + } catch (PDOException $error) { + echo "error: " . $error->getMessage() . " sql: $sql
"; } + //complete the transaction + $this->database->commit(); } + } //check if a column exists in sqlite - private function sqlite_column_exists($table_info, $column_name) { - foreach ($table_info as $key => $row) { - if ($row['name'] == $column_name) { - return true; - } + private function sqlite_column_exists($table_info, $column_name) { + foreach ($table_info as $key => $row) { + if ($row['name'] == $column_name) { + return true; } - return $false; } + return $false; + } //check if a column exists - public function column_exists ($db_name, $table_name, $column_name) { + public function column_exists($db_name, $table_name, $column_name) { - if ($this->db_type == "sqlite") { - $table_info = $this->table_info($db_name, $table_name); - if ($this->sqlite_column_exists($table_info, $column_name)) { - return true; - } - else { - return false; - } - } - if ($this->db_type == "pgsql") { - $sql = "SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$table_name' limit 1) AND attname = '$column_name'; "; - } - if ($this->db_type == "mysql") { - //$sql .= "SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = '$db_name' and TABLE_NAME = '$table_name' and COLUMN_NAME = '$column_name' "; - $sql = "show columns from $table_name where field = '$column_name' "; - } - - if ($sql) { - $prep_statement = $this->database->db->prepare($sql); - $prep_statement->execute(); - $result = $prep_statement->fetchAll(PDO::FETCH_NAMED); - if (!$result) { - return false; - } - if (count($result) > 0) { - return true; - } - else { - return false; - } - unset ($prep_statement); + if ($this->db_type == "sqlite") { + $table_info = $this->table_info($db_name, $table_name); + if ($this->sqlite_column_exists($table_info, $column_name)) { + return true; + } else { + return false; } } + if ($this->db_type == "pgsql") { + $sql = "SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$table_name' limit 1) AND attname = '$column_name'; "; + } + if ($this->db_type == "mysql") { + //$sql .= "SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = '$db_name' and TABLE_NAME = '$table_name' and COLUMN_NAME = '$column_name' "; + $sql = "show columns from $table_name where field = '$column_name' "; + } - //get the table information - public function table_info($db_name, $table_name) { - if (empty($table_name)) { return false; } - if ($this->db_type == "sqlite") { - $sql = "PRAGMA table_info(".$table_name.");"; - } - if ($this->db_type == "pgsql") { - $sql = "SELECT ordinal_position, "; - $sql .= "column_name, "; - $sql .= "data_type, "; - $sql .= "column_default, "; - $sql .= "is_nullable, "; - $sql .= "character_maximum_length, "; - $sql .= "numeric_precision "; - $sql .= "FROM information_schema.columns "; - $sql .= "WHERE table_name = '".$table_name."' "; - $sql .= "and table_catalog = '".$db_name."' "; - $sql .= "ORDER BY ordinal_position; "; - } - if ($this->db_type == "mysql") { - $sql = "describe ".$table_name.";"; - } + if ($sql) { $prep_statement = $this->database->db->prepare($sql); $prep_statement->execute(); - return $prep_statement->fetchAll(PDO::FETCH_ASSOC); + $result = $prep_statement->fetchAll(PDO::FETCH_NAMED); + if (!$result) { + return false; + } + if (count($result) > 0) { + return true; + } else { + return false; + } + unset($prep_statement); } + } + + //get the table information + public function table_info($db_name, $table_name) { + if (empty($table_name)) { + return false; + } + if ($this->db_type == "sqlite") { + $sql = "PRAGMA table_info(" . $table_name . ");"; + } + if ($this->db_type == "pgsql") { + $sql = "SELECT ordinal_position, "; + $sql .= "column_name, "; + $sql .= "data_type, "; + $sql .= "column_default, "; + $sql .= "is_nullable, "; + $sql .= "character_maximum_length, "; + $sql .= "numeric_precision "; + $sql .= "FROM information_schema.columns "; + $sql .= "WHERE table_name = '" . $table_name . "' "; + $sql .= "and table_catalog = '" . $db_name . "' "; + $sql .= "ORDER BY ordinal_position; "; + } + if ($this->db_type == "mysql") { + $sql = "describe " . $table_name . ";"; + } + $prep_statement = $this->database->db->prepare($sql); + $prep_statement->execute(); + return $prep_statement->fetchAll(PDO::FETCH_ASSOC); + } //database table exists alternate - private function db_table_exists_alternate ($db_type, $table_name) { - $sql = "select count(*) from $table_name "; - $result = $this->database->query($sql); - if ($result > 0) { - return true; //table exists - } - else { - return false; //table doesn't exist - } + private function db_table_exists_alternate($db_type, $table_name) { + $sql = "select count(*) from $table_name "; + $result = $this->database->query($sql); + if ($result > 0) { + return true; //table exists + } else { + return false; //table doesn't exist } + } //database table exists - private function db_table_exists ($db_type, $db_name, $table_name) { - $sql = ""; - if ($db_type == "sqlite") { - $sql .= "SELECT * FROM sqlite_master WHERE type='table' and name='$table_name' "; + private function db_table_exists($db_type, $db_name, $table_name) { + $sql = ""; + if ($db_type == "sqlite") { + $sql .= "SELECT * FROM sqlite_master WHERE type='table' and name='$table_name' "; + } + if ($db_type == "pgsql") { + $sql .= "select * from pg_tables where schemaname='public' and tablename = '$table_name' "; + } + if ($db_type == "mysql") { + $sql .= "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = '$db_name' and TABLE_NAME = '$table_name' "; + } + $prep_statement = $this->database->db->prepare(check_sql($sql)); + $prep_statement->execute(); + $result = $prep_statement->fetchAll(PDO::FETCH_NAMED); + if (count($result) > 0) { + return true; //table exists + } else { + return false; //table doesn't exist + } + } + + //database table information + private function db_table_info($db_name, $db_type, $table_name) { + if (empty($table_name)) { + return false; + } + if ($db_type == "sqlite") { + $sql = "PRAGMA table_info(" . $table_name . ");"; + } + if ($db_type == "pgsql") { + $sql = "SELECT ordinal_position, "; + $sql .= "column_name, "; + $sql .= "data_type, "; + $sql .= "column_default, "; + $sql .= "is_nullable, "; + $sql .= "character_maximum_length, "; + $sql .= "numeric_precision "; + $sql .= "FROM information_schema.columns "; + $sql .= "WHERE table_name = '" . $table_name . "' "; + $sql .= "and table_catalog = '" . $db_name . "' "; + $sql .= "ORDER BY ordinal_position; "; + } + if ($db_type == "mysql") { + $sql = "describe " . $table_name . ";"; + } + $prep_statement = $this->database->db->prepare($sql); + $prep_statement->execute(); + return $prep_statement->fetchAll(PDO::FETCH_ASSOC); + } + + //database type + private function db_data_type($db_type, $table_info, $column_name) { + if ($db_type == "sqlite") { + foreach ($table_info as $key => $row) { + if ($row['name'] == $column_name) { + return $row['type']; + } } - if ($db_type == "pgsql") { - $sql .= "select * from pg_tables where schemaname='public' and tablename = '$table_name' "; + } + if ($db_type == "pgsql") { + foreach ($table_info as $key => $row) { + if ($row['column_name'] == $column_name) { + return $row['data_type']; + } } - if ($db_type == "mysql") { - $sql .= "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = '$db_name' and TABLE_NAME = '$table_name' "; + } + if ($db_type == "mysql") { + foreach ($table_info as $key => $row) { + if ($row['Field'] == $column_name) { + return $row['Type']; + } } + } + } + + //sqlite column exists + private function db_sqlite_column_exists($table_info, $column_name) { + foreach ($table_info as $key => $row) { + if ($row['name'] == $column_name) { + return true; + } + } + return $false; + } + + //database column exists + private function db_column_exists($db_type, $db_name, $table_name, $column_name) { + + if ($db_type == "sqlite") { + $table_info = $this->db_table_info($db_name, $db_type, $table_name); + if ($this->db_sqlite_column_exists($table_info, $column_name)) { + return true; + } else { + return false; + } + } + if ($db_type == "pgsql") { + $sql = "SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$table_name' limit 1) AND attname = '$column_name'; "; + } + if ($db_type == "mysql") { + //$sql .= "SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = '$db_name' and TABLE_NAME = '$table_name' and COLUMN_NAME = '$column_name' "; + $sql = "show columns from $table_name where field = '$column_name' "; + } + if ($sql) { $prep_statement = $this->database->db->prepare(check_sql($sql)); $prep_statement->execute(); $result = $prep_statement->fetchAll(PDO::FETCH_NAMED); - if (count($result) > 0) { - return true; //table exists - } - else { - return false; //table doesn't exist - } - } - - //database table information - private function db_table_info($db_name, $db_type, $table_name) { - if (empty($table_name)) { return false; } - if ($db_type == "sqlite") { - $sql = "PRAGMA table_info(".$table_name.");"; - } - if ($db_type == "pgsql") { - $sql = "SELECT ordinal_position, "; - $sql .= "column_name, "; - $sql .= "data_type, "; - $sql .= "column_default, "; - $sql .= "is_nullable, "; - $sql .= "character_maximum_length, "; - $sql .= "numeric_precision "; - $sql .= "FROM information_schema.columns "; - $sql .= "WHERE table_name = '".$table_name."' "; - $sql .= "and table_catalog = '".$db_name."' "; - $sql .= "ORDER BY ordinal_position; "; - } - if ($db_type == "mysql") { - $sql = "describe ".$table_name.";"; - } - $prep_statement = $this->database->db->prepare($sql); - $prep_statement->execute(); - return $prep_statement->fetchAll(PDO::FETCH_ASSOC); - } - - //database type - private function db_data_type($db_type, $table_info, $column_name) { - if ($db_type == "sqlite") { - foreach ($table_info as $key => $row) { - if ($row['name'] == $column_name) { - return $row['type']; - } - } - } - if ($db_type == "pgsql") { - foreach ($table_info as $key => $row) { - if ($row['column_name'] == $column_name) { - return $row['data_type']; - } - } - } - if ($db_type == "mysql") { - foreach ($table_info as $key => $row) { - if ($row['Field'] == $column_name) { - return $row['Type']; - } - } - } - } - - //sqlite column exists - private function db_sqlite_column_exists($table_info, $column_name) { - foreach ($table_info as $key => $row) { - if ($row['name'] == $column_name) { - return true; - } - } - return $false; - } - - //database column exists - private function db_column_exists ($db_type, $db_name, $table_name, $column_name) { - - if ($db_type == "sqlite") { - $table_info = $this->db_table_info($db_name, $db_type, $table_name); - if ($this->db_sqlite_column_exists($table_info, $column_name)) { - return true; - } - else { - return false; - } - } - if ($db_type == "pgsql") { - $sql = "SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$table_name' limit 1) AND attname = '$column_name'; "; - } - if ($db_type == "mysql") { - //$sql .= "SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = '$db_name' and TABLE_NAME = '$table_name' and COLUMN_NAME = '$column_name' "; - $sql = "show columns from $table_name where field = '$column_name' "; - } - if ($sql) { - $prep_statement = $this->database->db->prepare(check_sql($sql)); - $prep_statement->execute(); - $result = $prep_statement->fetchAll(PDO::FETCH_NAMED); - if (!empty($result)) { - return true; - } - else { - return false; - } - unset ($prep_statement); + if (!empty($result)) { + return true; + } else { + return false; } + unset($prep_statement); } + } //database column data type - private function db_column_data_type ($db_type, $db_name, $table_name, $column_name) { - $table_info = $this->db_table_info($db_name, $db_type, $table_name); - return $this->db_data_type($db_type, $table_info, $column_name); - } + private function db_column_data_type($db_type, $db_name, $table_name, $column_name) { + $table_info = $this->db_table_info($db_name, $db_type, $table_name); + return $this->db_data_type($db_type, $table_info, $column_name); + } //database create table - public function db_create_table ($apps, $db_type, $table) { - if (empty($apps)) { return false; } - if (is_array($apps)) foreach ($apps as $x => $app) { - if (!empty($app['db']) && is_array($app['db'])) foreach ($app['db'] as $y => $row) { - if (!empty($row['table']['name']) && is_array($row['table']['name'])) { - $table_name = $row['table']['name']['text']; - } - else { - $table_name = $row['table']['name']; - } - if ($table_name == $table) { - $sql = "CREATE TABLE " . $table_name . " (\n"; - (int)$field_count = 0; - if (!empty($row['fields']) && is_array($row['fields'])) foreach ($row['fields'] as $field) { - if (!empty($field['deprecated']) && $field['deprecated'] == "true") { - //skip this row - } - else { - if ($field_count > 0 ) { $sql .= ",\n"; } - if (!empty($field['name']) &&is_array($field['name'])) { - $sql .= $field['name']['text'] . " "; - } - else { - $sql .= $field['name'] . " "; - } - if (!empty($field['type']) &&is_array($field['type'])) { - $sql .= $field['type'][$db_type]; - } - else { - $sql .= $field['type']; - } - if (!empty($field['key']['type']) && $field['key']['type'] == "primary") { - $sql .= " PRIMARY KEY"; - } - $field_count++; - } + public function db_create_table($apps, $db_type, $table) { + if (empty($apps)) { + return false; + } + if (is_array($apps)) { + foreach ($apps as $x => $app) { + if (!empty($app['db']) && is_array($app['db'])) { + foreach ($app['db'] as $y => $row) { + if (!empty($row['table']['name']) && is_array($row['table']['name'])) { + $table_name = $row['table']['name']['text']; + } else { + $table_name = $row['table']['name']; + } + if ($table_name == $table) { + $sql = "CREATE TABLE " . $table_name . " (\n"; + (int) $field_count = 0; + if (!empty($row['fields']) && is_array($row['fields'])) { + foreach ($row['fields'] as $field) { + if (!empty($field['deprecated']) && $field['deprecated'] == "true") { + //skip this row + } else { + if ($field_count > 0) { + $sql .= ",\n"; + } + if (!empty($field['name']) && is_array($field['name'])) { + $sql .= $field['name']['text'] . " "; + } else { + $sql .= $field['name'] . " "; + } + if (!empty($field['type']) && is_array($field['type'])) { + $sql .= $field['type'][$db_type]; + } else { + $sql .= $field['type']; + } + if (!empty($field['key']['type']) && $field['key']['type'] == "primary") { + $sql .= " PRIMARY KEY"; + } + $field_count++; + } + } + } + $sql .= ");\n"; + return $sql; } - $sql .= ");\n"; - return $sql; } } } } + } //database insert - private function db_insert_into ($apps, $db_type, $table) { - global $db_name; - foreach ($apps as $x => $app) { - foreach ($app['db'] as $y => $row) { - if ($row['table']['name'] == $table) { - $sql = "INSERT INTO " . $row['table']['name'] . " ("; - $field_count = 0; - foreach ($row['fields'] as $field) { - if (!empty($field['deprecated']) && $field['deprecated'] == "true") { - //skip this field + private function db_insert_into($apps, $db_type, $table) { + global $db_name; + foreach ($apps as $x => $app) { + foreach ($app['db'] as $y => $row) { + if ($row['table']['name'] == $table) { + $sql = "INSERT INTO " . $row['table']['name'] . " ("; + $field_count = 0; + foreach ($row['fields'] as $field) { + if (!empty($field['deprecated']) && $field['deprecated'] == "true") { + //skip this field + } else { + if ($field_count > 0) { + $sql .= ","; } - else { - if ($field_count > 0 ) { $sql .= ","; } - if (is_array($field['name'])) { + if (is_array($field['name'])) { + $sql .= $field['name']['text']; + } else { + $sql .= $field['name']; + } + $field_count++; + } + } + $sql .= ")\n"; + $sql .= "SELECT "; + $field_count = 0; + foreach ($row['fields'] as $field) { + if (!empty($field['deprecated']) && $field['deprecated'] == "true") { + //skip this field + } else { + if ($field_count > 0) { + $sql .= ","; + } + if (is_array($field['name'])) { + if ($field['exists'] == "false") { + if (is_array($field['name']['deprecated'])) { + $found = false; + foreach ($field['name']['deprecated'] as $row) { + if ($this->db_column_exists($db_type, $db_name, 'tmp_' . $table, $row)) { + $sql .= $row; + $found = true; + break; + } + } + if (!$found) { + $sql .= "''"; + } + } else { + if ($this->db_column_exists($db_type, $db_name, 'tmp_' . $table, $field['name']['deprecated'])) { + $sql .= $field['name']['deprecated']; + } else { + $sql .= "''"; + } + } + } else { $sql .= $field['name']['text']; } - else { - $sql .= $field['name']; - } - $field_count++; + } else { + $sql .= $field['name']; } + $field_count++; } - $sql .= ")\n"; - $sql .= "SELECT "; - $field_count = 0; - foreach ($row['fields'] as $field) { + } + $sql .= " FROM tmp_" . $table . ";\n"; + return $sql; + } + } + } + } + + //datatase schema + public function schema($format = '') { + + //set the global variable + global $text, $output_format; + + if ($format == '') { + $format = $output_format; + } + + //get the db variables + //require_once "resources/classes/config.php"; + //$config = new config; + //$config_exists = $config->exists(); + //$config_path = $config->find(); + //$config->get(); + //$db_type = $config->db_type; + //$db_name = $config->db_name; + //$db_username = $config->db_username; + //$db_password = $config->db_password; + //$db_host = $config->db_host; + //$db_path = $config->db_path; + //$db_port = $config->db_port; + //includes files + require dirname(__DIR__, 2) . "/resources/require.php"; + + //add multi-lingual support + if (!isset($text)) { + $language = new text; + $text = $language->get(null, 'core/upgrade'); + } + + //PHP PDO check if table or column exists + //check if table exists + // SELECT * FROM sqlite_master WHERE type='table' AND name='v_cdr' + //check if column exists + // SELECT * FROM sqlite_master WHERE type='table' AND name='v_cdr' AND sql LIKE '%caller_id_name TEXT,%' + //aditional information + // http://www.sqlite.org/faq.html#q9 + //postgresql + //list all tables in the database + // SELECT table_name FROM pg_tables WHERE schemaname='public'; + //check if table exists + // SELECT * FROM pg_tables WHERE schemaname='public' AND table_name = 'v_groups' + //check if column exists + // SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'v_cdr') AND attname = 'caller_id_name'; + //mysql + //list all tables in the database + // SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'fusionpbx' + //check if table exists + // SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'fusionpbx' AND TABLE_NAME = 'v_groups' + //check if column exists + // SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = 'fusionpbx' AND TABLE_NAME = 'v_cdr' AND COLUMN_NAME = 'context' + //oracle + //check if table exists + // SELECT TABLE_NAME FROM ALL_TABLES + //update the app db array add exists true or false + $sql = ''; + foreach ($this->apps as $x => $app) { + if (isset($app['db'])) { + foreach ($app['db'] as $y => $row) { + if (isset($row['table']['name'])) { + if (is_array($row['table']['name'])) { + $table_name = $row['table']['name']['text']; + } else { + $table_name = $row['table']['name']; + } + } else { + //old array syntax + if (is_array($row['table'])) { + $table_name = $row['table']['text']; + } else { + $table_name = $row['table']; + } + } + if (!empty($table_name)) { + + //check if the table exists + if ($this->db_table_exists($db_type, $db_name, $table_name)) { + $this->apps[$x]['db'][$y]['exists'] = 'true'; + } else { + $this->apps[$x]['db'][$y]['exists'] = 'false'; + } + //check if the column exists + foreach ($row['fields'] as $z => $field) { if (!empty($field['deprecated']) && $field['deprecated'] == "true") { //skip this field - } - else { - if ($field_count > 0 ) { $sql .= ","; } + } else { if (is_array($field['name'])) { - if ($field['exists'] == "false") { - if (is_array($field['name']['deprecated'])) { - $found = false; - foreach ($field['name']['deprecated'] as $row) { - if ($this->db_column_exists ($db_type, $db_name, 'tmp_'.$table, $row)) { - $sql .= $row; - $found = true; - break; - } - } - if (!$found) { $sql .= "''"; } - } - else { - if ($this->db_column_exists ($db_type, $db_name, 'tmp_'.$table, $field['name']['deprecated'])) { - $sql .= $field['name']['deprecated']; - } - else { - $sql .= "''"; - } - } - } - else { - $sql .= $field['name']['text']; + $field_name = $field['name']['text']; + } else { + $field_name = $field['name']; + } + if (!empty($field_name)) { + if ($this->db_column_exists($db_type, $db_name, $table_name, $field_name)) { + //found + $this->apps[$x]['db'][$y]['fields'][$z]['exists'] = 'true'; + } else { + //not found + $this->apps[$x]['db'][$y]['fields'][$z]['exists'] = 'false'; } } - else { - $sql .= $field['name']; - } - $field_count++; + unset($field_name); } } - $sql .= " FROM tmp_".$table.";\n"; - return $sql; + unset($table_name); } } } } - //datatase schema - public function schema ($format = '') { + //prepare the variables + $sql_update = ''; - //set the global variable - global $text, $output_format; + //add missing tables and fields + foreach ($this->apps as $x => $app) { + if (isset($app['db'])) { + foreach ($app['db'] as $y => $row) { + if (is_array($row['table']['name'])) { + $table_name = $row['table']['name']['text']; + if ($this->db_table_exists($db_type, $db_name, $row['table']['name']['deprecated'])) { + $row['exists'] = "false"; //testing + if ($db_type == "pgsql") { + $sql_update .= "ALTER TABLE " . $row['table']['name']['deprecated'] . " RENAME TO " . $row['table']['name']['text'] . ";\n"; + } + if ($db_type == "mysql") { + $sql_update .= "RENAME TABLE " . $row['table']['name']['deprecated'] . " TO " . $row['table']['name']['text'] . ";\n"; + } + if ($db_type == "sqlite") { + $sql_update .= "ALTER TABLE " . $row['table']['name']['deprecated'] . " RENAME TO " . $row['table']['name']['text'] . ";\n"; + } + } else { + if ($this->db_table_exists($db_type, $db_name, $row['table']['name']['text'])) { + $row['exists'] = "true"; + } else { + $row['exists'] = "false"; + $sql_update .= $this->db_create_table($this->apps, $db_type, $row['table']['name']['text']); + } + } + } else { + if ($this->db_table_exists($db_type, $db_name, $row['table']['name'])) { + $row['exists'] = "true"; + } else { + $row['exists'] = "false"; + } + $table_name = $row['table']['name']; + } - if ($format == '') $format = $output_format; + //check if the table exists + if ($row['exists'] == "true") { + if (count($row['fields']) > 0) { + foreach ($row['fields'] as $z => $field) { + if (!empty($field['deprecated']) && $field['deprecated'] == "true") { + //skip this field + } else { + //get the data type + if (is_array($field['type'])) { + $field_type = $field['type'][$db_type]; + } else { + $field_type = $field['type']; + } + //get the field name + if (is_array($field['name'])) { + $field_name = $field['name']['text']; + } else { + $field_name = $field['name']; + } - //get the db variables - //require_once "resources/classes/config.php"; - //$config = new config; - //$config_exists = $config->exists(); - //$config_path = $config->find(); - //$config->get(); - //$db_type = $config->db_type; - //$db_name = $config->db_name; - //$db_username = $config->db_username; - //$db_password = $config->db_password; - //$db_host = $config->db_host; - //$db_path = $config->db_path; - //$db_port = $config->db_port; + //check if the field exists + // if ($this->db_column_exists($db_type, $db_name, $table_name, $field_name)) { + // $field['exists'] = "true"; + // } + // else { + // $field['exists'] = "false"; + // } + //add or rename fields + if (isset($field['name']['deprecated']) && $this->db_column_exists($db_type, $db_name, $table_name, $field['name']['deprecated'])) { + if ($db_type == "pgsql") { + $sql_update .= "ALTER TABLE " . $table_name . " RENAME COLUMN " . $field['name']['deprecated'] . " to " . $field['name']['text'] . ";\n"; + } + if ($db_type == "mysql") { + $field_type = str_replace("AUTO_INCREMENT PRIMARY KEY", "", $field_type); + $sql_update .= "ALTER TABLE " . $table_name . " CHANGE " . $field['name']['deprecated'] . " " . $field['name']['text'] . " " . $field_type . ";\n"; + } + if ($db_type == "sqlite") { + //a change has been made to the field name + $this->apps[$x]['db'][$y]['rebuild'] = 'true'; + } + } else { + //find missing fields and add them + if ($field['exists'] == "false") { + $sql_update .= "ALTER TABLE " . $table_name . " ADD " . $field_name . " " . $field_type . ";\n"; + } + } - //includes files - require dirname(__DIR__, 2) . "/resources/require.php"; + //change the data type if it has been changed + //if the data type in the app db array is different than the type in the database then change the data type + if ($this->data_types) { + $db_field_type = $this->db_column_data_type($db_type, $db_name, $table_name, $field_name); + $field_type_array = explode("(", $field_type); + $field_type = $field_type_array[0]; + if (trim($db_field_type) != trim($field_type) && !empty($db_field_type)) { + if ($db_type == "pgsql") { + if (strtolower($field_type) == "uuid") { + $sql_update .= "ALTER TABLE " . $table_name . " ALTER COLUMN " . $field_name . " TYPE uuid USING\n"; + $sql_update .= "CAST(regexp_replace(" . $field_name . ", '([A-Z0-9]{4})([A-Z0-9]{12})', E'\\1-\\2')\n"; + $sql_update .= "AS uuid);\n"; + } else { + //field type has not changed + if ($db_field_type == "integer" && strtolower($field_type) == "serial") { - //add multi-lingual support - if (!isset($text)) { - $language = new text; - $text = $language->get(null,'core/upgrade'); + } else if ($db_field_type == "timestamp without time zone" && strtolower($field_type) == "timestamp") { + + } else if ($db_field_type == "timestamp without time zone" && strtolower($field_type) == "datetime") { + + } else if ($db_field_type == "timestamp with time zone" && strtolower($field_type) == "timestamptz") { + + } else if ($db_field_type == "integer" && strtolower($field_type) == "numeric") { + + } else if ($db_field_type == "character" && strtolower($field_type) == "char") { + + } + //field type has changed + else { + switch ($field_type) { + case 'numeric': $using = $field_name . "::numeric"; + break; + case 'timestamp': + case 'datetime': $using = $field_name . "::timestamp without time zone"; + break; + case 'timestamptz': $using = $field_name . "::timestamp with time zone"; + break; + case 'boolean': $using = $field_name . "::boolean"; + break; + default: unset($using); + } + $sql_update .= "ALTER TABLE " . $table_name . " ALTER COLUMN " . $field_name . " TYPE " . $field_type . " " . ($using ? "USING " . $using : null) . ";\n"; + } + } + } + if ($db_type == "mysql") { + $type = explode("(", $db_field_type); + if ($type[0] == $field_type) { + //do nothing + } else if ($field_type == "numeric" && $type[0] == "decimal") { + //do nothing + } else { + $sql_update .= "ALTER TABLE " . $table_name . " modify " . $field_name . " " . $field_type . ";\n"; + } + unset($type); + } + if ($db_type == "sqlite") { + //a change has been made to the field type + $this->apps[$x]['db'][$y]['rebuild'] = 'true'; + } + } + } + } + } + } + } elseif (!is_array($row['table']['name'])) { + //create table + $sql_update .= $this->db_create_table($this->apps, $db_type, $row['table']['name']); + } } - - //PHP PDO check if table or column exists - //check if table exists - // SELECT * FROM sqlite_master WHERE type='table' AND name='v_cdr' - //check if column exists - // SELECT * FROM sqlite_master WHERE type='table' AND name='v_cdr' AND sql LIKE '%caller_id_name TEXT,%' - //aditional information - // http://www.sqlite.org/faq.html#q9 - - //postgresql - //list all tables in the database - // SELECT table_name FROM pg_tables WHERE schemaname='public'; - //check if table exists - // SELECT * FROM pg_tables WHERE schemaname='public' AND table_name = 'v_groups' - //check if column exists - // SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'v_cdr') AND attname = 'caller_id_name'; - //mysql - //list all tables in the database - // SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'fusionpbx' - //check if table exists - // SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'fusionpbx' AND TABLE_NAME = 'v_groups' - //check if column exists - // SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = 'fusionpbx' AND TABLE_NAME = 'v_cdr' AND COLUMN_NAME = 'context' - //oracle - //check if table exists - // SELECT TABLE_NAME FROM ALL_TABLES - - //update the app db array add exists true or false - $sql = ''; - foreach ($this->apps as $x => $app) { - if (isset($app['db'])) foreach ($app['db'] as $y => $row) { - if (isset($row['table']['name'])) { - if (is_array($row['table']['name'])) { - $table_name = $row['table']['name']['text']; - } - else { - $table_name = $row['table']['name']; - } - } - else { - //old array syntax - if (is_array($row['table'])) { - $table_name = $row['table']['text']; - } - else { - $table_name = $row['table']; - } - } - if (!empty($table_name)) { - - //check if the table exists - if ($this->db_table_exists($db_type, $db_name, $table_name)) { - $this->apps[$x]['db'][$y]['exists'] = 'true'; - } - else { - $this->apps[$x]['db'][$y]['exists'] = 'false'; - } - //check if the column exists - foreach ($row['fields'] as $z => $field) { - if (!empty($field['deprecated']) && $field['deprecated'] == "true") { - //skip this field - } - else { - if (is_array($field['name'])) { - $field_name = $field['name']['text']; - } - else { - $field_name = $field['name']; - } - if (!empty($field_name)) { - if ($this->db_column_exists ($db_type, $db_name, $table_name, $field_name)) { - //found - $this->apps[$x]['db'][$y]['fields'][$z]['exists'] = 'true'; - } - else { - //not found - $this->apps[$x]['db'][$y]['fields'][$z]['exists'] = 'false'; - } - } - unset($field_name); - } - } - unset($table_name); + } + } + //rebuild and populate the table + foreach ($this->apps as $x => $app) { + if (isset($app['db'])) { + foreach ($app['db'] as $y => $row) { + if (is_array($row['table']['name'])) { + $table_name = $row['table']['name']['text']; + } else { + $table_name = $row['table']['name']; + } + if (!empty($field['rebuild']) && $row['rebuild'] == "true") { + if ($db_type == "sqlite") { + //start the transaction + //$sql_update .= "BEGIN TRANSACTION;\n"; + //rename the table + $sql_update .= "ALTER TABLE " . $table_name . " RENAME TO tmp_" . $table_name . ";\n"; + //create the table + $sql_update .= $this->db_create_table($this->apps, $db_type, $table_name); + //insert the data into the new table + $sql_update .= $this->db_insert_into($this->apps, $db_type, $table_name); + //drop the old table + $sql_update .= "DROP TABLE tmp_" . $table_name . ";\n"; + //commit the transaction + //$sql_update .= "COMMIT;\n"; } } } + } + } - //prepare the variables - $sql_update = ''; + // initialize response variable + $response = ''; - //add missing tables and fields - foreach ($this->apps as $x => $app) { - if (isset($app['db'])) foreach ($app['db'] as $y => $row) { + //display results as html + if ($format == "html") { + //show the database type + $response .= "" . $text['header-database_type'] . ": " . $db_type . "

"; + //start the table + $response .= "\n"; + //show the changes + if (!empty($sql_update)) { + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + } + //list all tables + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + //build the html while looping through the app db array + $sql = ''; + foreach ($this->apps as $app) { + if (isset($app['db'])) { + foreach ($app['db'] as $row) { if (is_array($row['table']['name'])) { $table_name = $row['table']['name']['text']; - if ($this->db_table_exists($db_type, $db_name, $row['table']['name']['deprecated'])) { - $row['exists'] = "false"; //testing - if ($db_type == "pgsql") { - $sql_update .= "ALTER TABLE ".$row['table']['name']['deprecated']." RENAME TO ".$row['table']['name']['text'].";\n"; - } - if ($db_type == "mysql") { - $sql_update .= "RENAME TABLE ".$row['table']['name']['deprecated']." TO ".$row['table']['name']['text'].";\n"; - } - if ($db_type == "sqlite") { - $sql_update .= "ALTER TABLE ".$row['table']['name']['deprecated']." RENAME TO ".$row['table']['name']['text'].";\n"; - } - } - else { - if ($this->db_table_exists($db_type, $db_name, $row['table']['name']['text'])) { - $row['exists'] = "true"; - } - else { - $row['exists'] = "false"; - $sql_update .= $this->db_create_table($this->apps, $db_type, $row['table']['name']['text']); - } - } - } - else { - if ($this->db_table_exists($db_type, $db_name, $row['table']['name'])) { - $row['exists'] = "true"; - } - else { - $row['exists'] = "false"; - } + } else { $table_name = $row['table']['name']; } + $response .= "\n"; //check if the table exists - if ($row['exists'] == "true") { - if (count($row['fields']) > 0) { - foreach ($row['fields'] as $z => $field) { - if (!empty($field['deprecated']) && $field['deprecated'] == "true") { - //skip this field - } - else { - //get the data type - if (is_array($field['type'])) { - $field_type = $field['type'][$db_type]; - } - else { - $field_type = $field['type']; - } - //get the field name - if (is_array($field['name'])) { - $field_name = $field['name']['text']; - } - else { - $field_name = $field['name']; - } + if ($row['exists'] == "true") { + $response .= "\n"; + $response .= "\n"; - //check if the field exists - // if ($this->db_column_exists($db_type, $db_name, $table_name, $field_name)) { - // $field['exists'] = "true"; - // } - // else { - // $field['exists'] = "false"; - // } - - //add or rename fields - if (isset($field['name']['deprecated']) && $this->db_column_exists ($db_type, $db_name, $table_name, $field['name']['deprecated'])) { - if ($db_type == "pgsql") { - $sql_update .= "ALTER TABLE ".$table_name." RENAME COLUMN ".$field['name']['deprecated']." to ".$field['name']['text'].";\n"; - } - if ($db_type == "mysql") { - $field_type = str_replace("AUTO_INCREMENT PRIMARY KEY", "", $field_type); - $sql_update .= "ALTER TABLE ".$table_name." CHANGE ".$field['name']['deprecated']." ".$field['name']['text']." ".$field_type.";\n"; - } - if ($db_type == "sqlite") { - //a change has been made to the field name - $this->apps[$x]['db'][$y]['rebuild'] = 'true'; - } - } - else { - //find missing fields and add them - if ($field['exists'] == "false") { - $sql_update .= "ALTER TABLE ".$table_name." ADD ".$field_name." ".$field_type.";\n"; - } - } - - //change the data type if it has been changed - //if the data type in the app db array is different than the type in the database then change the data type - if ($this->data_types) { - $db_field_type = $this->db_column_data_type ($db_type, $db_name, $table_name, $field_name); - $field_type_array = explode("(", $field_type); - $field_type = $field_type_array[0]; - if (trim($db_field_type) != trim($field_type) && !empty($db_field_type)) { - if ($db_type == "pgsql") { - if (strtolower($field_type) == "uuid") { - $sql_update .= "ALTER TABLE ".$table_name." ALTER COLUMN ".$field_name." TYPE uuid USING\n"; - $sql_update .= "CAST(regexp_replace(".$field_name.", '([A-Z0-9]{4})([A-Z0-9]{12})', E'\\1-\\2')\n"; - $sql_update .= "AS uuid);\n"; - } - else { - //field type has not changed - if ($db_field_type == "integer" && strtolower($field_type) == "serial") { } - else if ($db_field_type == "timestamp without time zone" && strtolower($field_type) == "timestamp") { } - else if ($db_field_type == "timestamp without time zone" && strtolower($field_type) == "datetime") { } - else if ($db_field_type == "timestamp with time zone" && strtolower($field_type) == "timestamptz") { } - else if ($db_field_type == "integer" && strtolower($field_type) == "numeric") { } - else if ($db_field_type == "character" && strtolower($field_type) == "char") { } - //field type has changed - else { - switch ($field_type) { - case 'numeric': $using = $field_name."::numeric"; break; - case 'timestamp': - case 'datetime': $using = $field_name."::timestamp without time zone"; break; - case 'timestamptz': $using = $field_name."::timestamp with time zone"; break; - case 'boolean': $using = $field_name."::boolean"; break; - default: unset($using); - } - $sql_update .= "ALTER TABLE ".$table_name." ALTER COLUMN ".$field_name." TYPE ".$field_type." ".($using ? "USING ".$using : null).";\n"; - } - } - } - if ($db_type == "mysql") { - $type = explode("(", $db_field_type); - if ($type[0] == $field_type) { - //do nothing - } - else if ($field_type == "numeric" && $type[0] == "decimal") { - //do nothing - } - else { - $sql_update .= "ALTER TABLE ".$table_name." modify ".$field_name." ".$field_type.";\n"; - } - unset($type); - } - if ($db_type == "sqlite") { - //a change has been made to the field type - $this->apps[$x]['db'][$y]['rebuild'] = 'true'; - } - } - } - } - } - } - } - elseif (!is_array($row['table']['name'])) { - //create table - $sql_update .= $this->db_create_table($this->apps, $db_type, $row['table']['name']); - } - } - } - //rebuild and populate the table - foreach ($this->apps as $x => $app) { - if (isset($app['db'])) foreach ($app['db'] as $y => $row) { - if (is_array($row['table']['name'])) { - $table_name = $row['table']['name']['text']; - } - else { - $table_name = $row['table']['name']; - } - if (!empty($field['rebuild']) && $row['rebuild'] == "true") { - if ($db_type == "sqlite") { - //start the transaction - //$sql_update .= "BEGIN TRANSACTION;\n"; - //rename the table - $sql_update .= "ALTER TABLE ".$table_name." RENAME TO tmp_".$table_name.";\n"; - //create the table - $sql_update .= $this->db_create_table($this->apps, $db_type, $table_name); - //insert the data into the new table - $sql_update .= $this->db_insert_into($this->apps, $db_type, $table_name); - //drop the old table - $sql_update .= "DROP TABLE tmp_".$table_name.";\n"; - //commit the transaction - //$sql_update .= "COMMIT;\n"; - } - } - } - } - - // initialize response variable - $response = ''; - - //display results as html - if ($format == "html") { - //show the database type - $response .= "".$text['header-database_type'].": ".$db_type. "

"; - //start the table - $response .= "
\n"; + $response .= "
\n"; + $response .= "" . $text['label-sql_changes'] . ":
\n"; + $response .= "
\n";
+					$response .= $sql_update;
+					$response .= "
\n"; + $response .= "
\n"; + $response .= "
" . $text['label-table'] . "" . $text['label-exists'] . "" . $text['label-details'] . "
" . $table_name . "" . $text['option-true'] . "
\n"; - //show the changes - if (!empty($sql_update)) { - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - } - //list all tables - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - //build the html while looping through the app db array - $sql = ''; - foreach ($this->apps as $app) { - if (isset($app['db'])) foreach ($app['db'] as $row) { - if (is_array($row['table']['name'])) { - $table_name = $row['table']['name']['text']; - } - else { - $table_name = $row['table']['name']; - } + if (count($row['fields']) > 0) { + $response .= "\n"; } + } else { + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; } - //end the list of tables - $response .= "
\n"; - $response .= "
\n"; - $response .= "".$text['label-sql_changes'].":
\n"; - $response .= "
\n";
-								$response .= $sql_update;
-								$response .= "
\n"; - $response .= "
\n"; - $response .= "
".$text['label-table']."".$text['label-exists']."".$text['label-details']."
\n"; + //show the list of columns + $response .= "\n"; $response .= "\n"; - - //check if the table exists - if ($row['exists'] == "true") { - $response .= "\n"; - $response .= "\n"; - - if (count($row['fields']) > 0) { - $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + foreach ($row['fields'] as $field) { + if (!empty($field['deprecated']) && $field['deprecated'] == "true") { + //skip this field + } else { + if (is_array($field['name'])) { + $field_name = $field['name']['text']; + } else { + $field_name = $field['name']; } + if (is_array($field['type'])) { + $field_type = $field['type'][$db_type]; + } else { + $field_type = $field['type']; + } + $response .= "\n"; + $response .= "\n"; + $response .= "\n"; + if ($field['exists'] == "true") { + $response .= "\n"; + $response .= "\n"; + } else { + $response .= "\n"; + $response .= "\n"; + } + $response .= "\n"; } - else { - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - } - $response .= "\n"; + } + $response .= "
".$table_name."".$text['option-true']."\n"; - //show the list of columns - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - foreach ($row['fields'] as $field) { - if (!empty($field['deprecated']) && $field['deprecated'] == "true") { - //skip this field - } - else { - if (is_array($field['name'])) { - $field_name = $field['name']['text']; - } - else { - $field_name = $field['name']; - } - if (is_array($field['type'])) { - $field_type = $field['type'][$db_type]; - } - else { - $field_type = $field['type']; - } - $response .= "\n"; - $response .= "\n"; - $response .= "\n"; - if ($field['exists'] == "true") { - $response .= "\n"; - $response .= "\n"; - } - else { - $response .= "\n"; - $response .= "\n"; - } - $response .= "\n"; - } - } - $response .= "
".$text['label-name']."".$text['label-type']."".$text['label-exists']."
".$field_name."".$field_type."".$text['option-true']." ".$text['option-false']." 
\n"; - $response .= "
" . $text['label-name'] . "" . $text['label-type'] . "" . $text['label-exists'] . "
" . $field_name . "" . $field_type . "" . $text['option-true'] . " " . $text['option-false'] . " 
$table_name".$text['label-exists']."
".$text['option-false']."
 
\n"; + $response .= "
$table_name" . $text['label-exists'] . "
" . $text['option-false'] . "
 
\n"; - $response .= "
\n"; - - } - - //loop line by line through all the lines of sql code - $x = 0; - if (empty($sql_update) && $format == "text") { - $response .= " ".$text['label-schema'].": ".$text['label-no_change']."\n"; + $response .= "\n"; } - else { + } + } + //end the list of tables + $response .= "\n"; + $response .= "
\n"; + } + + //loop line by line through all the lines of sql code + $x = 0; + if (empty($sql_update) && $format == "text") { + $response .= " " . $text['label-schema'] . ": " . $text['label-no_change'] . "\n"; + } else { + if ($format == "text") { + $response .= " " . $text['label-schema'] . "\n"; + } + //$this->db->beginTransaction(); + $update_array = explode(";", $sql_update); + foreach ($update_array as $sql) { + if (strlen(trim($sql))) { + try { + $this->database->db->query(trim($sql)); if ($format == "text") { - $response .= " ".$text['label-schema']."\n"; + $response .= " $sql;\n"; } - //$this->db->beginTransaction(); - $update_array = explode(";", $sql_update); - foreach($update_array as $sql) { - if (strlen(trim($sql))) { - try { - $this->database->db->query(trim($sql)); - if ($format == "text") { - $response .= " $sql;\n"; - } - } - catch (PDOException $error) { - $response .= " error: " . $error->getMessage() . " sql: $sql\n"; - } - } - } - //$this->db->commit(); - $response .= "\n"; - unset ($sql_update, $sql); - } - - //refresh each postgresql subscription with its publication - if ($db_type == "pgsql") { - //get the list of postgresql subscriptions - $sql = "select subname from pg_subscription; "; - $pg_subscriptions = $this->database->select($sql, null, 'all'); - unset($sql, $parameters); - - //refresh each subscription publication - foreach ($pg_subscriptions as $row) { - $sql = "ALTER SUBSCRIPTION ".$row['subname']." REFRESH PUBLICATION;"; - $response .= $sql; - $this->database->execute($sql); + } catch (PDOException $error) { + $response .= " error: " . $error->getMessage() . " sql: $sql\n"; } } + } + //$this->db->commit(); + $response .= "\n"; + unset($sql_update, $sql); + } - //handle response - //if ($output == "echo") { - // echo $response; - //} - //else if ($output == "return") { - return $response; - //} - } //end function + //refresh each postgresql subscription with its publication + if ($db_type == "pgsql") { + //get the list of postgresql subscriptions + $sql = "select subname from pg_subscription; "; + $pg_subscriptions = $this->database->select($sql, null, 'all'); + unset($sql, $parameters); + + //refresh each subscription publication + foreach ($pg_subscriptions as $row) { + $sql = "ALTER SUBSCRIPTION " . $row['subname'] . " REFRESH PUBLICATION;"; + $response .= $sql; + $this->database->execute($sql); + } + } + + //handle response + //if ($output == "echo") { + // echo $response; + //} + //else if ($output == "return") { + return $response; + //} + } //end function } + } //example use - //require_once "resources/classes/schema.php"; - //$obj = new schema; - //$obj->db_type = $db_type; - //$obj->schema(); - //$result_array = $schema->obj['sql']; - //print_r($result_array); - +//require_once "resources/classes/schema.php"; +//$obj = new schema; +//$obj->db_type = $db_type; +//$obj->schema(); +//$result_array = $schema->obj['sql']; +//print_r($result_array); ?> From bc22ab8cc4263dcd1bdf6cdcea243d04f7d80504 Mon Sep 17 00:00:00 2001 From: fusionate Date: Tue, 28 Jan 2025 17:18:28 -0700 Subject: [PATCH 35/89] Contact - View: Show speed dial prefix and number after a Contact's number, if defined. --- core/contacts/contact_phones_view.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/core/contacts/contact_phones_view.php b/core/contacts/contact_phones_view.php index 4f0cf25874..81fe1f4278 100644 --- a/core/contacts/contact_phones_view.php +++ b/core/contacts/contact_phones_view.php @@ -51,6 +51,29 @@ //show if exists if (!empty($contact_phones)) { + //detect speed dial prefix from dialplan + $sql = "select dialplan_detail_data from v_dialplan_details "; + $sql .= "where domain_uuid = :domain_uuid "; + $sql .= "and dialplan_uuid = ( "; + $sql .= " select dialplan_uuid from v_dialplan_details "; + $sql .= " where domain_uuid = :domain_uuid "; + $sql .= " and dialplan_detail_data like 'app.lua speed_dial%' "; + $sql .= " and (dialplan_detail_enabled = true or dialplan_detail_enabled is null) "; + $sql .= " limit 1 "; + $sql .= ") "; + $sql .= "and dialplan_detail_tag = 'condition' "; + $sql .= "and dialplan_detail_type = 'destination_number' "; + $sql .= "and dialplan_detail_data like '^\\\\%' "; + $sql .= "and (dialplan_detail_enabled = true or dialplan_detail_enabled is null) "; + $sql .= "limit 1"; + $parameters['domain_uuid'] = $domain_uuid; + $database = new database; + $speed_dial_condition = $database->select($sql, $parameters, 'column'); + if (!empty($speed_dial_condition)) { + $speed_dial_prefix = str_replace('(.*)', '', trim($speed_dial_condition,'^\$')); // default: ^\*0(.*)$ + } + unset($sql, $speed_dial_condition); + //javascript function: send_cmd echo "