use await and async to fetch phrases

This commit is contained in:
Tim Fry 2024-12-13 16:13:04 -04:00
parent 90bc61d2d0
commit 847dbb23b5
5 changed files with 343 additions and 21 deletions

30
app/phrases/phrase.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/*
* FusionPBX
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FusionPBX
*
* The Initial Developer of the Original Code is
* Mark J Crane <markjcrane@fusionpbx.com>
* Portions created by the Initial Developer are Copyright (C) 2008-2024
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark J Crane <markjcrane@fusionpbx.com>
* Tim Fry <tim@fusionpbx.com>
*/
echo "<!doctype html>";
echo "<html><head></head><body><script src='resources/javascript/phrase_fetch.js'></script></body></html>";

View File

@ -414,10 +414,10 @@ if (count($_POST) > 0) {
}
}
//send the phrase details to the browser as a global scope json array object
echo "window.phrase_details = " . json_encode($phrase_details, true) . ";\n";
//echo "window.phrase_details = " . json_encode($phrase_details, true) . ";\n";
} else {
//send an empty array to the browser as a global scope json array object
echo "window.phrase_details = [];\n";
//echo "window.phrase_details = [];\n";
}
//recording files

View File

@ -0,0 +1,199 @@
<?php
/*
* FusionPBX
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FusionPBX
*
* The Initial Developer of the Original Code is
* Mark J Crane <markjcrane@fusionpbx.com>
* Portions created by the Initial Developer are Copyright (C) 2008-2024
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark J Crane <markjcrane@fusionpbx.com>
* Tim Fry <tim@fusionpbx.com>
*/
// require the class loader and global functions
//require dirname(__DIR__, 2) . '/resources/classes/auto_loader.php'; new auto_loader();
//require dirname(__DIR__, 2) . '/resources/functions.php';
require_once dirname(__DIR__, 2) . '/resources/require.php';
// Disable output buffering and compression
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', 'off');
ini_set('implicit_flush', 1);
ob_implicit_flush(1);
// Set headers to ensure immediate response
header('Content-Type: text/plain');
header('Cache-Control: no-cache');
header('Content-Encoding: none');
function fetch_recordings(database $database): array {
global $domain_uuid;
// guard against corrupt data
if (empty($domain_uuid) || !is_uuid($domain_uuid)) {
throw new Exception('Domain is invalid');
}
// always return an array
$return_value = [];
$sql = "select recording_uuid, recording_name, recording_filename, domain_uuid from v_recordings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "order by recording_name asc ";
$parameters['domain_uuid'] = $domain_uuid;
$recordings = $database->select($sql, $parameters, 'all');
if (!empty($recordings)) {
$return_value = $recordings;
}
return $return_value;
}
function fetch_sound_files(settings $settings) {
$return_value = [];
//get the switch sound files
$file = new file($settings);
$sound_files = $file->sounds();
//try finding display_name in the switch sound files
if (!empty($sound_files)) {
$return_value = $sound_files;
}
return $return_value;
}
function fetch_phrase_details(settings $settings, string $phrase_uuid): array {
global $domain_uuid;
// guard against corrupt data
if (empty($domain_uuid) || !is_uuid($domain_uuid)) {
throw new Exception('Domain is invalid');
}
if (empty($phrase_uuid) || !is_uuid($phrase_uuid)) {
throw new Exception('Phrase UUID is invalid');
}
$database = $settings->database();
// set the return value to be an empty array
$return_value = [];
// get the phrase details
if (!empty($phrase_uuid)) {
$sql = "select * from v_phrase_details ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and phrase_uuid = :phrase_uuid ";
$sql .= "order by phrase_detail_order asc ";
$parameters['domain_uuid'] = $domain_uuid;
$parameters['phrase_uuid'] = $phrase_uuid;
$phrase_details = $database->select($sql, $parameters, 'all');
}
//existing details
if (!empty($phrase_details)) {
$recordings = fetch_recordings($database);
$sound_files = fetch_sound_files($settings);
//update the array to include the recording name for display in select box
foreach ($phrase_details as &$row) {
$row['display_name'] = '';
$file = basename($row['phrase_detail_data']);
//get the display_name from recording name based on the file matched
foreach ($recordings as $key => $recordings_row) {
//match on filename first and then domain_uuid
if ($recordings_row['recording_filename'] === $file && $recordings_row['domain_uuid'] === $row['domain_uuid']) {
$row['display_name'] = $recordings[$key]['recording_name'];
break;
}
}
//check if display_name was not found in the recording names
if (strlen($row['display_name']) === 0) {
//try finding display_name in the switch sound files
if (!empty($sound_files)) {
//use optimized php function with strict comparison
$i = array_search($row['phrase_detail_data'], $sound_files, true);
//if found in the switch sound files
if ($i !== false) {
//set the display_name to the switch sound file name
$row['display_name'] = $sound_files[$i];
}
}
}
}
$return_value = $phrase_details;
}
return $return_value;
}
function fetch_domain_uuid(database $database): string {
$domain = $_SERVER['HTTP_HOST'];
$domain_uuid = '';
$sql = 'select domain_uuid from v_domains where domain_name = :domain';
$parameters = [];
$parameters['domain'] = $domain;
$result = $database->select($sql, $parameters, 'column');
if (!empty($result)) {
$domain_uuid = $result;
}
return $domain_uuid;
}
function send_message(string $json_data) {
echo $json_data . "\n";
ob_flush();
flush();
}
$config = config::load();
$database = database::new(['config' => $config]);
$domain_uuid = fetch_domain_uuid($database);
$settings = new settings(['database' => $database, 'domain_uuid' => $domain_uuid]);
// Set default response
$response = ['code' => 200, 'message' => ''];
// Check if the request method is POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$message = '';
// Get the raw POST data
$input = file_get_contents('php://input');
// Parse JSON data
$data = json_decode($input, true); // Decode JSON as associative array
if (isset($data['request'])) {
try {
//check the data source requested
switch ($data['request']) {
case 'sound_files':
$message = fetch_sound_files($settings);
break;
case 'recordings':
$message = fetch_recordings($database);
break;
case 'phrase_details':
$phrase_uuid = $data['data'];
$message = fetch_phrase_details($settings, $phrase_uuid);
break;
}
} catch (Exception $e) {
$response['code'] = 500;
$message = $e->getMessage();
}
}
//save the message
$response['message'] = $message;
//send the response
send_message(json_encode($response));
exit();
}
exit();

