2016-04-27 21:24:59 +02:00
< ? 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 ) 2016
the Initial Developer . All Rights Reserved .
Contributor ( s ) :
Mark J Crane < markjcrane @ fusionpbx . com >
*/
/**
* xml_cdr class provides methods for adding cdr records to the database
*
* @ method boolean add
*/
if ( ! class_exists ( 'xml_cdr' )) {
class xml_cdr {
//define variables
public $db ;
public $array ;
public $debug ;
public $fields ;
2016-06-06 01:19:06 +02:00
//user summary
public $domain_uuid ;
public $quick_select ;
public $start_stamp_begin ;
public $start_stamp_end ;
public $include_internal ;
public $extensions ;
2016-04-27 21:24:59 +02:00
/**
* Called when the object is created
*/
public function __construct () {
//connect to the database if not connected
if ( ! $this -> db ) {
require_once " resources/classes/database.php " ;
$database = new database ;
$database -> connect ();
$this -> db = $database -> db ;
}
}
/**
* Called when there are no references to a particular object
* unset the variables used in the class
*/
public function __destruct () {
2016-04-30 08:33:35 +02:00
if ( isset ( $this )) foreach ( $this as $key => $value ) {
2016-04-27 21:24:59 +02:00
unset ( $this -> $key );
}
}
/**
* cdr process logging
*/
public function log ( $message ) {
//save to file system (alternative to a syslog server)
$fp = fopen ( $_SESSION [ 'server' ][ 'temp' ][ 'dir' ] . '/xml_cdr.log' , 'a+' );
if ( ! $fp ) {
return ;
}
2016-04-28 07:51:53 +02:00
fwrite ( $fp , $message );
2016-04-27 21:24:59 +02:00
fclose ( $fp );
}
/**
* cdr fields in the database schema
*/
public function fields () {
2016-04-28 07:51:53 +02:00
$this -> fields [] = " uuid " ;
$this -> fields [] = " domain_uuid " ;
$this -> fields [] = " extension_uuid " ;
$this -> fields [] = " domain_name " ;
$this -> fields [] = " accountcode " ;
$this -> fields [] = " direction " ;
$this -> fields [] = " default_language " ;
$this -> fields [] = " context " ;
$this -> fields [] = " xml " ;
$this -> fields [] = " json " ;
$this -> fields [] = " caller_id_name " ;
$this -> fields [] = " caller_id_number " ;
2017-05-29 23:54:39 +02:00
$this -> fields [] = " caller_destination " ;
2016-04-28 07:51:53 +02:00
$this -> fields [] = " destination_number " ;
2016-05-12 00:23:42 +02:00
$this -> fields [] = " source_number " ;
2016-04-28 07:51:53 +02:00
$this -> fields [] = " start_epoch " ;
$this -> fields [] = " start_stamp " ;
$this -> fields [] = " answer_stamp " ;
$this -> fields [] = " answer_epoch " ;
$this -> fields [] = " end_epoch " ;
$this -> fields [] = " end_stamp " ;
$this -> fields [] = " duration " ;
$this -> fields [] = " mduration " ;
$this -> fields [] = " billsec " ;
$this -> fields [] = " billmsec " ;
$this -> fields [] = " bridge_uuid " ;
$this -> fields [] = " read_codec " ;
$this -> fields [] = " read_rate " ;
$this -> fields [] = " write_codec " ;
$this -> fields [] = " write_rate " ;
$this -> fields [] = " remote_media_ip " ;
$this -> fields [] = " network_addr " ;
$this -> fields [] = " recording_file " ;
$this -> fields [] = " leg " ;
$this -> fields [] = " pdd_ms " ;
$this -> fields [] = " rtp_audio_in_mos " ;
$this -> fields [] = " last_app " ;
$this -> fields [] = " last_arg " ;
$this -> fields [] = " cc_side " ;
$this -> fields [] = " cc_member_uuid " ;
$this -> fields [] = " cc_queue_joined_epoch " ;
$this -> fields [] = " cc_queue " ;
$this -> fields [] = " cc_member_session_uuid " ;
$this -> fields [] = " cc_agent " ;
$this -> fields [] = " cc_agent_type " ;
$this -> fields [] = " waitsec " ;
$this -> fields [] = " conference_name " ;
$this -> fields [] = " conference_uuid " ;
$this -> fields [] = " conference_member_id " ;
$this -> fields [] = " digits_dialed " ;
$this -> fields [] = " pin_number " ;
$this -> fields [] = " hangup_cause " ;
$this -> fields [] = " hangup_cause_q850 " ;
$this -> fields [] = " sip_hangup_disposition " ;
2016-12-21 22:02:56 +01:00
if ( is_array ( $_SESSION [ 'cdr' ][ 'field' ])) {
foreach ( $_SESSION [ 'cdr' ][ 'field' ] as $field ) {
$this -> fields [] = $field ;
}
}
2016-04-27 21:24:59 +02:00
}
/**
* save to the database
*/
public function save () {
2016-04-28 07:51:53 +02:00
$this -> fields ();
2016-04-27 21:24:59 +02:00
$field_count = sizeof ( $this -> fields );
$sql = " insert into v_xml_cdr ( " ;
2016-04-28 07:51:53 +02:00
$f = 1 ;
2016-04-30 08:33:35 +02:00
if ( isset ( $this -> fields )) foreach ( $this -> fields as $field ) {
2016-04-28 07:51:53 +02:00
if ( $field_count == $f ) {
$sql .= " $field " ;
}
else {
$sql .= " $field , " ;
}
$f ++ ;
2016-04-27 21:24:59 +02:00
}
$sql .= " ) \n " ;
$sql .= " values \n " ;
$row_count = sizeof ( $this -> array );
//$field_count = sizeof($this->fields);
$i = 0 ;
2016-04-30 08:33:35 +02:00
if ( isset ( $this -> array )) foreach ( $this -> array as $row ) {
2016-04-27 21:24:59 +02:00
$sql .= " ( " ;
2016-04-28 07:51:53 +02:00
$f = 1 ;
2016-04-30 08:33:35 +02:00
if ( isset ( $this -> fields )) foreach ( $this -> fields as $field ) {
2016-04-28 07:51:53 +02:00
if ( isset ( $row [ $field ]) && strlen ( $row [ $field ]) > 0 ) {
2016-04-27 21:24:59 +02:00
$sql .= " ' " . $row [ $field ] . " ' " ;
}
else {
$sql .= " null " ;
}
2016-04-28 07:51:53 +02:00
if ( $field_count != $f ) {
2016-04-27 21:24:59 +02:00
$sql .= " , " ;
}
$f ++ ;
}
$sql .= " ) " ;
if ( $row_count != $i ) {
$sql .= " , \n " ;
}
$i ++ ;
}
2016-04-28 07:51:53 +02:00
if ( substr ( $sql , - 2 ) == " , \n " ) {
$sql = substr ( $sql , 0 , - 2 );
}
2016-04-27 21:24:59 +02:00
$this -> db -> exec ( check_sql ( $sql ));
unset ( $sql );
}
/**
* process method converts the xml cdr and adds it to the database
*/
2016-06-12 00:17:35 +02:00
public function xml_array ( $key , $leg , $xml_string ) {
2016-04-27 21:24:59 +02:00
//fix the xml by escaping the contents of <sip_full_XXX>
if ( defined ( 'STDIN' )) {
$xml_string = preg_replace_callback ( " /<([^><]+)>(.*?[><].*?)< \ / \ g1>/ " ,
function ( $matches ) {
return '<' . $matches [ 1 ] . '>' .
str_replace ( " > " , " > " ,
str_replace ( " < " , " < " , $matches [ 2 ])
) .
'</' . $matches [ 1 ] . '>' ;
},
$xml_string
);
}
//parse the xml to get the call detail record info
2016-04-28 07:51:53 +02:00
try {
//$this->log($xml_string);
$xml = simplexml_load_string ( $xml_string );
//$this->log("\nxml load done\n");
}
catch ( Exception $e ) {
echo $e -> getMessage ();
//$this->log("\nfail loadxml: " . $e->getMessage() . "\n");
}
2016-04-27 21:24:59 +02:00
2016-05-12 02:37:01 +02:00
//get the destination number
2016-05-12 00:23:42 +02:00
if ( $xml -> variables -> current_application == " bridge " ) {
$current_application_data = urldecode ( $xml -> variables -> current_application_data );
2016-05-12 01:05:06 +02:00
$bridge_array = explode ( " / " , $current_application_data );
2016-05-12 00:23:42 +02:00
$destination_number = end ( $bridge_array );
2016-05-12 01:58:43 +02:00
if ( strpos ( $destination_number , '@' ) !== FALSE ) {
$destination_array = explode ( " @ " , $destination_number );
$destination_number = $destination_array [ 0 ];
}
2016-05-12 00:23:42 +02:00
}
else {
2016-05-12 01:58:43 +02:00
$destination_number = urldecode ( $xml -> variables -> sip_to_user );
2016-05-12 00:23:42 +02:00
}
2016-05-12 02:37:01 +02:00
2016-06-02 00:45:50 +02:00
//if last_sent_callee_id_number is set use it for the destination_number
if ( strlen ( $xml -> variables -> last_sent_callee_id_number ) > 0 ) {
$destination_number = urldecode ( $xml -> variables -> last_sent_callee_id_number );
}
2017-05-29 23:54:39 +02:00
//get the caller details
2016-05-12 02:37:01 +02:00
$caller_id_name = urldecode ( $xml -> variables -> effective_caller_id_name );
$caller_id_number = urldecode ( $xml -> variables -> effective_caller_id_number );
2017-05-29 23:54:39 +02:00
$caller_id_destination = urldecode ( $xml -> variables -> caller_destination );
2016-05-12 02:37:01 +02:00
if ( strlen ( $caller_id_number ) == 0 ) foreach ( $xml -> callflow as $row ) {
$caller_id_name = urldecode ( $row -> caller_profile -> caller_id_name );
$caller_id_number = urldecode ( $row -> caller_profile -> caller_id_number );
}
//misc
$uuid = check_str ( urldecode ( $xml -> variables -> uuid ));
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'uuid' ] = $uuid ;
$this -> array [ $key ][ 'destination_number' ] = check_str ( $destination_number );
$this -> array [ $key ][ 'source_number' ] = check_str ( urldecode ( $xml -> variables -> effective_caller_id_number ));
$this -> array [ $key ][ 'user_context' ] = check_str ( urldecode ( $xml -> variables -> user_context ));
$this -> array [ $key ][ 'network_addr' ] = check_str ( urldecode ( $xml -> variables -> sip_network_ip ));
$this -> array [ $key ][ 'caller_id_name' ] = check_str ( $caller_id_name );
$this -> array [ $key ][ 'caller_id_number' ] = check_str ( $caller_id_number );
$this -> array [ $key ][ 'accountcode' ] = check_str ( urldecode ( $xml -> variables -> accountcode ));
$this -> array [ $key ][ 'default_language' ] = check_str ( urldecode ( $xml -> variables -> default_language ));
$this -> array [ $key ][ 'bridge_uuid' ] = check_str ( urldecode ( $xml -> variables -> bridge_uuid ));
//$this->array[$key]['digits_dialed'] = check_str(urldecode($xml->variables->digits_dialed));
$this -> array [ $key ][ 'sip_hangup_disposition' ] = check_str ( urldecode ( $xml -> variables -> sip_hangup_disposition ));
$this -> array [ $key ][ 'pin_number' ] = check_str ( urldecode ( $xml -> variables -> pin_number ));
2016-04-27 21:24:59 +02:00
//time
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'start_epoch' ] = check_str ( urldecode ( $xml -> variables -> start_epoch ));
2016-04-27 21:24:59 +02:00
$start_stamp = check_str ( urldecode ( $xml -> variables -> start_stamp ));
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'start_stamp' ] = $start_stamp ;
$this -> array [ $key ][ 'answer_stamp' ] = check_str ( urldecode ( $xml -> variables -> answer_stamp ));
$this -> array [ $key ][ 'answer_epoch' ] = check_str ( urldecode ( $xml -> variables -> answer_epoch ));
$this -> array [ $key ][ 'end_epoch' ] = check_str ( urldecode ( $xml -> variables -> end_epoch ));
$this -> array [ $key ][ 'end_stamp' ] = check_str ( urldecode ( $xml -> variables -> end_stamp ));
$this -> array [ $key ][ 'duration' ] = check_str ( urldecode ( $xml -> variables -> duration ));
$this -> array [ $key ][ 'mduration' ] = check_str ( urldecode ( $xml -> variables -> mduration ));
$this -> array [ $key ][ 'billsec' ] = check_str ( urldecode ( $xml -> variables -> billsec ));
$this -> array [ $key ][ 'billmsec' ] = check_str ( urldecode ( $xml -> variables -> billmsec ));
2016-04-27 21:24:59 +02:00
//codecs
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'read_codec' ] = check_str ( urldecode ( $xml -> variables -> read_codec ));
$this -> array [ $key ][ 'read_rate' ] = check_str ( urldecode ( $xml -> variables -> read_rate ));
$this -> array [ $key ][ 'write_codec' ] = check_str ( urldecode ( $xml -> variables -> write_codec ));
$this -> array [ $key ][ 'write_rate' ] = check_str ( urldecode ( $xml -> variables -> write_rate ));
$this -> array [ $key ][ 'remote_media_ip' ] = check_str ( urldecode ( $xml -> variables -> remote_media_ip ));
$this -> array [ $key ][ 'hangup_cause' ] = check_str ( urldecode ( $xml -> variables -> hangup_cause ));
$this -> array [ $key ][ 'hangup_cause_q850' ] = check_str ( urldecode ( $xml -> variables -> hangup_cause_q850 ));
2016-04-27 21:24:59 +02:00
//call center
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'cc_side' ] = check_str ( urldecode ( $xml -> variables -> cc_side ));
$this -> array [ $key ][ 'cc_member_uuid' ] = check_str ( urldecode ( $xml -> variables -> cc_member_uuid ));
$this -> array [ $key ][ 'cc_queue_joined_epoch' ] = check_str ( urldecode ( $xml -> variables -> cc_queue_joined_epoch ));
$this -> array [ $key ][ 'cc_queue' ] = check_str ( urldecode ( $xml -> variables -> cc_queue ));
$this -> array [ $key ][ 'cc_member_session_uuid' ] = check_str ( urldecode ( $xml -> variables -> cc_member_session_uuid ));
$this -> array [ $key ][ 'cc_agent' ] = check_str ( urldecode ( $xml -> variables -> cc_agent ));
$this -> array [ $key ][ 'cc_agent_type' ] = check_str ( urldecode ( $xml -> variables -> cc_agent_type ));
$this -> array [ $key ][ 'waitsec' ] = check_str ( urldecode ( $xml -> variables -> waitsec ));
2016-04-27 21:24:59 +02:00
//app info
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'last_app' ] = check_str ( urldecode ( $xml -> variables -> last_app ));
$this -> array [ $key ][ 'last_arg' ] = check_str ( urldecode ( $xml -> variables -> last_arg ));
2016-04-27 21:24:59 +02:00
//conference
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'conference_name' ] = check_str ( urldecode ( $xml -> variables -> conference_name ));
$this -> array [ $key ][ 'conference_uuid' ] = check_str ( urldecode ( $xml -> variables -> conference_uuid ));
$this -> array [ $key ][ 'conference_member_id' ] = check_str ( urldecode ( $xml -> variables -> conference_member_id ));
2016-04-27 21:24:59 +02:00
//call quality
$rtp_audio_in_mos = check_str ( urldecode ( $xml -> variables -> rtp_audio_in_mos ));
if ( strlen ( $rtp_audio_in_mos ) > 0 ) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'rtp_audio_in_mos' ] = $rtp_audio_in_mos ;
2016-04-27 21:24:59 +02:00
}
//store the call leg
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'leg' ] = $leg ;
2016-04-27 21:24:59 +02:00
//store the call direction
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'direction' ] = check_str ( urldecode ( $xml -> variables -> call_direction ));
2016-04-27 21:24:59 +02:00
//store post dial delay, in milliseconds
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'pdd_ms' ] = check_str ( urldecode ( $xml -> variables -> progress_mediamsec ) + urldecode ( $xml -> variables -> progressmsec ));
2016-04-27 21:24:59 +02:00
//get break down the date to year, month and day
$tmp_time = strtotime ( $start_stamp );
$tmp_year = date ( " Y " , $tmp_time );
$tmp_month = date ( " M " , $tmp_time );
$tmp_day = date ( " d " , $tmp_time );
//get the domain values from the xml
$domain_name = check_str ( urldecode ( $xml -> variables -> domain_name ));
$domain_uuid = check_str ( urldecode ( $xml -> variables -> domain_uuid ));
2016-10-26 02:06:34 +02:00
//get the domain name
2016-04-27 21:24:59 +02:00
if ( strlen ( $domain_name ) == 0 ) {
$domain_name = check_str ( urldecode ( $xml -> variables -> sip_req_host ));
}
2016-10-26 02:02:26 +02:00
if ( strlen ( $domain_name ) == 0 ) {
$presence_id = check_str ( urldecode ( $xml -> variables -> presence_id ));
if ( strlen ( $presence_id ) > 0 ) {
$presence_array = explode ( $presence_id );
$domain_name = $presence_array [ 1 ];
}
}
2016-04-27 21:24:59 +02:00
2016-12-21 22:02:56 +01:00
//dynamic cdr fields
if ( is_array ( $_SESSION [ 'cdr' ][ 'field' ])) {
foreach ( $_SESSION [ 'cdr' ][ 'field' ] as $field ) {
2016-12-23 05:14:22 +01:00
$fields = explode ( " , " , $field );
$field_name = end ( $fields );
$this -> fields [] = $field_name ;
if ( count ( $fields ) == 1 ) {
$this -> array [ $key ][ $field_name ] = urldecode ( $xml -> variables -> $fields [ 0 ]);
}
if ( count ( $fields ) == 2 ) {
$this -> array [ $key ][ $field_name ] = urldecode ( $xml -> $fields [ 0 ] -> $fields [ 1 ]);
}
if ( count ( $fields ) == 3 ) {
$this -> array [ $key ][ $field_name ] = urldecode ( $xml -> $fields [ 0 ] -> $fields [ 1 ] -> $fields [ 2 ]);
}
2016-12-21 22:02:56 +01:00
}
}
2016-04-27 21:24:59 +02:00
//send the domain name to the cdr log
2016-04-28 07:51:53 +02:00
//$this->log("\ndomain_name is `$domain_name`; domain_uuid is '$domain_uuid'\n");
2016-04-27 21:24:59 +02:00
//get the domain_uuid with the domain_name
if ( strlen ( $domain_uuid ) == 0 ) {
$sql = " select domain_uuid from v_domains " ;
if ( strlen ( $domain_name ) == 0 && $context != 'public' && $context != 'default' ) {
$sql .= " where domain_name = ' " . $context . " ' " ;
}
else {
$sql .= " where domain_name = ' " . $domain_name . " ' " ;
}
$row = $this -> db -> query ( $sql ) -> fetch ();
$domain_uuid = $row [ 'domain_uuid' ];
}
//set values in the database
if ( strlen ( $domain_uuid ) > 0 ) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'domain_uuid' ] = $domain_uuid ;
2016-04-27 21:24:59 +02:00
}
if ( strlen ( $domain_name ) > 0 ) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'domain_name' ] = $domain_name ;
2016-04-27 21:24:59 +02:00
}
//check whether a recording exists
$recording_relative_path = '/' . $_SESSION [ 'domain_name' ] . '/archive/' . $tmp_year . '/' . $tmp_month . '/' . $tmp_day ;
if ( file_exists ( $_SESSION [ 'switch' ][ 'recordings' ][ 'dir' ] . $recording_relative_path . '/' . $uuid . '.wav' )) {
$recording_file = $recording_relative_path . '/' . $uuid . '.wav' ;
}
elseif ( file_exists ( $_SESSION [ 'switch' ][ 'recordings' ][ 'dir' ] . $recording_relative_path . '/' . $uuid . '.mp3' )) {
$recording_file = $recording_relative_path . '/' . $uuid . '.mp3' ;
}
if ( isset ( $recording_file ) && ! empty ( $recording_file )) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'recording_file' ] = $recording_file ;
2016-04-27 21:24:59 +02:00
}
//save to the database in xml format
if ( $_SESSION [ 'cdr' ][ 'format' ][ 'text' ] == " xml " && $_SESSION [ 'cdr' ][ 'storage' ][ 'text' ] == " db " ) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'xml' ] = check_str ( $xml_string );
2016-04-27 21:24:59 +02:00
}
//save to the database in json format
if ( $_SESSION [ 'cdr' ][ 'format' ][ 'text' ] == " json " && $_SESSION [ 'cdr' ][ 'storage' ][ 'text' ] == " db " ) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'json' ] = check_str ( json_encode ( $xml ));
2016-04-27 21:24:59 +02:00
}
//insert the check_str($extension_uuid)
if ( strlen ( $xml -> variables -> extension_uuid ) > 0 ) {
2016-06-12 00:17:35 +02:00
$this -> array [ $key ][ 'extension_uuid' ] = check_str ( urldecode ( $xml -> variables -> extension_uuid ));
2016-04-27 21:24:59 +02:00
}
//insert the values
if ( strlen ( $uuid ) > 0 ) {
if ( $this -> debug ) {
//$time5_insert = microtime(true);
//echo $sql."<br />\n";
}
try {
$error = " false " ;
//$this->db->exec(check_sql($sql));
}
catch ( PDOException $e ) {
$tmp_dir = $_SESSION [ 'switch' ][ 'log' ][ 'dir' ] . '/xml_cdr/failed/' ;
if ( ! file_exists ( $tmp_dir )) {
2016-06-28 23:18:40 +02:00
event_socket_mkdir ( $tmp_dir );
2016-04-27 21:24:59 +02:00
}
if ( $_SESSION [ 'cdr' ][ 'format' ][ 'text' ] == " xml " ) {
$tmp_file = $uuid . '.xml' ;
$fh = fopen ( $tmp_dir . '/' . $tmp_file , 'w' );
fwrite ( $fh , $xml_string );
}
else {
$tmp_file = $uuid . '.json' ;
$fh = fopen ( $tmp_dir . '/' . $tmp_file , 'w' );
fwrite ( $fh , json_encode ( $xml ));
}
fclose ( $fh );
if ( $this -> debug ) {
echo $e -> getMessage ();
}
$error = " true " ;
}
if ( $_SESSION [ 'cdr' ][ 'storage' ][ 'text' ] == " dir " && $error != " true " ) {
if ( strlen ( $uuid ) > 0 ) {
$tmp_time = strtotime ( $start_stamp );
$tmp_year = date ( " Y " , $tmp_time );
$tmp_month = date ( " M " , $tmp_time );
$tmp_day = date ( " d " , $tmp_time );
$tmp_dir = $_SESSION [ 'switch' ][ 'log' ][ 'dir' ] . '/xml_cdr/archive/' . $tmp_year . '/' . $tmp_month . '/' . $tmp_day ;
if ( ! file_exists ( $tmp_dir )) {
2016-06-28 23:18:40 +02:00
event_socket_mkdir ( $tmp_dir );
2016-04-27 21:24:59 +02:00
}
if ( $_SESSION [ 'cdr' ][ 'format' ][ 'text' ] == " xml " ) {
$tmp_file = $uuid . '.xml' ;
$fh = fopen ( $tmp_dir . '/' . $tmp_file , 'w' );
fwrite ( $fh , $xml_string );
}
else {
$tmp_file = $uuid . '.json' ;
$fh = fopen ( $tmp_dir . '/' . $tmp_file , 'w' );
fwrite ( $fh , json_encode ( $xml ));
}
fclose ( $fh );
}
}
unset ( $error );
//if ($this->debug) {
//GLOBAL $insert_time,$insert_count;
//$insert_time+=microtime(true)-$time5_insert; //add this current query.
//$insert_count++;
//}
}
unset ( $sql );
}
/**
* get xml from the filesystem and save it to the database
*/
public function read_files () {
$xml_cdr_dir = $_SESSION [ 'switch' ][ 'log' ][ 'dir' ] . '/xml_cdr' ;
$dir_handle = opendir ( $xml_cdr_dir );
$x = 0 ;
while ( $file = readdir ( $dir_handle )) {
if ( $file != '.' && $file != '..' ) {
if ( ! is_dir ( $xml_cdr_dir . '/' . $file ) ) {
//get the leg of the call and the file prefix
if ( substr ( $file , 0 , 2 ) == " a_ " ) {
$leg = " a " ;
$file_prefix = substr ( $file , 2 , 1 );
}
else {
$leg = " b " ;
$file_prefix = substr ( $file , 0 , 1 );
}
2016-05-02 01:44:53 +02:00
//set the limit
if ( isset ( $_SERVER [ " argv " ][ 1 ]) && is_numeric ( $_SERVER [ " argv " ][ 1 ])) {
$limit = $_SERVER [ " argv " ][ 1 ];
}
else {
$limit = 1 ;
}
//filter for specific files based on the file prefix
if ( isset ( $_SERVER [ " argv " ][ 2 ])) {
if ( strpos ( $_SERVER [ " argv " ][ 2 ], $file_prefix ) !== FALSE ) {
$import = true ;
}
else {
$import = false ;
}
}
else {
$import = true ;
}
//import the call detail record
if ( $import ) {
//get the xml cdr string
$xml_string = file_get_contents ( $xml_cdr_dir . '/' . $file );
//parse the xml and insert the data into the db
$this -> xml_array ( $x , $leg , $xml_string );
2016-04-27 21:24:59 +02:00
2016-05-02 01:44:53 +02:00
//delete the file after it has been imported
unlink ( $xml_cdr_dir . '/' . $file );
}
2016-04-27 21:24:59 +02:00
2016-05-02 01:44:53 +02:00
//increment the value
if ( $import ) {
$x ++ ;
}
2016-04-27 21:24:59 +02:00
2016-05-02 01:44:53 +02:00
//if limit exceeded exit the loop
if ( $limit == $x ) {
//echo "limit: $limit count: $x if\n";
break ;
}
2016-04-27 21:24:59 +02:00
}
}
}
2016-04-30 08:33:35 +02:00
$this -> save ();
2016-04-27 21:24:59 +02:00
closedir ( $dir_handle );
}
//$this->read_files();
/**
* read the call detail records from the http post
*/
public function post () {
if ( isset ( $_POST [ " cdr " ])) {
//debug method
if ( $this -> debug ){
2016-04-28 07:51:53 +02:00
print_r ( $_POST [ " cdr " ]);
2016-04-27 21:24:59 +02:00
}
//authentication for xml cdr http post
if ( ! defined ( 'STDIN' )) {
if ( $_SESSION [ " cdr " ][ " http_enabled " ][ " boolean " ] == " true " && strlen ( $_SESSION [ " xml_cdr " ][ " username " ]) == 0 ) {
//get the contents of xml_cdr.conf.xml
$conf_xml_string = file_get_contents ( $_SESSION [ 'switch' ][ 'conf' ][ 'dir' ] . '/autoload_configs/xml_cdr.conf.xml' );
//parse the xml to get the call detail record info
try {
$conf_xml = simplexml_load_string ( $conf_xml_string );
}
catch ( Exception $e ) {
echo $e -> getMessage ();
}
2016-04-30 08:33:35 +02:00
if ( isset ( $conf_xml -> settings -> param )) foreach ( $conf_xml -> settings -> param as $row ) {
2016-04-27 21:24:59 +02:00
if ( $row -> attributes () -> name == " cred " ) {
$auth_array = explode ( " : " , $row -> attributes () -> value );
//echo "username: ".$auth_array[0]."<br />\n";
//echo "password: ".$auth_array[1]."<br />\n";
}
if ( $row -> attributes () -> name == " url " ) {
//check name is equal to url
}
}
}
}
//if http enabled is set to false then deny access
if ( ! defined ( 'STDIN' )) {
if ( $_SESSION [ " cdr " ][ " http_enabled " ][ " boolean " ] == " false " ) {
echo " access denied<br /> \n " ;
return ;
}
}
//check for the correct username and password
if ( ! defined ( 'STDIN' )) {
if ( $_SESSION [ " cdr " ][ " http_enabled " ][ " boolean " ] == " true " ) {
if ( $auth_array [ 0 ] == $_SERVER [ " PHP_AUTH_USER " ] && $auth_array [ 1 ] == $_SERVER [ " PHP_AUTH_PW " ]) {
//echo "access granted<br />\n";
$_SESSION [ " xml_cdr " ][ " username " ] = $auth_array [ 0 ];
$_SESSION [ " xml_cdr " ][ " password " ] = $auth_array [ 1 ];
}
else {
echo " access denied<br /> \n " ;
return ;
}
}
}
//loop through all attribues
//foreach($xml->settings->param[1]->attributes() as $a => $b) {
// echo $a,'="',$b,"\"<br />\n";
//}
//get the http post variable
$xml_string = trim ( $_POST [ " cdr " ]);
//get the leg of the call
if ( substr ( $_REQUEST [ 'uuid' ], 0 , 2 ) == " a_ " ) {
$leg = " a " ;
}
else {
$leg = " b " ;
}
//log the xml cdr
//xml_cdr_log("process cdr via post\n");
//parse the xml and insert the data into the database
2016-04-30 08:33:35 +02:00
$this -> xml_array ( 0 , $leg , $xml_string );
$this -> save ();
2016-04-27 21:24:59 +02:00
}
}
//$this->post();
2016-06-06 01:19:06 +02:00
/**
* user summary returns an array
*/
public function user_summary () {
2016-06-15 06:44:34 +02:00
//build the date range
if ( strlen ( $this -> start_stamp_begin ) > 0 || strlen ( $this -> start_stamp_end ) > 0 ) {
unset ( $this -> quick_select );
if ( strlen ( $this -> start_stamp_begin ) > 0 && strlen ( $this -> start_stamp_end ) > 0 ) {
$sql_date_range .= " and start_stamp between ' " . $this -> start_stamp_begin . " :00.000' and ' " . $this -> start_stamp_end . " :59.999' \n " ;
2016-06-06 01:19:06 +02:00
}
else {
2016-12-30 18:54:33 +01:00
if ( strlen ( $this -> start_stamp_begin ) > 0 ) { $sql_date_range .= " AND start_stamp >= ' " . $this -> start_stamp_begin . " :00.000' \n " ; }
if ( strlen ( $this -> start_stamp_end ) > 0 ) { $sql_date_range .= " AND start_stamp <= ' " . $this -> start_stamp_end . " :59.999' \n " ; }
2016-06-06 01:19:06 +02:00
}
}
2016-06-15 06:44:34 +02:00
else {
switch ( $this -> quick_select ) {
2016-12-30 18:54:33 +01:00
case 1 : $sql_date_range .= " AND start_stamp >= ' " . date ( 'Y-m-d H:i:s.000' , strtotime ( " -1 week " )) . " ' \n " ; break ; //last 7 days
case 2 : $sql_date_range .= " AND start_stamp >= ' " . date ( 'Y-m-d H:i:s.000' , strtotime ( " -1 hour " )) . " ' \n " ; break ; //last hour
case 3 : $sql_date_range .= " AND start_stamp >= ' " . date ( 'Y-m-d' ) . " " . " 00:00:00.000' \n " ; break ; //today
case 4 : $sql_date_range .= " AND start_stamp between ' " . date ( 'Y-m-d' , strtotime ( " -1 day " )) . " " . " 00:00:00.000' and ' " . date ( 'Y-m-d' , strtotime ( " -1 day " )) . " " . " 23:59:59.999' \n " ; break ; //yesterday
case 5 : $sql_date_range .= " AND start_stamp >= ' " . date ( 'Y-m-d' , strtotime ( " this week " )) . " " . " 00:00:00.000' \n " ; break ; //this week
case 6 : $sql_date_range .= " AND start_stamp >= ' " . date ( 'Y-m-' ) . " 01 " . " 00:00:00.000' \n " ; break ; //this month
case 7 : $sql_date_range .= " AND start_stamp >= ' " . date ( 'Y-' ) . " 01-01 " . " 00:00:00.000' \n " ; break ; //this year
2016-06-06 01:19:06 +02:00
}
}
2016-06-15 06:44:34 +02:00
//calculate the summary data
$sql = " SELECT \n " ;
$sql .= " e.domain_uuid, \n " ;
$sql .= " d.domain_name, \n " ;
$sql .= " e.extension, \n " ;
$sql .= " e.number_alias, \n " ;
2016-12-30 18:54:33 +01:00
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER( \n " ;
$sql .= " WHERE c.domain_uuid = e.domain_uuid \n " ;
$sql .= " AND (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL and ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.answer_stamp IS NOT NULL \n " ;
$sql .= " and \n " ;
$sql .= " c.bridge_uuid IS NOT NULL) \n " ;
2016-06-15 06:44:34 +02:00
if ( $this -> include_internal ) {
2016-12-30 18:54:33 +01:00
$sql .= " AND (direction = 'inbound' OR direction = 'local')) \n " ;
2016-06-06 01:19:06 +02:00
}
else {
2016-12-30 18:54:33 +01:00
$sql .= " AND direction = 'inbound') \n " ;
}
$sql .= " AS answered, \n " ;
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.answer_stamp IS NULL \n " ;
$sql .= " AND \n " ;
$sql .= " c.bridge_uuid IS NULL) \n " ;
if ( $this -> include_internal ) {
$sql .= " AND (direction = 'inbound' OR direction = 'outbound')) " ;
} else {
$sql .= " AND direction = 'inbound') " ;
}
$sql .= " AS missed, \n " ;
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
$sql .= " AND c.hangup_cause = 'NO_ANSWER' \n " ;
2016-12-29 20:59:52 +01:00
if ( $this -> include_internal ) {
2016-12-30 18:54:33 +01:00
$sql .= " AND (direction = 'inbound' OR direction = 'local') \n " ;
}
else {
$sql .= " AND direction = 'inbound' \n " ;
}
$sql .= " ) AS no_answer, \n " ;
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
$sql .= " AND \n " ;
$sql .= " c.hangup_cause = 'USER_BUSY' \n " ;
if ( $this -> include_internal ) {
$sql .= " AND (direction = 'inbound' OR direction = 'local')) \n " ;
2016-06-15 06:44:34 +02:00
}
else {
2016-12-30 18:54:33 +01:00
$sql .= " AND direction = 'inbound') \n " ;
}
$sql .= " AS busy, \n " ;
$sql .= " SUM(c.billsec) \n " ;
$sql .= " FILTER ( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
if ( $this -> include_internal ) {
$sql .= " AND (direction = 'inbound' OR 'direction = 'outbound') \n " ;
}
$sql .= " ) / \n " ;
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER ( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
if ( $this -> include_internal ) {
$sql .= " AND (direction = 'inbound' OR 'direction = 'outbound') \n " ;
}
$sql .= " ) AS aloc, \n " ;
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER ( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
if ( $this -> include_internal ) {
$sql .= " AND (direction = 'inbound' OR direction = 'local')) \n " ;
}
else {
$sql .= " AND direction = 'inbound') \n " ;
}
$sql .= " AS inbound_calls, \n " ;
$sql .= " SUM(c.billsec) \n " ;
$sql .= " FILTER ( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
if ( $this -> include_internal ) {
$sql .= " AND (direction = 'inbound' OR direction = 'local')) \n " ;
}
else {
$sql .= " AND direction = 'inbound') \n " ;
}
$sql .= " AS inbound_duration, \n " ;
$sql .= " COUNT(*) \n " ;
$sql .= " FILTER ( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
$sql .= " AND \n " ;
$sql .= " c.direction = 'outbound') \n " ;
$sql .= " AS outbound_calls, \n " ;
$sql .= " SUM(c.billsec) \n " ;
$sql .= " FILTER ( \n " ;
$sql .= " WHERE (( \n " ;
$sql .= " c.caller_id_number = e.extension \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.extension) \n " ;
$sql .= " OR ( \n " ;
$sql .= " e.number_alias IS NOT NULL \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.caller_id_number = e.number_alias \n " ;
$sql .= " OR \n " ;
$sql .= " c.destination_number = e.number_alias))) \n " ;
$sql .= " AND ( \n " ;
$sql .= " c.direction = 'outbound')) \n " ;
$sql .= " AS outbound_duration, \n " ;
$sql .= " e.description \n " ;
$sql .= " FROM v_extensions AS e, v_domains AS d, \n " ;
$sql .= " ( SELECT \n " ;
$sql .= " domain_uuid, \n " ;
$sql .= " caller_id_number, \n " ;
$sql .= " destination_number, \n " ;
$sql .= " answer_stamp, \n " ;
$sql .= " bridge_uuid, \n " ;
$sql .= " direction, \n " ;
$sql .= " start_stamp, \n " ;
$sql .= " hangup_cause, \n " ;
$sql .= " billsec \n " ;
$sql .= " FROM v_xml_cdr \n " ;
$sql .= " WHERE domain_uuid = ' " . $this -> domain_uuid . " ' \n " ;
$sql .= $sql_date_range ;
$sql .= " ) AS c \n " ;
$sql .= " WHERE \n " ;
$sql .= " d.domain_uuid = e.domain_uuid \n " ;
if ( ! ( $_GET [ 'showall' ] && permission_exists ( 'xml_cdr_all' ))) {
$sql .= " AND e.domain_uuid = ' " . $this -> domain_uuid . " ' \n " ;
}
$sql .= " GROUP BY e.extension, e.domain_uuid, d.domain_uuid, e.number_alias, e.description \n " ;
$sql .= " ORDER BY extension ASC \n " ;
2016-06-06 01:19:06 +02:00
$prep_statement = $this -> db -> prepare ( check_sql ( $sql ));
$prep_statement -> execute ();
2016-06-15 06:44:34 +02:00
$summary = $prep_statement -> fetchAll ( PDO :: FETCH_NAMED );
2016-06-06 01:19:06 +02:00
//return the array
return $summary ;
}
2016-04-27 21:24:59 +02:00
} //end scripts class
}
/*
//example use
$cdr = new xml_cdr ;
2016-04-30 08:33:35 +02:00
$cdr -> read_files ();
2016-04-27 21:24:59 +02:00
*/
2016-06-06 05:53:28 +02:00
?>