Ring Group - Edit: Add playback of selected Greeting (Recordings and Sounds).
This commit is contained in:
parent
372db3cc50
commit
64ba5e268c
|
|
@ -610,40 +610,35 @@
|
|||
$document['title'] = $text['title-ring_group'];
|
||||
require_once "resources/header.php";
|
||||
|
||||
//option to change select to text
|
||||
if (if_group("superadmin")) {
|
||||
echo "<script>\n";
|
||||
echo "var Objs;\n";
|
||||
echo "\n";
|
||||
echo "function changeToInput(obj){\n";
|
||||
echo " tb=document.createElement('INPUT');\n";
|
||||
echo " tb.type='text';\n";
|
||||
echo " tb.name=obj.name;\n";
|
||||
echo " tb.setAttribute('class', 'formfld');\n";
|
||||
//echo " tb.setAttribute('style', 'width: 380px;');\n";
|
||||
echo " tb.value=obj.options[obj.selectedIndex].value;\n";
|
||||
echo " tbb=document.createElement('INPUT');\n";
|
||||
echo " tbb.setAttribute('class', 'btn');\n";
|
||||
echo " tbb.setAttribute('style', 'margin-left: 4px;');\n";
|
||||
echo " tbb.type='button';\n";
|
||||
echo " tbb.value=$('<div />').html('◁').text();\n";
|
||||
echo " tbb.objs=[obj,tb,tbb];\n";
|
||||
echo " tbb.onclick=function(){ Replace(this.objs); }\n";
|
||||
echo " obj.parentNode.insertBefore(tb,obj);\n";
|
||||
echo " obj.parentNode.insertBefore(tbb,obj);\n";
|
||||
echo " obj.parentNode.removeChild(obj);\n";
|
||||
echo "}\n";
|
||||
echo "\n";
|
||||
echo "function Replace(obj){\n";
|
||||
echo " obj[2].parentNode.insertBefore(obj[0],obj[2]);\n";
|
||||
echo " obj[0].parentNode.removeChild(obj[1]);\n";
|
||||
echo " obj[0].parentNode.removeChild(obj[2]);\n";
|
||||
echo "}\n";
|
||||
//show the content
|
||||
if (permission_exists('recording_play') || permission_exists('recording_download')) {
|
||||
echo "<script type='text/javascript' language='JavaScript'>\n";
|
||||
echo " function set_playable(id, greeting_selected, greeting_type) {\n";
|
||||
echo " file_ext = greeting_selected.split('.').pop();\n";
|
||||
echo " var audio_file_type = '';\n";
|
||||
echo " switch (file_ext) {\n";
|
||||
echo " case 'wav': audio_file_type = 'audio/wav'; break;\n";
|
||||
echo " case 'mp3': audio_file_type = 'audio/mpeg'; break;\n";
|
||||
echo " case 'ogg': audio_file_type = 'audio/ogg'; break;\n";
|
||||
echo " }\n";
|
||||
echo " if (audio_file_type != '' && (greeting_type == 'recordings' || greeting_type == 'sounds')) {\n";
|
||||
echo " if (greeting_type == 'recordings') {\n";
|
||||
echo " $('#recording_audio_' + id).attr('src', '../recordings/recordings.php?action=download&type=rec&filename=' + greeting_selected);\n";
|
||||
echo " }\n";
|
||||
echo " else if (greeting_type == 'sounds') {\n";
|
||||
echo " $('#recording_audio_' + id).attr('src', '../switch/sounds.php?action=download&filename=' + greeting_selected);\n";
|
||||
echo " }\n";
|
||||
echo " $('#recording_audio_' + id).attr('type', audio_file_type);\n";
|
||||
echo " $('#recording_button_' + id).show();\n";
|
||||
echo " }\n";
|
||||
echo " else {\n";
|
||||
echo " $('#recording_button_' + id).hide();\n";
|
||||
echo " $('#recording_audio_' + id).attr('src','').attr('type','');\n";
|
||||
echo " }\n";
|
||||
echo " }\n";
|
||||
echo "</script>\n";
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
//show the content
|
||||
echo "<form method='post' name='frm' id='frm'>\n";
|
||||
|
||||
echo "<div class='action_bar' id='action_bar'>\n";
|
||||
|
|
@ -703,33 +698,102 @@
|
|||
echo "</tr>\n";
|
||||
|
||||
echo "<tr>\n";
|
||||
echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
|
||||
echo "<td class='vncell' rowspan='2' valign='top' align='left' nowrap='nowrap'>\n";
|
||||
echo " ".$text['label-greeting']."\n";
|
||||
echo "</td>\n";
|
||||
echo "<td class='vtable playback_progress_bar_background' id='recording_progress_bar_greeting' style='display: none; border-bottom: none; padding-top: 0 !important; padding-bottom: 0 !important;' align='left'><span class='playback_progress_bar' id='recording_progress_greeting'></span></td>\n";
|
||||
echo "</tr>\n";
|
||||
echo "<tr>\n";
|
||||
echo "<td class='vtable' align='left'>\n";
|
||||
echo "<select name='ring_group_greeting' class='formfld' style='width: 200px;' ".((if_group("superadmin")) ? "onchange='changeToInput(this);'" : null).">\n";
|
||||
if (if_group("superadmin")) {
|
||||
$destination_id = "ring_group_greeting";
|
||||
$script = "<script>\n";
|
||||
$script .= "var objs;\n";
|
||||
$script .= "\n";
|
||||
$script .= "function changeToInput".$destination_id."(obj){\n";
|
||||
$script .= " tb=document.createElement('INPUT');\n";
|
||||
$script .= " tb.type='text';\n";
|
||||
$script .= " tb.name=obj.name;\n";
|
||||
$script .= " tb.className='formfld';\n";
|
||||
$script .= " tb.setAttribute('id', '".$destination_id."');\n";
|
||||
$script .= " tb.setAttribute('style', '".$select_style."');\n";
|
||||
if (!empty($on_change)) {
|
||||
$script .= " tb.setAttribute('onchange', \"".$on_change."\");\n";
|
||||
$script .= " tb.setAttribute('onkeyup', \"".$on_change."\");\n";
|
||||
}
|
||||
$script .= " tb.value=obj.options[obj.selectedIndex].value;\n";
|
||||
$script .= " document.getElementById('btn_select_to_input_".$destination_id."').style.display = 'none';\n";
|
||||
$script .= " tbb=document.createElement('INPUT');\n";
|
||||
$script .= " tbb.setAttribute('class', 'btn');\n";
|
||||
$script .= " tbb.setAttribute('style', 'margin-left: 4px;');\n";
|
||||
$script .= " tbb.type='button';\n";
|
||||
$script .= " tbb.value=$('<div />').html('◁').text();\n";
|
||||
$script .= " tbb.objs=[obj,tb,tbb];\n";
|
||||
$script .= " tbb.onclick=function(){ Replace".$destination_id."(this.objs); }\n";
|
||||
$script .= " obj.parentNode.insertBefore(tb,obj);\n";
|
||||
$script .= " obj.parentNode.insertBefore(tbb,obj);\n";
|
||||
$script .= " obj.parentNode.removeChild(obj);\n";
|
||||
$script .= " Replace".$destination_id."(this.objs);\n";
|
||||
$script .= "}\n";
|
||||
$script .= "\n";
|
||||
$script .= "function Replace".$destination_id."(obj){\n";
|
||||
$script .= " obj[2].parentNode.insertBefore(obj[0],obj[2]);\n";
|
||||
$script .= " obj[0].parentNode.removeChild(obj[1]);\n";
|
||||
$script .= " obj[0].parentNode.removeChild(obj[2]);\n";
|
||||
$script .= " document.getElementById('btn_select_to_input_".$destination_id."').style.display = 'inline';\n";
|
||||
if (!empty($on_change)) {
|
||||
$script .= " ".$on_change.";\n";
|
||||
}
|
||||
$script .= "}\n";
|
||||
$script .= "</script>\n";
|
||||
$script .= "\n";
|
||||
echo $script;
|
||||
}
|
||||
echo "<select name='ring_group_greeting' id='ring_group_greeting' class='formfld' style='width: 200px;' ".(permission_exists('recording_play') || permission_exists('recording_download') ? "onchange=\"recording_reset('greeting'); set_playable('greeting', this.value, this.options[this.selectedIndex].parentNode.getAttribute('data-type'));\"" : null).">\n";
|
||||
echo " <option value=''></option>\n";
|
||||
foreach($sounds as $key => $value) {
|
||||
echo "<optgroup label=".$text['label-'.$key].">\n";
|
||||
$selected = false;
|
||||
$found = false;
|
||||
foreach ($sounds as $key => $value) {
|
||||
echo "<optgroup label=".$text['label-'.$key]." data-type='".$key."'>\n";
|
||||
foreach ($value as $row) {
|
||||
if (!empty($ring_group_greeting) && $ring_group_greeting == $row["value"]) {
|
||||
$selected = true;
|
||||
echo " <option value='".escape($row["value"])."' selected='selected'>".escape($row["name"])."</option>\n";
|
||||
$selected = "selected='selected'";
|
||||
if ($key == 'recordings') {
|
||||
$playable_greeting = '../recordings/recordings.php?action=download&type=rec&filename='.$row["value"];
|
||||
}
|
||||
else if ($key == 'sounds') {
|
||||
$playable_greeting = '../switch/sounds.php?action=download&filename='.$row["value"];
|
||||
}
|
||||
else {
|
||||
$playable_greeting = false;
|
||||
}
|
||||
$found = true;
|
||||
}
|
||||
else {
|
||||
echo " <option value='".escape($row["value"])."'>".escape($row["name"])."</option>\n";
|
||||
unset($selected);
|
||||
}
|
||||
echo " <option value='".escape($row["value"])."' ".$selected.">".escape($row["name"])."</option>\n";
|
||||
}
|
||||
echo "</optgroup>\n";
|
||||
}
|
||||
if (if_group("superadmin")) {
|
||||
if (!$selected && !empty($ring_group_greeting)) {
|
||||
echo " <option value='".escape($ring_group_greeting)."' selected='selected'>".escape($ring_group_greeting)."</option>\n";
|
||||
}
|
||||
unset($selected);
|
||||
if (if_group("superadmin") && !empty($ring_group_greeting) && !$found) {
|
||||
echo " <option value='".escape($ring_group_greeting)."' selected='selected'>".escape($ring_group_greeting)."</option>\n";
|
||||
}
|
||||
unset($selected);
|
||||
echo " </select>\n";
|
||||
if (if_group("superadmin")) {
|
||||
echo "<input type='button' id='btn_select_to_input_".escape($destination_id)."' class='btn' name='' alt='back' onclick='changeToInput".escape($destination_id)."(document.getElementById(\"".escape($destination_id)."\")); this.style.visibility=\"hidden\";' value='◁'>";
|
||||
unset($destination_id);
|
||||
}
|
||||
if ((permission_exists('recording_play') || permission_exists('recording_download')) && !empty($playable_greeting)) {
|
||||
switch (pathinfo($playable_greeting, PATHINFO_EXTENSION)) {
|
||||
case 'wav' : $audio_file_type = 'audio/wav'; break;
|
||||
case 'mp3' : $audio_file_type = 'audio/mpeg'; break;
|
||||
case 'ogg' : $audio_file_type = 'audio/ogg'; break;
|
||||
}
|
||||
}
|
||||
echo "<audio id='recording_audio_greeting' style='display: none;' preload='none' ontimeupdate=\"update_progress('greeting')\" onended=\"recording_reset('greeting');\" src='".($playable_greeting ?? '')."' type='".($audio_file_type ?? '')."'></audio>";
|
||||
echo button::create(['type'=>'button','title'=>$text['label-play'].' / '.$text['label-pause'],'icon'=>$_SESSION['theme']['button_icon_play'],'id'=>'recording_button_greeting','style'=>'display: '.(!empty($audio_file_type) ? 'inline' : 'none'),'onclick'=>"recording_play('greeting')"]);
|
||||
unset($playable_greeting, $audio_file_type);
|
||||
echo "<br />\n";
|
||||
echo $text['description-greeting']."\n";
|
||||
echo "</td>\n";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,191 @@
|
|||
<?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) 2023
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mark J Crane <markjcrane@fusionpbx.com>
|
||||
*/
|
||||
|
||||
//set the max php execution time
|
||||
ini_set('max_execution_time', 7200);
|
||||
|
||||
//includes files
|
||||
require_once dirname(__DIR__, 2) . "/resources/require.php";
|
||||
require_once "resources/check_auth.php";
|
||||
|
||||
//check the permission
|
||||
if (permission_exists('recording_play') || permission_exists('recording_download')) {
|
||||
//access granted
|
||||
}
|
||||
else {
|
||||
echo "access denied";
|
||||
exit;
|
||||
}
|
||||
|
||||
//set additional variables
|
||||
$action = $_REQUEST["action"] ?? '';
|
||||
|
||||
//download the sound
|
||||
if ($action == "download") {
|
||||
|
||||
//get first installed language (like en/us/callie)
|
||||
$language_paths = glob($_SESSION["switch"]['sounds']['dir']."/*/*/*");
|
||||
foreach ($language_paths as $key => $path) {
|
||||
$path = str_replace($_SESSION["switch"]['sounds']['dir'].'/', "", $path);
|
||||
$path_array = explode('/', $path);
|
||||
if (count($path_array) <> 3 || strlen($path_array[0]) <> 2 || strlen($path_array[1]) <> 2) {
|
||||
unset($language_paths[$key]);
|
||||
}
|
||||
$language_paths[$key] = str_replace($_SESSION["switch"]['sounds']['dir']."/","",$language_paths[$key] ?? '');
|
||||
if (empty($language_paths[$key])) {
|
||||
unset($language_paths[$key]);
|
||||
}
|
||||
}
|
||||
$language_path = $language_paths[0];
|
||||
|
||||
//determine the path for sound file
|
||||
$filename_parts = explode('/', str_replace('..', '', $_GET['filename']));
|
||||
if (!is_array($filename_parts) || @sizeof($filename_parts) != 2) { exit; }
|
||||
$path = $_SESSION['switch']['sounds']['dir'].'/'.$language_path.'/'.$filename_parts[0].'/8000/';
|
||||
|
||||
//set sound filename
|
||||
$sound_filename = $filename_parts[1];
|
||||
|
||||
//build full path
|
||||
$full_sound_path = $path.$sound_filename;
|
||||
|
||||
//send the headers and then the data stream
|
||||
if (file_exists($full_sound_path)) {
|
||||
|
||||
$fd = fopen($full_sound_path, "rb");
|
||||
switch (pathinfo($sound_filename, PATHINFO_EXTENSION)) {
|
||||
case "wav" : header("Content-Type: audio/x-wav"); break;
|
||||
case "mp3" : header("Content-Type: audio/mpeg"); break;
|
||||
case "ogg" : header("Content-Type: audio/ogg"); break;
|
||||
}
|
||||
header('Content-Disposition: attachment; filename="'.$filename_parts[0].'_'.$filename_parts[1].'"');
|
||||
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
|
||||
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
|
||||
|
||||
ob_clean();
|
||||
|
||||
//content-range
|
||||
if (isset($_SERVER['HTTP_RANGE']) && (empty($_GET['t']) || $_GET['t'] != "bin")) {
|
||||
range_download($full_sound_path);
|
||||
}
|
||||
|
||||
fpassthru($fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//define the download function (helps safari play audio sources)
|
||||
function range_download($file) {
|
||||
$fp = @fopen($file, 'rb');
|
||||
|
||||
$size = filesize($file); // File size
|
||||
$length = $size; // Content length
|
||||
$start = 0; // Start byte
|
||||
$end = $size - 1; // End byte
|
||||
// Now that we've gotten so far without errors we send the accept range header
|
||||
/* At the moment we only support single ranges.
|
||||
* Multiple ranges requires some more work to ensure it works correctly
|
||||
* and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
|
||||
*
|
||||
* Multirange support annouces itself with:
|
||||
* header('Accept-Ranges: bytes');
|
||||
*
|
||||
* Multirange content must be sent with multipart/byteranges mediatype,
|
||||
* (mediatype = mimetype)
|
||||
* as well as a boundry header to indicate the various chunks of data.
|
||||
*/
|
||||
header("Accept-Ranges: 0-$length");
|
||||
// header('Accept-Ranges: bytes');
|
||||
// multipart/byteranges
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
|
||||
if (isset($_SERVER['HTTP_RANGE'])) {
|
||||
|
||||
$c_start = $start;
|
||||
$c_end = $end;
|
||||
// Extract the range string
|
||||
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
|
||||
// Make sure the client hasn't sent us a multibyte range
|
||||
if (strpos($range, ',') !== false) {
|
||||
// (?) Shoud this be issued here, or should the first
|
||||
// range be used? Or should the header be ignored and
|
||||
// we output the whole content?
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header("Content-Range: bytes $start-$end/$size");
|
||||
// (?) Echo some info to the client?
|
||||
exit;
|
||||
}
|
||||
// If the range starts with an '-' we start from the beginning
|
||||
// If not, we forward the file pointer
|
||||
// And make sure to get the end byte if spesified
|
||||
if ($range == '-') {
|
||||
// The n-number of the last bytes is requested
|
||||
$c_start = $size - substr($range, 1);
|
||||
}
|
||||
else {
|
||||
$range = explode('-', $range);
|
||||
$c_start = $range[0];
|
||||
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
|
||||
}
|
||||
/* Check the range and make sure it's treated according to the specs.
|
||||
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
*/
|
||||
// End bytes can not be larger than $end.
|
||||
$c_end = ($c_end > $end) ? $end : $c_end;
|
||||
// Validate the requested range and return an error if it's not correct.
|
||||
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
|
||||
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header("Content-Range: bytes $start-$end/$size");
|
||||
// (?) Echo some info to the client?
|
||||
exit;
|
||||
}
|
||||
$start = $c_start;
|
||||
$end = $c_end;
|
||||
$length = $end - $start + 1; // Calculate new content length
|
||||
fseek($fp, $start);
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
}
|
||||
// Notify the client the byte range we'll be outputting
|
||||
header("Content-Range: bytes $start-$end/$size");
|
||||
header("Content-Length: $length");
|
||||
|
||||
// Start buffered download
|
||||
$buffer = 1024 * 8;
|
||||
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
|
||||
if ($p + $buffer > $end) {
|
||||
// In case we're only outputtin a chunk, make sure we don't
|
||||
// read past the length
|
||||
$buffer = $end - $p + 1;
|
||||
}
|
||||
set_time_limit(0); // Reset time limit for big files
|
||||
echo fread($fp, $buffer);
|
||||
flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
?>
|
||||
Loading…
Reference in New Issue