Portions created by the Initial Developer are Copyright (C) 2008-2024 the Initial Developer. All Rights Reserved. Contributor(s): Mark J Crane */ //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 permissions if (!permission_exists('voicemail_greeting_view') || (!permission_exists('voicemail_view') && !extension_assigned($_REQUEST["id"]))) { echo "access denied"; return; } //add multi-lingual support $language = new text; $text = $language->get(); //check for speech app $speech_enabled = $settings->get('speech', 'enabled'); //set the defaults $sql_file_size = ''; //get the http get values and set them as php variables $voicemail_id = $_REQUEST["id"] ?? ''; $order_by = $_GET["order_by"] ?? ''; $order = $_GET["order"] ?? ''; //set the back button url $_SESSION['back'][$_SERVER['PHP_SELF']] = !empty($_GET['back']) ? urldecode($_GET['back']) : $_SESSION['back'][$_SERVER['PHP_SELF']]; //define order by default if ($order_by == '') { $order_by = "greeting_id"; $order = "asc"; } //used (above) to search the array to determine if an extension is assigned to the user function extension_assigned($number) { foreach ($_SESSION['user']['extension'] as $row) { if ((is_numeric($row['number_alias']) && $row['number_alias'] == $number) || $row['user'] == $number) { return true; } } return false; } //get currently selected greeting $sql = "select greeting_id from v_voicemails "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_id = :voicemail_id "; $parameters = []; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; $parameters['voicemail_id'] = $voicemail_id; $selected_greeting_id = $database->select($sql, $parameters, 'column'); unset($sql, $parameters); //define greeting directory $greeting_dir = $_SESSION['switch']['voicemail']['dir'].'/default/'.$_SESSION['domains'][$domain_uuid]['domain_name'].'/'.$voicemail_id; //download the greeting if (!empty($_GET['a']) && $_GET['a'] == "download" && (permission_exists('voicemail_greeting_play') || permission_exists('voicemail_greeting_download'))) { if ($_GET['type'] == "rec") { //get the id $voicemail_greeting_uuid = $_GET['uuid']; //get voicemail greeting details from db $sql = "select greeting_filename, greeting_base64, greeting_id "; $sql .= "from v_voicemail_greetings "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_greeting_uuid = :voicemail_greeting_uuid "; $parameters = []; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; $parameters['voicemail_greeting_uuid'] = $voicemail_greeting_uuid; $row = $database->select($sql, $parameters, 'row'); if (is_array($row) && @sizeof($row) != 0) { $greeting_filename = $row['greeting_filename']; $greeting_id = $row['greeting_id']; if (!empty($_SESSION['voicemail']['storage_type']['text']) && $_SESSION['voicemail']['storage_type']['text'] == 'base64' && $row['greeting_base64'] != '') { $greeting_decoded = base64_decode($row['greeting_base64']); file_put_contents($greeting_dir.'/'.$greeting_filename, $greeting_decoded); } } unset($sql, $row, $greeting_decoded); if (file_exists($greeting_dir.'/'.$greeting_filename)) { $fd = fopen($greeting_dir.'/'.$greeting_filename, "rb"); if (!empty($_GET['t']) && $_GET['t'] == "bin") { header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download"); header("Content-Description: File Transfer"); } else { $file_ext = pathinfo($greeting_filename, PATHINFO_EXTENSION); switch ($file_ext) { 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="'.$greeting_filename.'"'); header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past if (!empty($_GET['t']) && $_GET['t'] == "bin") { header("Content-Length: ".filesize($greeting_dir.'/'.$greeting_filename)); } ob_clean(); //content-range if (isset($_SERVER['HTTP_RANGE']) && (empty($_GET['t']) || $_GET['t'] != "bin")) { range_download($greeting_dir.'/'.$greeting_filename); } fpassthru($fd); } //if base64, remove temp greeting file (if not currently selected greeting) if (!empty($_SESSION['voicemail']['storage_type']['text']) && $_SESSION['voicemail']['storage_type']['text'] == 'base64' && $row['greeting_base64'] != '') { if ($greeting_id != $selected_greeting_id) { @unlink($greeting_dir.'/'.$greeting_filename); } } } exit; } //upload the greeting if (!empty($_POST['a']) && $_POST['a'] == "upload" && permission_exists('voicemail_greeting_upload') && $_POST['type'] == 'rec' && is_uploaded_file($_FILES['file']['tmp_name'])) { //validate the token $token = new token; if (!$token->validate($_SERVER['PHP_SELF'])) { message::add($text['message-invalid_token'],'negative'); header('Location: voicemail_greetings.php?id='.urlencode($voicemail_id)); exit; } //get the file extension $file_ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION); $file_name = $_FILES['file']['name']; //check file extension if ($file_ext == 'wav' || $file_ext == 'mp3' || $file_ext == 'ogg') { //get the next greeting id starting at 1 $greeting_id = count(glob($greeting_dir . '/greeting_*.*')) + 1; //set the greeting file name $greeting_file_name = "greeting_{$greeting_id}.{$file_ext}"; //move the uploaded greeting if (!empty($greeting_dir) && !file_exists($greeting_dir)) { mkdir($greeting_dir, 0770, false); } move_uploaded_file($_FILES['file']['tmp_name'], $greeting_dir.'/'.$greeting_file_name); //set newly uploaded greeting as active greeting for voicemail box $sql = "update v_voicemails "; $sql .= "set greeting_id = :greeting_id "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_id = :voicemail_id "; $parameters = []; $parameters['greeting_id'] = $greeting_id; $parameters['domain_uuid'] = $domain_uuid; $parameters['voicemail_id'] = $voicemail_id; $database->execute($sql, $parameters); unset($sql, $parameters); //build insert array $x = 0; $array['voicemail_greetings'][$x]['voicemail_greeting_uuid'] = uuid(); $array['voicemail_greetings'][$x]['domain_uuid'] = $domain_uuid; $array['voicemail_greetings'][$x]['voicemail_id'] = $voicemail_id; $array['voicemail_greetings'][$x]['greeting_id'] = $greeting_id; $array['voicemail_greetings'][$x]['greeting_name'] = $text['label-greeting'].' '.$greeting_id; $array['voicemail_greetings'][$x]['greeting_filename'] = $greeting_file_name; $array['voicemail_greetings'][$x]['greeting_description'] = ''; if (!empty($_SESSION['voicemail']['storage_type']['text']) && $_SESSION['voicemail']['storage_type']['text'] == 'base64') { $array['voicemail_greetings'][$x]['greeting_base64'] = base64_encode(file_get_contents($greeting_dir.'/'.$file_name)); } //save the array if (is_array($array) && @sizeof($array) != 0) { //grant temporary permissions $p = permissions::new(); $p->add('voicemail_greeting_add', 'temp'); $p->add('voicemail_greeting_edit', 'temp'); //execute inserts/updates $database->app_name = 'voicemail_greetings'; $database->app_uuid = 'e4b4fbee-9e4d-8e46-3810-91ba663db0c2'; $database->save($array); unset($array); //revoke temporary permissions $p->delete('voicemail_greeting_add', 'temp'); $p->delete('voicemail_greeting_edit', 'temp'); } else { echo __line__; } //set message message::add($text['message-uploaded'].": ".$_FILES['file']['name']); } //set the file name to be inserted as the greeting description $greeting_description = base64_encode($_FILES['file']['name']); header("Location: voicemail_greetings.php?id=".urlencode($voicemail_id)."&order_by=".urlencode($order_by)."&order=".urlencode($order)."&gd=".$greeting_description); exit; } //check the permission if (permission_exists('voicemail_greeting_view')) { //access granted } else { echo "access denied"; exit; } //set the greeting if (!empty($_REQUEST['action']) && $_REQUEST['action'] == "set") { //save the greeting_id to a variable $greeting_id = $_REQUEST['greeting_id']; //set the greeting_id $sql = "update v_voicemails "; $sql .= "set greeting_id = :greeting_id "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_id = :voicemail_id "; $parameters = []; $parameters['greeting_id'] = $greeting_id; $parameters['domain_uuid'] = $domain_uuid; $parameters['voicemail_id'] = $voicemail_id; $database->execute($sql, $parameters); unset($sql, $parameters); //set message message::add($text['message-greeting_selected']); //redirect header("Location: voicemail_greetings.php?id=".$voicemail_id."&order_by=".$order_by."&order=".$order); exit; } //get the http post data if (!empty($_POST['voicemail_greetings'])) { $action = $_POST['action']; $voicemail_id = $_POST['voicemail_id']; $voicemail_greetings = $_POST['voicemail_greetings']; } //process the http post data by action if (!empty($action) && !empty($voicemail_greetings)) { switch ($action) { case 'delete': if (permission_exists('voicemail_greeting_delete')) { $obj = new voicemail_greetings; $obj->voicemail_id = $voicemail_id; $obj->delete($voicemail_greetings); } break; } header('Location: voicemail_greetings.php?id='.urlencode($voicemail_id).'&back='.urlencode(PROJECT_PATH.'/app/voicemails/voicemails.php')); exit; } //get the greetings list if (!empty($_SESSION['voicemail']['storage_type']['text']) && $_SESSION['voicemail']['storage_type']['text'] == 'base64') { switch ($db_type) { case 'pgsql': $sql_file_size = ", length(decode(greeting_base64,'base64')) as greeting_size "; break; case 'mysql': $sql_file_size = ", length(from_base64(greeting_base64)) as greeting_size "; break; } } $sql = "select * ".$sql_file_size." from v_voicemail_greetings "; $sql .= "where domain_uuid = :domain_uuid "; $sql .= "and voicemail_id = :voicemail_id "; $sql .= order_by($order_by, $order); $parameters = []; $parameters['domain_uuid'] = $domain_uuid; $parameters['voicemail_id'] = $voicemail_id; $greetings = $database->select($sql, $parameters, 'all'); $num_rows = is_array($greetings) ? @sizeof($greetings) : 0; unset($sql, $parameters); //create token $object = new token; $token = $object->create($_SERVER['PHP_SELF']); //include the header $document['title'] = $text['title']; require_once "resources/header.php"; //file type check script echo ""; //show the content echo "
\n"; echo "
".$text['title']."
".number_format($num_rows)."
\n"; echo "
\n"; echo button::create(['type'=>'button','label'=>$text['button-back'],'icon'=>$settings->get('theme', 'button_icon_back'),'id'=>'btn_back','link'=>$_SESSION['back'][$_SERVER['PHP_SELF']]]); $margin_left = false; if (permission_exists('voicemail_greeting_add') && is_array($greetings) && @sizeof($greetings) < 9 && $speech_enabled == 'true') { echo button::create(['type'=>'button','label'=>$text['button-add'],'icon'=>$settings->get('theme', 'button_icon_add'),'id'=>'btn_add','style'=>'margin-left: 15px;','link'=>'voicemail_greeting_edit.php?voicemail_id='.urlencode($voicemail_id)]); $margin_left = true; } if (permission_exists('voicemail_greeting_upload') && is_array($greetings) && @sizeof($greetings) < 9) { echo "
\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo button::create(['type'=>'button','label'=>$text['button-upload'],'icon'=>$settings->get('theme', 'button_icon_add'),'id'=>'btn_upload','style'=>(!$margin_left ? 'margin-left: 15px;' : null),'onclick'=>"$(this).fadeOut(250, function(){ $('span#form_upload').fadeIn(250); document.getElementById('ulfile').click(); });"]); echo "\n"; echo "
"; $margin_left = true; } if (permission_exists('voicemail_greeting_delete') && $greetings) { echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$settings->get('theme', 'button_icon_delete'),'id'=>'btn_delete','name'=>'btn_delete','style'=>'display: none; '.(!$margin_left ? 'margin-left: 15px;' : null),'onclick'=>"modal_open('modal-delete','btn_delete');"]); $margin_left = true; } echo "
\n"; echo "
\n"; echo "
\n"; if (permission_exists('voicemail_greeting_delete') && $greetings) { echo modal::create(['id'=>'modal-delete','type'=>'delete','actions'=>button::create(['type'=>'button','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_delete','style'=>'float: right; margin-left: 15px;','collapse'=>'never','onclick'=>"modal_close(); list_action_set('delete'); list_form_submit('form_list');"])]); } echo $text['description']." ".escape($voicemail_id)."\n"; echo "

