Portions created by the Initial Developer are Copyright (C) 2008-2023 the Initial Developer. All Rights Reserved. Contributor(s): Mark J Crane Luis Daniel Lucio Quiroz */ //includes files require_once dirname(__DIR__, 2) . "/resources/require.php"; require_once "resources/check_auth.php"; require_once "resources/paging.php"; //check permisions if (permission_exists('xml_cdr_view')) { //access granted } else { echo "access denied"; exit; } //add multi-lingual support $language = new text; $text = $language->get(); //set defaults $archive_request = false; $action = ''; $xml_cdrs = []; $paging_controls_mini = ''; $paging_controls = null; $order_by = ""; if(!isset($_REQUEST['show'])) { //set to show only this domain $_REQUEST['show'] = 'domain'; } //get posted data if (!$archive_request && isset($_POST['xml_cdrs']) && is_array($_POST['xml_cdrs'])) { $action = $_POST['action'] ?? ''; $xml_cdrs = $_POST['xml_cdrs'] ?? []; } //process the http post data by action if (!$archive_request && $action != '' && count($xml_cdrs) > 0) { switch ($action) { case 'delete': if (permission_exists('xml_cdr_delete')) { $obj = new xml_cdr; $obj->delete($xml_cdrs); } break; } header('Location: xml_cdr.php'); exit; } //create token $object = new token; $token = $object->create($_SERVER['PHP_SELF']); //include the header if ($archive_request) { $document['title'] = $text['title-call_detail_records_archive']; } else { $document['title'] = $text['title-call_detail_records']; } require_once "resources/header.php"; //xml cdr include $rows_per_page = ($_SESSION['domain']['paging']['numeric'] != '') ? $_SESSION['domain']['paging']['numeric'] : 50; require_once "xml_cdr_inc.php"; //javascript function: send_cmd echo "\n"; //javascript to toggle export select box echo ""; //show the content echo "
\n"; echo "
"; if ($archive_request) { echo "".$text['title-call_detail_records_archive'].""; } else { echo "".$text['title-call_detail_records'].""; } echo "
\n"; echo "
\n"; if (!$archive_request) { if (permission_exists('xml_cdr_statistics')) { echo button::create(['type'=>'button','label'=>$text['button-statistics'],'icon'=>'chart-area','link'=>'xml_cdr_statistics.php']); } if (permission_exists('xml_cdr_archive')) { echo button::create(['type'=>'button','label'=>$text['button-archive'],'icon'=>'archive','link'=>'xml_cdr_archive.php'.($_REQUEST['show'] == 'all' ? '?show=all' : null)]); } } echo "
\n"; if ($archive_request) { echo " \n"; } echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; if (permission_exists('xml_cdr_all') && $_REQUEST['show'] == 'all') { echo " \n"; } if (isset($_SESSION['cdr']['field']) && is_array($_SESSION['cdr']['field'])) { foreach ($_SESSION['cdr']['field'] as $field) { $array = explode(",", $field); $field_name = $array[count($array) - 1]; if (isset($_REQUEST[$field_name])) { echo " \n"; } } } if (isset($order_by)) { echo " \n"; echo " \n"; } if ($archive_request) { echo button::create(['type'=>'button','label'=>$text['button-back'],'icon'=>$_SESSION['theme']['button_icon_back'],'link'=>'xml_cdr.php']); } echo button::create(['type'=>'button','label'=>$text['button-refresh'],'icon'=>'sync-alt','style'=>'margin-left: 15px;','onclick'=>'location.reload(true);']); if (isset($_GET['status']) && $_GET['status'] != 'missed') { echo button::create(['type'=>'button','label'=>$text['button-missed'],'icon'=>'phone-slash','link'=>'?status=missed']); } if (permission_exists('xml_cdr_export')) { echo button::create(['type'=>'button','label'=>$text['button-export'],'icon'=>$_SESSION['theme']['button_icon_export'],'onclick'=>"toggle_select('export_format'); this.blur();"]); echo ""; } if (!$archive_request && permission_exists('xml_cdr_delete')) { echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'name'=>'btn_delete','onclick'=>"modal_open('modal-delete','btn_delete');"]); } if (permission_exists('xml_cdr_all') && $_REQUEST['show'] !== 'all') { echo button::create(['type'=>'button','label'=>$text['button-show_all'],'icon'=>$_SESSION['theme']['button_icon_all'],'link'=>'?show=all']); } if ($paging_controls_mini != '') { echo "".$paging_controls_mini.""; } echo "
\n"; echo "
\n"; echo "
\n"; echo "
\n"; if (!$archive_request && permission_exists('xml_cdr_delete')) { 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']." \n"; echo "