View File

@ -1,4 +1,4 @@
document.addEventListener("DOMContentLoaded", function () {
document.addEventListener("DOMContentLoaded", async function () {
// Initialize the select options
const select = document.getElementById('phrase_detail_data_empty');
const grp_rec = document.createElement('optgroup');
@ -9,17 +9,27 @@ document.addEventListener("DOMContentLoaded", function () {
// Add recordings
grp_rec.label = window.phrase_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));
try {
const phrase_recordings = await fetch_data({request: 'recordings', data: ''});
for (let i = 0; i < phrase_recordings.length; i++) {
grp_rec.appendChild(new Option(phrase_recordings[i].recording_name, phrase_recordings[i].recording_uuid));
}
select.appendChild(grp_rec);
} catch (error) {
console.error("Error fetching recordings:", error);
}
select.appendChild(grp_rec);
// Add sounds
grp_snd.label = window.phrase_label_sounds;
for (let i = 0; i < window.phrase_sounds.length; i++) {
grp_snd.appendChild(new Option(window.phrase_sounds[i], window.phrase_sounds[i]));
try {
const phrase_sounds = await fetch_data({request: 'sound_files', data: ''});
for (let i = 0; i < phrase_sounds.length; i++) {
grp_snd.appendChild(new Option(phrase_sounds[i], phrase_sounds[i]));
}
select.appendChild(grp_snd);
} catch (error) {
console.error("Error fetching recordings:", error);
}
select.appendChild(grp_snd);
// add the existing data
add_existing();
@ -31,34 +41,65 @@ document.addEventListener("DOMContentLoaded", function () {
add_draggable_rows();
});
async function fetch_data(command) {
try {
const response = await fetch('phrase_responder.php', {
method: 'POST', // or 'GET' depending on your requirement
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(command) // If sending data with POST
});
const data = await response.json();
return data.message;
} catch (error) {
console.error('Error:', error);
}
}
//
// Inserts all existing records before the empty one
//
function add_existing() {
async function add_existing() {
//get the body structure
const tbody = document.getElementById('structure');
for (let index=0; index < window.phrase_details.length; index++) {
//get the phrase id
const urlParams = new URLSearchParams(window.location.search);
const phrase_uuid = urlParams.get('id');
//fetch the phrase details from the database
const phrase_details = await fetch_data({request: 'phrase_details', data: phrase_uuid});
//display the phrase details
for (let index=0; index < phrase_details.length; index++) {
//add an empty row
add_row();
//get the action select box
const select_action = document.getElementById('phrase_detail_function[' + index + ']');
select_by_value(select_action, window.phrase_details[index].phrase_detail_function);
//set the chosen option
select_by_value(select_action, phrase_details[index].phrase_detail_function);
//get the data select box
const select_data = document.getElementById('phrase_detail_data[' + index + ']');
select_by_text(select_data, window.phrase_details[index]['display_name']);
//set the chosen option
select_by_text(select_data, phrase_details[index]['display_name']);
const uuid_field = document.getElementById('phrase_detail_uuid[' +index+']');
uuid_field.value = window.phrase_details[index]['phrase_detail_uuid'];
uuid_field.value = phrase_details[index]['phrase_detail_uuid'];
//set the slider value
const slider = document.getElementById('slider['+index+']');
const sleep = document.getElementById('sleep['+index+']');
const phrase_detail_text = document.getElementById('phrase_detail_text['+index+']');
//update the sleep data
if (window.phrase_details[index].phrase_detail_function === 'pause') {
sleep.value = window.phrase_details[index].phrase_detail_data;
slider.value = window.phrase_details[index].phrase_detail_data;
if (phrase_details[index].phrase_detail_function === 'pause') {
sleep.value = phrase_details[index].phrase_detail_data;
slider.value = phrase_details[index].phrase_detail_data;
}
//update the execute text
if (window.phrase_details[index].phrase_detail_function === 'execute') {
phrase_detail_text.value = window.phrase_details[index].phrase_detail_data;
if (phrase_details[index].phrase_detail_function === 'execute') {
phrase_detail_text.value = phrase_details[index].phrase_detail_data;
}
// Manually trigger the change event to select the proper display
if (window.phrase_details[index].phrase_detail_function !== 'play-file') {
if (phrase_details[index].phrase_detail_function !== 'play-file') {
const changeEvent = new Event('change', { bubbles: true });
select_action.dispatchEvent(changeEvent);
}

View File

@ -0,0 +1,52 @@
/*
* FusionPBX
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FusionPBX
*
* The Initial Developer of the Original Code is
* Mark J Crane <markjcrane@fusionpbx.com>
* Portions created by the Initial Developer are Copyright (C) 2008-2024
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark J Crane <markjcrane@fusionpbx.com>
* Tim Fry <tim@fusionpbx.com>
*/
async function fetchData() {
try {
const response = await fetch('phrase_responder.php', {
method: 'POST', // or 'GET' depending on your requirement
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ request: 'phrase_details', phrase_uuid: '86141ace-b218-4f07-b412-fe02d4fdde17' }) // If sending data with POST
});
const data = await response.text();
const json = JSON.parse(data);
const body = document.body;
const input = document.createElement('input');
input.type = 'text';
input.value = json.message;
body.appendChild(input);
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
fetchData();