From 9f2e4c4ba300bf7481e3c077aff9cbc8b6e9c8cf Mon Sep 17 00:00:00 2001 From: Tim Fry Date: Tue, 26 Nov 2024 02:29:24 -0400 Subject: [PATCH] allow base64 recordings fix outstanding bugs - still must add sleep and execute functions --- app/phrases/phrase_edit.php | 53 ++++++++++--------- app/phrases/resources/classes/phrases.php | 24 +++++---- .../resources/javascript/phrase_edit.js | 21 ++++---- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/app/phrases/phrase_edit.php b/app/phrases/phrase_edit.php index c97460eed3..60a9df6c40 100644 --- a/app/phrases/phrase_edit.php +++ b/app/phrases/phrase_edit.php @@ -44,6 +44,13 @@ function build_data_array_from_post() { $drop_rows = []; $drop_row_count = 0; + //load sound files from the switch so we can validate selections + $sound_files = (new file)->sounds(); + + //recording_files are: + // 'recording_uuid' => 'recording.wav' + // OR + // 'recording_uuid' => '${lua streamfile.lua ' . base64_data .'}' $recording_files = phrases::get_all_domain_recordings($settings); //update the phrase information $array['phrases'][0]['domain_uuid'] = $domain_uuid; @@ -53,10 +60,6 @@ function build_data_array_from_post() { $array['phrases'][0]['phrase_enabled'] = $phrase_enabled; $array['phrases'][0]['phrase_description'] = $phrase_description; for ($i = 0; $i < count($_POST['phrase_detail_function']); $i++) { - //check for valid uuids - if (!empty($_POST['phrase_detail_uuid'][$i]) && !is_uuid($_POST['phrase_detail_uuid'][$i])) { - continue; - } //check for the empty rows to delete if (empty($_POST['phrase_detail_data'][$i]) && !empty($_POST['phrase_detail_uuid'][$i])) { $drop_rows['phrase_details'][$drop_row_count++]['phrase_detail_uuid'] = $_POST['phrase_detail_uuid'][$i]; @@ -64,6 +67,21 @@ function build_data_array_from_post() { } //only save rows with data if (!empty($_POST['phrase_detail_data'][$i])) { + $recording_uuid_or_file = $_POST['phrase_detail_data'][$i]; + //check for valid recordings and files + if (is_uuid($recording_uuid_or_file)) { + //recording UUID + $file = $recording_files[$recording_uuid_or_file]; + } else { + //not a recording so must be valid path inside the switch recording files + if (in_array($recording_uuid_or_file, $sound_files)) { + //valid switch audio file + $file = $recording_uuid_or_file; + } else { + //ignore an invalid audio file + continue; + } + } //build data array if ($_POST['phrase_detail_function'][$i] == 'execute' && substr($_POST['phrase_detail_data'][$i], 0,5) != "sleep" && !permission_exists("phrase_execute")) { header("Location: phrase_edit.php?id=".$phrase_uuid); @@ -78,7 +96,6 @@ function build_data_array_from_post() { } else { $phrase_detail_uuid = uuid(); } - $recording_uuid = $_POST['phrase_detail_data'][$i]; $array['phrase_details'][$i]['phrase_detail_uuid'] = $phrase_detail_uuid; $array['phrase_details'][$i]['phrase_uuid'] = $phrase_uuid; $array['phrase_details'][$i]['domain_uuid'] = $domain_uuid; @@ -86,7 +103,7 @@ function build_data_array_from_post() { $array['phrase_details'][$i]['phrase_detail_tag'] = $_POST['phrase_detail_tag']; $array['phrase_details'][$i]['phrase_detail_pattern'] = $_POST['phrase_detail_pattern'] ?? null; $array['phrase_details'][$i]['phrase_detail_function'] = $_POST['phrase_detail_function'][$i]; - $array['phrase_details'][$i]['phrase_detail_data'] = $recording_files[$recording_uuid]; //path and filename of recording + $array['phrase_details'][$i]['phrase_detail_data'] = $file; //path and filename of recording $array['phrase_details'][$i]['phrase_detail_method'] = $_POST['phrase_detail_method'] ?? null; $array['phrase_details'][$i]['phrase_detail_type'] = $_POST['phrase_detail_type'] ?? null; $array['phrase_details'][$i]['phrase_detail_group'] = $_POST['phrase_detail_group']; @@ -227,22 +244,8 @@ if (count($_POST) > 0) { } if (!empty($_POST['phrase_detail_function'])) { $array = build_data_array_from_post(); - //execute update/insert - $p = new permissions; - $p->add('phrase_detail_add', 'temp'); - $p->add('phrase_detail_edit', 'temp'); - $p->add('phrase_detail_delete', 'temp'); - $database->app_name = 'phrases'; - $database->app_uuid = '5c6f597c-9b78-11e4-89d3-123b93f75cba'; - if (count($array) > 0) { - $database->save($array); - } - if (count($drop_rows) > 0) { - $database->delete($drop_rows); - } - $p->delete('phrase_detail_add', 'temp'); } - //execute update/insert + //execute update/insert $p = new permissions; $p->add('phrase_detail_add', 'temp'); $p->add('phrase_detail_edit', 'temp'); @@ -250,10 +253,12 @@ if (count($_POST) > 0) { $database->app_name = 'phrases'; $database->app_uuid = '5c6f597c-9b78-11e4-89d3-123b93f75cba'; if (count($array) > 0) { - //$database->save($array); + $database->save($array); + unset($array); } if (count($drop_rows) > 0) { $database->delete($drop_rows); + unset($drop_rows); } $p->delete('phrase_detail_add', 'temp'); //clear the cache @@ -387,7 +392,7 @@ if (count($_POST) > 0) { if ($action == "update" && permission_exists('phrase_delete')) { echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'name'=>'btn_delete','style'=>'margin-left: 15px;','onclick'=>"modal_open('modal-delete','btn_delete');"]); } - echo button::create(['type'=>'submit','label'=>$text['button-save'],'icon'=>$_SESSION['theme']['button_icon_save'],'id'=>'btn_save','style'=>'margin-left: 15px;']); + echo button::create(['type'=>'submit','onclick'=>'submit_phrase()','label'=>$text['button-save'],'icon'=>$_SESSION['theme']['button_icon_save'],'id'=>'btn_save','style'=>'margin-left: 15px;']); echo " \n"; echo "
\n"; echo "\n"; @@ -453,7 +458,7 @@ if (count($_POST) > 0) { echo " \n"; echo " \n"; echo " \n"; - echo " "; + echo " "; // if (if_group("superadmin")) { // echo " \n"; // } diff --git a/app/phrases/resources/classes/phrases.php b/app/phrases/resources/classes/phrases.php index f60dbea25b..9d06897356 100644 --- a/app/phrases/resources/classes/phrases.php +++ b/app/phrases/resources/classes/phrases.php @@ -451,6 +451,7 @@ if (!class_exists('phrases')) { /** * Returns an associative array of recordings with the uuid as key and recording filename as value. + * When the recording is a base64 encoded recording, the filename returned is the filename only with no path. * @param settings $settings Settings object * @param int $limit (Optional) Limit the number of results returned * @return array @@ -459,18 +460,19 @@ if (!class_exists('phrases')) { //set defaults $recordings = []; $parameters = []; - //get the database object and current domain_uuid + //get the database object from the settings object $database = $settings->database(); - //get the domain name - $domain_name = $database->select("SELECT domain_name from v_domains where domain_uuid = :domain_uuid", ['domain_uuid' => $database->domain_uuid], 'column'); + //get the domain name using the domain_uuid in the database object + $domain_uuid = $settings->domain_uuid(); + $domain_name = $database->select("SELECT domain_name from v_domains where domain_uuid = :domain_uuid", ['domain_uuid' => $domain_uuid], 'column'); //get the recording directory $recordings_dir = $settings->get('switch', 'recordings', '/var/lib/freeswitch/recordings') . DIRECTORY_SEPARATOR . $domain_name; - //build initial sql - $sql = "SELECT recording_uuid, recording_filename FROM v_recordings"; - //add domain_uuid to sql if needed - if (!empty($domain_name) && is_uuid($domain_name)) { + //build initial sql that ignores the domain_uuid + $sql = "SELECT recording_uuid, recording_filename, recording_base64 IS NOT NULL AS has_base64_recording FROM v_recordings"; + //add domain_uuid to sql when available + if (!empty($domain_name) && is_uuid($domain_uuid)) { $sql .= " where domain_uuid = :domain_uuid"; - $parameters['domain_uuid'] = $domain_name; + $parameters['domain_uuid'] = $domain_uuid; } //add limit to sql if needed if (!empty($limit)) { @@ -482,7 +484,11 @@ if (!class_exists('phrases')) { if (!empty($rows)) { //set the path and filename for each of the uuids foreach($rows as $row) { - $recordings[$row['recording_uuid']] = $recordings_dir . DIRECTORY_SEPARATOR . $row['recording_filename']; + if ($row['has_base64_recording']) { + $recordings[$row['recording_uuid']] = '${lua streamfile.lua ' . basename($row['recording_filename']) .'}'; + } else { + $recordings[$row['recording_uuid']] = $recordings_dir . DIRECTORY_SEPARATOR . $row['recording_filename']; + } } } //return recordings or empty array diff --git a/app/phrases/resources/javascript/phrase_edit.js b/app/phrases/resources/javascript/phrase_edit.js index da9de59f2e..6ffdf2f458 100644 --- a/app/phrases/resources/javascript/phrase_edit.js +++ b/app/phrases/resources/javascript/phrase_edit.js @@ -10,14 +10,14 @@ document.addEventListener("DOMContentLoaded", function () { // Add recordings grp_rec.label = 'Recordings'; for (let i = 0; i < window.phrase_recordings.length; i++) { - grp_rec.appendChild(new Option(' ' + window.phrase_recordings[i].recording_name, window.phrase_recordings[i].recording_uuid)); + grp_rec.appendChild(new Option(window.phrase_recordings[i].recording_name, window.phrase_recordings[i].recording_uuid)); } select.appendChild(grp_rec); // Add sounds grp_snd.label = 'Sounds'; for (let i = 0; i < window.phrase_sounds.length; i++) { - grp_snd.appendChild(new Option(' ' + window.phrase_sounds[i], i)); + grp_snd.appendChild(new Option(window.phrase_sounds[i], window.phrase_sounds[i])); } select.appendChild(grp_snd); @@ -27,9 +27,6 @@ document.addEventListener("DOMContentLoaded", function () { // add empty row add_row(); - // update order - update_order(); - // Initialize draggable rows add_draggable_rows(); }); @@ -52,7 +49,6 @@ function add_existing() { //recording select box const select_recording = select_list[1]; - select_recording.setAttribute('tag', window.phrase_details[i]['phrase_detail_uuid']); select_by_text(select_recording, window.phrase_details[i]['phrase_detail_display_name']); const input_fields = newRow.querySelectorAll('td input'); @@ -87,11 +83,6 @@ function select_by_text(selectElement, textToFind) { console.warn('Text not found in select options'); } -function update_id(element) { - index = element.index; - const hidden_input_field = document.getElementById('hidden_input_field[' + index +']'); -} - // Add draggable functionality to rows function add_draggable_rows() { const tableBody = document.getElementById('structure'); @@ -120,7 +111,6 @@ function add_draggable_rows() { tableBody.addEventListener('dragend', () => { draggedRow.classList.remove('dragging'); draggedRow = null; - update_order(); }); } @@ -154,6 +144,13 @@ function update_order() { }); } +function submit_phrase() { + //ensure order is updated before submitting form + update_order(); + //submit form + const form = document.getElementById('frm').submit(); +} + // Add a new row to the table function add_row() { const tbody = document.getElementById('structure');