\n"; //basic search of call detail records if (permission_exists('xml_cdr_search')) { echo "
\n"; echo "
\n"; if (permission_exists('xml_cdr_search_direction')) { echo "
\n"; echo "
\n"; echo " ".$text['label-direction']."\n"; echo "
\n"; echo "
\n"; echo " \n"; if (permission_exists('xml_cdr_b_leg')){ echo " \n"; } echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_status')) { echo "
\n"; echo "
\n"; echo " ".$text['label-status']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_extension')) { $sql = "select extension_uuid, extension, number_alias from v_extensions "; $sql .= "where domain_uuid = :domain_uuid "; if (!permission_exists('xml_cdr_domain') && is_array($extension_uuids) && @sizeof($extension_uuids != 0)) { $sql .= "and extension_uuid in ('".implode("','",$extension_uuids)."') "; //only show the user their extensions } $sql .= "order by extension asc, number_alias asc "; $parameters['domain_uuid'] = $_SESSION['domain_uuid']; $database = new database; $result_e = $database->select($sql, $parameters, 'all'); echo "
\n"; echo "
\n"; echo " ".$text['label-extension']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo "
\n"; echo "
\n"; unset($sql, $parameters, $result_e, $row, $selected); } if (permission_exists('xml_cdr_search_caller_id')) { echo "
\n"; echo "
\n"; echo " ".$text['label-caller_id']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_start_range')) { echo "
\n"; echo "
\n"; echo " ".$text['label-start_range']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_duration')) { echo "
\n"; echo "
\n"; echo " ".$text['label-duration']." (".$text['label-seconds'].")\n"; echo "
\n"; echo "
\n"; echo " \n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_caller_destination')) { echo "
\n"; echo "
\n"; echo " ".$text['label-caller_destination']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_destination')) { echo "
\n"; echo "
\n"; echo " ".$text['label-destination']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_tta')) { echo "
\n"; echo "
\n"; echo " ".$text['label-tta']." (".$text['label-seconds'].")\n"; echo "
\n"; echo "
\n"; echo " \n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_hangup_cause')) { echo "
\n"; echo "
\n"; echo " ".$text['label-hangup_cause']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_recording')) { echo "
\n"; echo "
\n"; echo " ".$text['label-recording']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo "
\n"; echo "
\n"; } if (permission_exists('xml_cdr_search_order')) { echo "
\n"; echo "
\n"; echo " ".$text['label-order']."\n"; echo "
\n"; echo "
\n"; echo " \n"; echo " \n"; echo "
\n"; echo "
\n"; } echo "
\n"; button::$collapse = false; echo "
"; if (permission_exists('xml_cdr_all') && $_REQUEST['show'] == 'all') { echo "\n"; } if (!$archive_request && permission_exists('xml_cdr_search_advanced')) { echo button::create(['type'=>'button','label'=>$text['button-advanced_search'],'icon'=>'tools','link'=>"xml_cdr_search.php".($_REQUEST['show'] == 'all' ? '?show=all' : null),'style'=>'margin-right: 15px;']); } echo button::create(['label'=>$text['button-reset'],'icon'=>$_SESSION['theme']['button_icon_reset'],'type'=>'button','link'=>($archive_request ? 'xml_cdr_archive.php' : 'xml_cdr.php')]); echo button::create(['label'=>$text['button-search'],'icon'=>$_SESSION['theme']['button_icon_search'],'type'=>'submit','id'=>'btn_save','name'=>'submit']); echo "
\n"; echo "
".$text['description_search']."
\n"; echo "
"; } //mod paging parameters for inclusion in column sort heading links $param = substr($param, 1); //remove leading '&' $param = substr($param, 0, strrpos($param, '&order_by=')); //remove trailing order by //show the results echo "
\n"; echo "\n"; echo "\n"; echo "\n"; $col_count = 0; if (!$archive_request && permission_exists('xml_cdr_delete')) { echo " \n"; $col_count++; } //column headings if (permission_exists('xml_cdr_direction')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_extension')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_all') && $_REQUEST['show'] == "all") { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_caller_id_name')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_caller_id_number')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_caller_destination')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_destination')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_recording') && (permission_exists('xml_cdr_recording_play') || permission_exists('xml_cdr_recording_download'))) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_custom_fields')) { if (isset($_SESSION['cdr']['field']) && is_array($_SESSION['cdr']['field']) && @sizeof($_SESSION['cdr']['field'])) { foreach ($_SESSION['cdr']['field'] as $field) { $array = explode(",", $field); $field_name = end($array); $field_label = ucwords(str_replace("_", " ", $field_name)); $field_label = str_replace("Sip", "SIP", $field_label); if ($field_name != "destination_number") { echo "\n"; $col_count++; } } } } if (permission_exists('xml_cdr_start')) { echo "\n"; echo "\n"; $col_count += 2; } if (permission_exists('xml_cdr_tta')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_duration')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_pdd')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_mos')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_status')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_hangup_cause')) { echo "\n"; $col_count++; } if (permission_exists('xml_cdr_details')) { echo "\n"; } echo "\n"; //show results if (is_array($result)) { //determine if theme images exist $theme_image_path = $_SERVER["DOCUMENT_ROOT"]."/themes/".$_SESSION['domain']['template']['name']."/images/"; $theme_cdr_images_exist = ( file_exists($theme_image_path."icon_cdr_inbound_answered.png") && file_exists($theme_image_path."icon_cdr_inbound_voicemail.png") && file_exists($theme_image_path."icon_cdr_inbound_missed.png") && file_exists($theme_image_path."icon_cdr_inbound_cancelled.png") && file_exists($theme_image_path."icon_cdr_inbound_failed.png") && file_exists($theme_image_path."icon_cdr_outbound_answered.png") && file_exists($theme_image_path."icon_cdr_outbound_cancelled.png") && file_exists($theme_image_path."icon_cdr_outbound_busy.png") && file_exists($theme_image_path."icon_cdr_outbound_failed.png") && file_exists($theme_image_path."icon_cdr_local_answered.png") && file_exists($theme_image_path."icon_cdr_local_voicemail.png") && file_exists($theme_image_path."icon_cdr_local_cancelled.png") && file_exists($theme_image_path."icon_cdr_local_failed.png") ) ? true : false; //simplify the variables $outbound_caller_id_name = $_SESSION['user']['extension'][0]['outbound_caller_id_name'] ?? ''; $outbound_caller_id_number = $_SESSION['user']['extension'][0]['outbound_caller_id_number'] ?? ''; $user_extension = $_SESSION['user']['extension'][0]['user'] ?? ''; //loop through the results $x = 0; foreach ($result as $index => $row) { //set the status $status = $row['status']; if (empty($row['status'])) { //define an array of failed hangup causes $failed_array = array( "CALL_REJECTED", "CHAN_NOT_IMPLEMENTED", "DESTINATION_OUT_OF_ORDER", "EXCHANGE_ROUTING_ERROR", "INCOMPATIBLE_DESTINATION", "INVALID_NUMBER_FORMAT", "MANDATORY_IE_MISSING", "NETWORK_OUT_OF_ORDER", "NORMAL_TEMPORARY_FAILURE", "NORMAL_UNSPECIFIED", "NO_ROUTE_DESTINATION", "RECOVERY_ON_TIMER_EXPIRE", "REQUESTED_CHAN_UNAVAIL", "SUBSCRIBER_ABSENT", "SYSTEM_SHUTDOWN", "UNALLOCATED_NUMBER" ); //determine the call status if ($row['billsec'] > 0) { $status = 'answered'; } if ($row['missed_call'] == '1') { $status = 'missed'; } if (substr($row['destination_number'], 0, 3) == '*99') { $status = 'voicemail'; } if ($row['hangup_cause'] == 'ORIGINATOR_CANCEL') { $status = 'cancelled'; } if ($row['hangup_cause'] == 'USER_BUSY') { $status = 'busy'; } if (in_array($row['hangup_cause'], $failed_array)) { $status = 'failed'; } } //clear previous variables unset($record_path, $record_name); //get the hangup cause $hangup_cause = $row['hangup_cause']; $hangup_cause = str_replace("_", " ", $hangup_cause); $hangup_cause = strtolower($hangup_cause); $hangup_cause = ucwords($hangup_cause); //if call cancelled, show the ring time, not the bill time. $seconds = $row['hangup_cause'] == "ORIGINATOR_CANCEL" ? $row['duration'] : round(($row['billmsec'] / 1000), 0, PHP_ROUND_HALF_UP); //determine recording properties if (!empty($row['record_path']) && !empty($row['record_name']) && permission_exists('xml_cdr_recording') && (permission_exists('xml_cdr_recording_play') || permission_exists('xml_cdr_recording_download'))) { $record_path = $row['record_path']; $record_name = $row['record_name']; //$record_name = strtolower(pathinfo($tmp_name, PATHINFO_BASENAME)); $record_extension = pathinfo($record_name, PATHINFO_EXTENSION); switch ($record_extension) { case "wav" : $record_type = "audio/wav"; break; case "mp3" : $record_type = "audio/mpeg"; break; case "ogg" : $record_type = "audio/ogg"; break; } } //set an empty content variable $content = ''; //recording playback if (permission_exists('xml_cdr_recording_play')) { $content .= "\n"; $content .= "\n"; // dummy row to maintain alternating background color } if (permission_exists('xml_cdr_details')) { $list_row_url = "xml_cdr_details.php?id=".urlencode($row['xml_cdr_uuid']).($_REQUEST['show'] ? "&show=all" : null); } $content .= "\n"; if (!$archive_request && permission_exists('xml_cdr_delete')) { $content .= " \n"; } //determine call result and appropriate icon if (permission_exists('xml_cdr_direction')) { $content .= "\n"; } //extension if (permission_exists('xml_cdr_extension')) { $content .= " \n"; } //domain name if (permission_exists('xml_cdr_all') && $_REQUEST['show'] == "all") { $content .= " \n"; } //caller id name if (permission_exists('xml_cdr_caller_id_name')) { $content .= " \n"; } //source if (permission_exists('xml_cdr_caller_id_number')) { $content .= " \n"; } //caller destination if (permission_exists('xml_cdr_caller_destination')) { $content .= " \n"; } //destination if (permission_exists('xml_cdr_destination')) { $content .= " \n"; } //recording if (permission_exists('xml_cdr_recording') && (permission_exists('xml_cdr_recording_play') || permission_exists('xml_cdr_recording_download'))) { if (!empty($record_path) || !empty($record_name)) { $content .= " \n"; } else { $content .= " \n"; } } //custom cdr fields if (permission_exists('xml_cdr_custom_fields')) { if (!empty($_SESSION['cdr']['field']) && is_array($_SESSION['cdr']['field'])) { foreach ($_SESSION['cdr']['field'] as $field) { $array = explode(",", $field); $field_name = $array[count($array) - 1]; if ($field_name != "destination_number") { $content .= " \n"; } } } } //start if (permission_exists('xml_cdr_start')) { $content .= " \n"; $content .= " \n"; } //tta (time to answer) if (permission_exists('xml_cdr_tta')) { $content .= " \n"; } //duration if (permission_exists('xml_cdr_duration')) { $content .= " \n"; } //pdd (post dial delay) if (permission_exists("xml_cdr_pdd")) { $content .= " \n"; } //mos (mean opinion score) if (permission_exists("xml_cdr_mos")) { if(!empty($row['rtp_audio_in_mos'])){ $title = " title='".$text['label-mos_score-'.round($row['rtp_audio_in_mos'])]."'"; $value = $row['rtp_audio_in_mos']; } $content .= " \n"; } //call result/status if (permission_exists("xml_cdr_status")) { $content .= " \n"; } //hangup cause if (permission_exists('xml_cdr_hangup_cause')) { $content .= " \n"; } $content .= "\n"; //show the leg b only to those with the permission if ($row['leg'] == 'a') { echo $content; } else if ($row['leg'] == 'b' && permission_exists('xml_cdr_b_leg')) { echo $content; } unset($content); $x++; } unset($sql, $result, $row_count); } echo "
\n"; echo " \n"; echo "  ".$text['label-ext']."".$text['label-domain']."".$text['label-caller_id_name']."".$text['label-caller_id_number']."".$text['label-caller_destination']."".$text['label-destination']."".$text['label-recording']."".$field_label."".$text['label-date']."".$text['label-time']."".$text['label-tta']."".$text['label-duration']."".$text['label-pdd']."".$text['label-mos']."".$text['label-status']."".$text['label-hangup_cause']." 
\n"; $content .= " \n"; $content .= " \n"; $content .= " \n"; if ($theme_cdr_images_exist) { if (!empty($row['direction'])) { $image_name = "icon_cdr_" . $row['direction'] . "_" . $status; if ($row['leg'] == 'b') { $image_name .= '_b'; } $image_name .= ".png"; $content .= "\n"; } } else { $content .= " "; } $content .= "".$row['extension']."".$row['domain_name']."".escape($row['caller_id_name'])." ".escape($row[$field_name])."".$row['start_date_formatted']."".$row['start_time_formatted']."".(!empty($row['tta']) && $row['tta'] >= 0 ? $row['tta']."s" : " ")."".gmdate("G:i:s", $seconds)."".number_format(escape($row['pdd_ms'])/1000,2)."s".($value ?? '')."".escape($text['label-'.$status])."".escape($hangup_cause)."
\n"; echo "
\n"; echo "
".$paging_controls."
\n"; echo "\n"; echo "
\n"; //store last search/sort query parameters in session $_SESSION['xml_cdr']['last_query'] = $_SERVER["QUERY_STRING"]; //show the footer require_once "resources/footer.php"; ?>