\n"; echo "
\n"; echo "\n"; echo "\n"; echo "
\n"; echo "\n"; echo "\n"; $col_count = 0; if (permission_exists('voicemail_greeting_delete')) { echo " \n"; $col_count++; } echo "\n"; $col_count++; echo th_order_by('greeting_id', $text['label-number'], $order_by, $order, null, "class='center shrink'", "id=".urlencode($voicemail_id)); $col_count++; echo th_order_by('greeting_name', $text['label-name'], $order_by, $order, null, null, "id=".urlencode($voicemail_id)); $col_count++; if (empty($_SESSION['voicemail']['storage_type']['text']) || $_SESSION['voicemail']['storage_type']['text'] != 'base64') { echo th_order_by('greeting_filename', $text['label-filename'], $order_by, $order, null, "class='hide-sm-dn'", "id=".urlencode($voicemail_id)); $col_count++; } if (permission_exists('voicemail_greeting_play') || permission_exists('voicemail_greeting_download')) { echo "\n"; $col_count++; } echo "\n"; $col_count++; if (empty($_SESSION['voicemail']['storage_type']['text']) || $_SESSION['voicemail']['storage_type']['text'] != 'base64') { echo "\n"; $col_count++; } echo th_order_by('greeting_description', $text['label-description'], $order_by, $order, null, "class='hide-sm-dn pct-25'", "id=".urlencode($voicemail_id)); $col_count++; if (permission_exists('voicemail_greeting_edit') && $settings->get('theme', 'list_row_edit_button', false)) { echo " \n"; } echo "\n"; if (is_array($greetings) && @sizeof($greetings) != 0) { $x = 0; foreach ($greetings as $row) { //playback progress bar if (permission_exists('voicemail_greeting_play')) { echo "\n"; echo "\n"; // dummy row to maintain alternating background color } $list_row_url = ''; if (permission_exists('voicemail_greeting_edit')) { $list_row_url = "voicemail_greeting_edit.php?id=".urlencode($row['voicemail_greeting_uuid'])."&voicemail_id=".urlencode($voicemail_id); if ($row['domain_uuid'] != $_SESSION['domain_uuid'] && permission_exists('domain_select')) { $list_row_url .= '&domain_uuid='.urlencode($row['domain_uuid']).'&domain_change=true'; } } echo "\n"; if (permission_exists('voicemail_greeting_delete')) { echo " \n"; } echo " \n"; echo " \n"; echo " \n"; if (empty($_SESSION['voicemail']['storage_type']['text']) || $_SESSION['voicemail']['storage_type']['text'] != 'base64') { echo " \n"; } if (permission_exists('voicemail_greeting_play') || permission_exists('voicemail_greeting_download')) { echo " \n"; } if (!empty($_SESSION['voicemail']['storage_type']['text']) && $_SESSION['voicemail']['storage_type']['text'] == 'base64') { $file_size = byte_convert($row['greeting_size']); echo " \n"; } else { $file_size = byte_convert(filesize($greeting_dir.'/'.$row['greeting_filename'])); $file_date = date("M d, Y H:i:s", filemtime($greeting_dir.'/'.$row['greeting_filename'])); echo " \n"; echo " \n"; } echo " \n"; if (permission_exists('voicemail_greeting_edit') && $settings->get('theme', 'list_row_edit_button', false)) { echo " \n"; } echo "\n"; $x++; } unset($greetings); } echo "
\n"; echo " \n"; echo " ".$text['label-selected']."".$text['label-tools']."".$text['label-size']."".$text['label-uploaded']." 
\n"; echo " \n"; echo " \n"; echo " ".escape($row['greeting_id']).""; if (permission_exists('voicemail_greeting_edit')) { echo "".escape($row['greeting_name']).""; } else { echo escape($row['greeting_name']); } echo " ".escape($row['greeting_filename'])."".$file_size."".$file_size."".$file_date."".escape($row['greeting_description'])." "; echo button::create(['type'=>'button','title'=>$text['button-edit'],'icon'=>$settings->get('theme', 'button_icon_edit'),'link'=>$list_row_url]); echo "
\n"; echo "
\n"; echo "
\n"; echo "\n"; echo "
\n"; //include the footer require_once "resources/footer.php"; //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 (!empty($range0) && $range0 == '-') { // 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); }