Issues (4511)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

freeswitch/fs/lib/astpp.cdr.php (23 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
###############################################################################
3
# ASTPP - Open Source VoIP Billing Solution
4
#
5
# Copyright (C) 2016 iNextrix Technologies Pvt. Ltd.
6
# Samir Doshi <[email protected]>
7
# ASTPP Version 3.0 and above
8
# License https://www.gnu.org/licenses/agpl-3.0.html
9
#
10
# This program is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU Affero General Public License as
12
# published by the Free Software Foundation, either version 3 of the
13
# License, or (at your option) any later version.
14
# 
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU Affero General Public License for more details.
19
# 
20
# You should have received a copy of the GNU Affero General Public License
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
###############################################################################
23
24
//Process CDR 
25
function process_cdr($data, $db, $logger, $decimal_points)
26
{
27
	//$logger->log(print_r($data,true));//exit;
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
28
29
	//Initializing variables 
30
	$origination_rate = array();
31
	$termination_rate = array();
32
33
	//FS CDR variables 
34
	$dataVariable = $data['variables'];
35
36
	//FS CDR Call flow variables 
37
	$dataCallflow = $data['callflow'];
38
39
	//Get account id
40
	$accountid = isset($dataVariable['account_id']) ? $dataVariable['account_id'] : '0';
41
42
	//Get caller id name and number 
43
	$dataVariable['effective_caller_id_name'] = (isset($dataVariable['effective_caller_id_name'])) ? $dataVariable['effective_caller_id_name'] : $dataCallflow['caller_profile']['caller_id_name'];
44
	$dataVariable['effective_caller_id_number'] = (isset($dataVariable['effective_caller_id_number'])) ? $dataVariable['effective_caller_id_number'] : $dataCallflow['caller_profile']['caller_id_number'];
45
46
47
	if ($dataVariable['billsec'] == 0 && $dataVariable['hangup_cause'] == 'NORMAL_CLEARING')
48
	{
49
		$hangup_cause = isset($dataVariable['last_bridge_hangup_cause'])?$dataVariable['last_bridge_hangup_cause']:$dataVariable['hangup_cause'];
50
	}else{
51
		$hangup_cause = $dataVariable['hangup_cause'];
52
	}   
53
54
	if ($dataVariable['error_cdr'] == '1')
55
	{
56
		//Get actual hangup cause 
57
		$hangup_cause= (isset($dataVariable['error_cdr'])) ? $dataVariable['last_bridge_hangup_cause'] : (isset($dataVariable['last_bridge_hangup_cause'])?$dataVariable['last_bridge_hangup_cause']:$dataVariable['hangup_cause']); 
58
	}
59
60
	/*#### PATCH FOR ONE WAY AUDIO ####*/
61
	if ($hangup_cause == "NORMAL_UNSPECIFIED" && $dataVariable['billsec'] > 0)
62
	{
63
		$hangup_cause = "NORMAL_CLEARING";
64
	}
65
	/*#### ************* END *************####*/
66
67
	//Don't thing this will be useful anytime. Need to remove it after testing. 
68
	if($hangup_cause == "NONE")
69
	{
70
		$hangup_cause = $dataVariable['current_application_data'];
71
	}
72
73
	$dataVariable['hangup_cause'] = $hangup_cause;
74
75
	/*if ( ($dataVariable['hangup_cause'] != 'NORMAL_CLEARING') && ($dataVariable['hangup_cause'] != 'ALLOTTED_TIMEOUT')) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
76
	  	$dataVariable['billsec'] = 0;
77
	}*/
78
79
	$account_type = (isset($dataVariable['entity_id'])) ? $dataVariable['entity_id'] : '0';
80
	$parentid = isset($dataVariable['parent_id']) ? $dataVariable['parent_id'] : '0';
81
	$parent_cost = 0;
82
	$cost = 0;
83
	$dataVariable['package_id'] = 0;         
84
	$actual_duration = $dataVariable['billsec'];
85
	$dataVariable['calltype'] = isset($dataVariable['calltype']) ? $dataVariable['calltype'] : "STANDARD";
86
	$actual_calltype = $dataVariable['calltype'];
87
	
88
	//Normalize origination and termination rates array 		   
89
	if(isset($dataVariable['origination_rates']))
90
	   $origination_rate = normalize_origination_rate($dataVariable['origination_rates']);
91
	if(isset($dataVariable['termination_rates']))
92
	   $termination_rate = normalize_rate($dataVariable['termination_rates']);
93
94
	//If receiver account id found then explicitly set call direction and call type 
95
	if(isset($dataVariable['receiver_accid']))
96
	{
97
		$dataVariable['call_direction'] = "outbound";
98
		$dataVariable['calltype'] = "STANDARD";
99
	}
100
101
	//Check if cusotmer have any package seconds left to use
102 View Code Duplication
	if ($actual_duration > 0)			
103
	{
104
			$package_array = package_calculation( $dataVariable['effective_destination_number'],$origination_rate[$accountid]['RATEGROUP'],$actual_duration,$dataVariable['call_direction'],$accountid,$db,$logger);
105
			if(!empty($package_array))
106
			{
107
				$dataVariable['calltype'] = "FREE";
108
				$dataVariable['package_id']= $package_array['package_id'];
109
			}
110
	}
111
	
112
	//Calculate debit of customer call 			
113
	$debit = calc_cost($dataVariable,$origination_rate[$accountid],$logger,$decimal_points);
114
115
	//Calculate cost for customer call for provider
116
	$provider_cost = calc_cost($dataVariable,$termination_rate,$logger,$decimal_points);
117
118
	//Calculate parent cost if customer have any parent 
119
	$parent_cost = ($parentid > 0) ? calc_cost($dataVariable,$origination_rate[$parentid],$logger,$decimal_points) : $provider_cost;
120
	$logger->log("Debit :".$debit ." Cost : ".$cost ." Provider Cost : ".$parent_cost);
121
    
122
	//Initialize final cost variable to use for billing
123
	$cost = ($parent_cost > 0) ? $parent_cost : $provider_cost;    
124
	
125
	//Outbound call entry for all type of calls 
126
	$logger->log("*********************** OUTBOUND CALL ENTRY START *************");
127
128
	$cdr_string = get_cdr_string($dataVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,$debit,$cost,$logger);
129
130
	$query = "INSERT INTO cdrs (uniqueid,accountid,type,callerid,callednum,billseconds,trunk_id,trunkip,callerip,disposition,callstart,debit,cost,provider_id,pricelist_id,package_id,pattern,notes,rate_cost,reseller_id,reseller_code,reseller_code_destination,reseller_cost,provider_code,provider_code_destination,provider_cost,provider_call_cost,call_direction,calltype,profile_start_stamp,answer_stamp,bridge_stamp,progress_stamp,progress_media_stamp,end_stamp,billmsec,answermsec,waitmsec,progress_mediamsec,flow_billmsec)  values ($cdr_string)";
131
	$logger->log($query);
132
	$db->run($query);
133
	
134
	//Update customer balance
135 View Code Duplication
	if($debit > 0 && $dataVariable['calltype'] != "FREE")
136
	{
137
		update_balance($accountid, $debit, 0, $logger, $db);
138
	}
139
140
	//Update parent or provider balance
141
	if($parent_cost > 0){
142
		update_balance($termination_rate['PROVIDER'], ($parent_cost * -1), 3, $logger, $db);
143
	}
144
145
	//Resellers CDR entry
146
	$flag_parent = false;
147
	insert_parent_data($dataVariable,$actual_calltype,$parentid,$origination_rate,$actual_duration,$provider_cost,$flag_parent,$logger,$db,$decimal_points);
148
149
	$logger->log("*********************** OUTBOUND CALL ENTRY END *************");
150
151
   
152
	//************ ADDING EXTRA ENTRY For local/DID Inbound call ****************************
153
	$receiver_parentid=0;
154
	if(isset($dataVariable['receiver_accid']) && $dataVariable['receiver_accid'] != "")
155
	{
156
		$logger->log("*********************** EXTRA ENTRY SECTION FOR BILLING START *************");            
157
158
		//Explicitly set call direction and call type 
159
		$dataVariable['call_direction'] = "inbound";
160
		$dataVariable['calltype'] = "DID";
161
162
    //Override variables if call for DID PSTN
163
    if(isset($dataVariable['caller_did_account_id']))
164
    {
165
        $dataVariable['receiver_accid'] = $dataVariable['caller_did_account_id'];
166
    		$dataVariable['call_direction'] = "outbound";
167
        $dataVariable['calltype'] = "STANDARD";
168
	      $dataVariable['effective_destination_number']=$dataVariable['sip_to_user'];
169
        unset($termination_rate);
170
        unset($provider_cost);
171
     }
172
173
        
174
175
		//Get call receiver account information 
176
		$receiver_carddata = get_accounts($dataVariable['receiver_accid'],$logger,$db);
177
		$receiver_parentid = $receiver_carddata['reseller_id'];
178
179
		//For additional cdr entry of receiver
180
		insert_extra_receiver_entry($dataVariable,$origination_rate,$termination_rate,$account_type,$actual_duration,$provider_cost,$receiver_parentid,$flag_parent,$dataVariable['receiver_accid'],$logger,$db,$decimal_points);
181
182
		$flag_parent = true;
183
		$dataVariable['uuid'] = $dataVariable['uuid'].$dataVariable['calltype']."_".$receiver_parentid;
184
185
		//Insert parent reseller cdr
186
		insert_parent_data($dataVariable,$actual_calltype,$receiver_parentid,$origination_rate,$actual_duration,$provider_cost,$flag_parent,$logger,$db,$decimal_points);
187
		$logger->log("*********************** EXTRA ENTRY SECTION FOR BILLING END *************");            
188
	}
189
	//*****************************************************************************************
190
	$logger->log("*************************** CDR ends ********************************");
191
}
192
193
//Insert parent resellers cdr
194
/**
195
 * @param string $provider_cost
196
 * @param boolean $flag_parent
197
 */
198
function insert_parent_data($dataVariable,$actual_calltype,$parentid,$origination_rate,$actual_duration,$provider_cost,$flag_parent,$logger,$db,$decimal_points)
199
{
200
	while($parentid > 0 )
201
	{
202
		$logger->log("*************** IN PARENT DATA SECTION ********");
203
		$dataVariable['calltype'] = $actual_calltype;
204
		$carddata = get_accounts($parentid,$logger,$db);
205
		$accountid = $carddata['id'];
206
207
		$debit = calc_cost($dataVariable,$origination_rate[$accountid],$logger,$decimal_points);
208
209
		//If receiver account id found then explicitly set call direction and call type
210
		/*if(isset($dataVariable['receiver_accid']))
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
211
        {
212
            $dataVariable['call_direction'] = "outbound";
213
            $dataVariable['calltype'] = "STANDARD";
214
        }*/
215
216
		//Check if reseller have any package seconds left to use        
217 View Code Duplication
		if ($actual_duration > 0)		{
218
			$package_array = package_calculation( $dataVariable['effective_destination_number'],$origination_rate[$accountid]['RATEGROUP'],$actual_duration,$dataVariable['call_direction'],$accountid,$db,$logger);
219
			if(!empty($package_array))
220
			{
221
				$dataVariable['calltype'] = "FREE";
222
				$dataVariable['package_id']= $package_array['package_id'];
223
			}
224
		}	
225
226
		//Get parent id for cost calculation 
227
		$parentid = $carddata['reseller_id'];
228
		$parent_cost = ($parentid > 0) ? calc_cost($dataVariable,$origination_rate[$parentid],$logger,$decimal_points) : $provider_cost;
229
		$cost = ($parent_cost > 0) ? $parent_cost : $provider_cost;
230
	
231
		if(isset($dataVariable['receiver_accid']) && $dataVariable['receiver_accid'] != "" && $flag_parent == true)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
232
		{
233
			$logger->log("********* IN RESELLER FOR RECEIVER ENTRY START ******");
234
			$flag_parent = true;
235
			insert_extra_receiver_entry($dataVariable,$origination_rate,$termination_rate,$account_type,$actual_duration,$provider_cost,$parentid,$flag_parent,$accountid,$logger,$db,$decimal_points);
0 ignored issues
show
The variable $termination_rate does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $account_type does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
236
			$logger->log("********* IN RESELLER FOR RECEIVER ENTRY END ******");
237
			//return true;	
238
239
		} else{
240
241
			$cdr_string = get_reseller_cdr_string($dataVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,$debit,$cost);	
242
243
 			$query = "INSERT INTO reseller_cdrs (uniqueid,accountid,callerid,callednum,billseconds,disposition,callstart,debit,cost,pricelist_id,package_id,pattern,notes,rate_cost,
244
		reseller_id,reseller_code,reseller_code_destination,reseller_cost,call_direction,calltype) values ($cdr_string)";
245
			$logger->log($query);
246
			$db->run($query);
247
248
			//Update reseller balance
249 View Code Duplication
			if ($debit > 0 && $dataVariable['calltype'] != "FREE") {
250
				update_balance($accountid, $debit, 0, $logger, $db);
251
			}
252
		}
253
		//return true;
254
	}
255
	return true;
256
}
257
258
//Insert callee cdr entry for DID calls
259
/**
260
 * @param boolean $flag_parent
261
 */
262
function insert_extra_receiver_entry($dataVariable,$origination_rate,$termination_rate,$account_type,$actual_duration,$provider_cost,$parentid,$flag_parent,$accountid,$logger,$db,$decimal_points)
263
{
264
		$localVariable = $dataVariable;
265
		$localVariable['call_direction'] = "inbound";
266
		$localVariable['uuid'] = $localVariable['uuid'].$dataVariable['calltype']."_".$accountid;
267
		
268
		if($dataVariable['calltype'] == "LOCAL")
269
		{
270
			$origination_rate[$accountid]['CODE'] = $dataVariable['effective_destination_number'];
271
			$origination_rate[$accountid]['DESTINATION'] = $dataVariable['calltype'];
272 View Code Duplication
			if($flag_parent == false){
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
273
				$cdr_string = get_cdr_string($localVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,0,0,$logger);
274
			} else{
275
				$cdr_string = get_reseller_cdr_string($dataVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,$debit,$cost);
0 ignored issues
show
The variable $debit seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
The variable $cost does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
276
			}
277
		} else{
278
279
			$origination_rate_did = normalize_origination_rate($dataVariable['origination_rates_did']);
280
			$debit = calc_cost($dataVariable,$origination_rate_did[$accountid],$logger,$decimal_points);
281
282 View Code Duplication
			if($flag_parent == false){
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
283
				
284
				$cdr_string = get_cdr_string($localVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate_did,$provider_cost,$parentid,$debit,0,$logger);
285
			} else{
286
				$cdr_string = get_reseller_cdr_string($dataVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,$debit,$cost);
287
			}
288
		}
289
	  
290
		if($flag_parent == false)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
291
		{
292
			$query = "INSERT INTO cdrs(uniqueid,accountid,type,callerid,callednum,billseconds,trunk_id,trunkip,callerip,disposition,callstart,debit,cost,provider_id,pricelist_id,package_id,pattern,notes,rate_cost,reseller_id,reseller_code,reseller_code_destination,reseller_cost,provider_code,provider_code_destination,provider_cost,provider_call_cost,call_direction,calltype,profile_start_stamp,answer_stamp,bridge_stamp,progress_stamp,progress_media_stamp,end_stamp,billmsec,answermsec,waitmsec,progress_mediamsec,flow_billmsec) values ($cdr_string)";
293
		} else{
294
			$query = "INSERT INTO reseller_cdrs (uniqueid,accountid,callerid,callednum,billseconds,disposition,callstart,debit,cost,pricelist_id,package_id,pattern,notes,rate_cost,
295
	reseller_id,reseller_code,reseller_code_destination,reseller_cost,call_direction,calltype) values ($cdr_string)";
296
		}
297
298
		$logger->log($query);
299
		$db->run($query);	
300
301 View Code Duplication
		if ($debit > 0 && ($dataVariable['calltype'] != "FREE" && $dataVariable['calltype'] != "LOCAL"))
302
		{
303
			update_balance($accountid, $debit, 0, $logger, $db);
0 ignored issues
show
The variable $debit does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
304
		}
305
		return true;
306
}
307
308
//Generate CDR string for insert query for customer.
309
function get_cdr_string($dataVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,$debit,$cost,$logger)
0 ignored issues
show
The parameter $logger is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
310
{
311
   	$dataVariable['calltype'] = ($dataVariable['calltype'] == 'DID-LOCAL' || $dataVariable['calltype'] == 'SIP-DID' || $dataVariable['calltype'] == 'OTHER')?"DID":$dataVariable['calltype'];
312
		$callerIdNumber = isset($dataVariable['effective_caller_id_number']) && !empty($dataVariable['effective_caller_id_number'])? $dataVariable['effective_caller_id_number'] :$dataVariable['caller_id'];
313
		return  $cdr_string = "'".($dataVariable['uuid'])."','".$accountid."','".$account_type."','".(urldecode($callerIdNumber))."','".($dataVariable['effective_destination_number'])."','".$actual_duration."',".(($termination_rate['TRUNK']) ? $termination_rate['TRUNK'] : '0').",".(($dataVariable['sip_via_host']) ? "'".$dataVariable['sip_via_host']."'" : '""').",".(($dataVariable['sip_contact_host']) ? "'".$dataVariable['sip_contact_host']."'" : '""').",'".($dataVariable['hangup_cause'])."','".urldecode($dataVariable['callstart'])."','".$debit."','".$cost."',".(($termination_rate['PROVIDER']) ? $termination_rate['PROVIDER'] : '0').",'".$origination_rate[$accountid]['RATEGROUP']."','".$dataVariable['package_id']."','".($origination_rate[$accountid]['CODE'])."',".(($origination_rate[$accountid]['DESTINATION']) ? "'".htmlentities($origination_rate[$accountid]['DESTINATION'],ENT_COMPAT, 'UTF-8')."'" : "'".''."'").",".(($origination_rate[$accountid]['COST']) ? "'".$origination_rate[$accountid]['COST']."'" : "'".'0'."'").",'".$parentid."',".(($origination_rate[$parentid]['CODE'] ) ? "'".$origination_rate[$parentid]['CODE']."'" : "'".'0'."'").",".(($origination_rate[$parentid]['DESTINATION']) ?  "'".$origination_rate[$parentid]['DESTINATION']."'" : "'".''."'").",".(($origination_rate[$parentid]['COST']) ?  "'".$origination_rate[$parentid]['COST']."'" :  '0').",".(($termination_rate['CODE']) ? "'".$termination_rate['CODE']."'" : "'".''."'" ).",".(($termination_rate['DESTINATION']) ? "'".$termination_rate['DESTINATION']."'" : "'".''."'").",".(($termination_rate['COST']) ? "'".$termination_rate['COST']."'" : '0').",'".$provider_cost."',".(($dataVariable['call_direction']) ? "'".$dataVariable['call_direction']."'" : "'internal'").",'".($dataVariable['calltype'])."','".convert_to_gmt(urldecode($dataVariable['profile_start_stamp']))."','".convert_to_gmt(urldecode($dataVariable['answer_stamp']))."','".convert_to_gmt(urldecode($dataVariable['bridge_stamp']))."','".convert_to_gmt(urldecode(@$dataVariable['progress_stamp']))."','".convert_to_gmt(urldecode(@$dataVariable['progress_media_stamp']))."','".convert_to_gmt(urldecode($dataVariable['end_stamp']))."',".$dataVariable['billmsec'].",'".$dataVariable['answermsec']."','".$dataVariable['waitmsec']."','".$dataVariable['progress_mediamsec']."','".$dataVariable['flow_billmsec']."'";
314
}
315
316
//Generate CDR string for insert query for reseller
317
function get_reseller_cdr_string($dataVariable,$accountid,$account_type,$actual_duration,$termination_rate,$origination_rate,$provider_cost,$parentid,$debit,$cost)
0 ignored issues
show
The parameter $account_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $termination_rate is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $provider_cost is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
318
{
319
        $dataVariable['calltype'] = ($dataVariable['calltype'] == 'DID-LOCAL' || $dataVariable['calltype'] == 'SIP-DID' || $dataVariable['calltype'] == 'OTHER')?"DID":$dataVariable['calltype'];
320
	$callerIdNumber = isset($dataVariable['effective_caller_id_number']) && !empty($dataVariable['effective_caller_id_number'])? $dataVariable['effective_caller_id_number'] :$dataVariable['caller_id'];
321
	
322
	return $cdr_string = "'".($dataVariable['uuid'])."','".$accountid."','".(urldecode($callerIdNumber))."','".($dataVariable['effective_destination_number'])."','".$actual_duration."','".($dataVariable['hangup_cause'])."','".convert_to_gmt(urldecode($dataVariable['callstart']))."','".$debit."','".$cost."','".$origination_rate[$accountid]['RATEGROUP']."','".$dataVariable['package_id']."','".($origination_rate[$accountid]['CODE'])."',".(($origination_rate[$accountid]['DESTINATION']) ? "'".$origination_rate[$accountid]['DESTINATION']."'" : "'".''."'").",".(($origination_rate[$accountid]['COST']) ? "'".$origination_rate[$accountid]['COST']."'" : "'".'0'."'").",'".$parentid."',".(($origination_rate[$parentid]['CODE'] ) ? "'".$origination_rate[$parentid]['CODE']."'" : "'".'0'."'").",".(($origination_rate[$parentid]['DESTINATION']) ?  "'".$origination_rate[$parentid]['DESTINATION']."'" : "'".''."'").",".(($origination_rate[$parentid]['COST']) ?  "'".$origination_rate[$parentid]['COST']."'" :  '0').",".(($dataVariable['call_direction']) ? "'".$dataVariable['call_direction']."'" : "'internal'").",'".($dataVariable['calltype'])."'";
323
}
324
325
//Update user balance
326
/**
327
 * @param integer $entity_id
328
 */
329 View Code Duplication
function update_balance($user_id, $amount, $entity_id, $logger, $db) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
330
    $math_sign = ($entity_id == 0 || $entity_id == 1) ? '-' : '+';
331
    $query = "UPDATE accounts SET balance=balance-" . $amount . " WHERE id=" . $user_id;
332
    $logger->log("Balance update : " . $query);
333
    $db->run($query);
334
}
335
336
//Normalize rate string which we are getting from dialplan
337
function normalize_rate($dataVariable)
338
{
339
	$rates = urldecode($dataVariable);
340
    $data = explode("|", $rates);
341
342
	$newarray = array();
343
    foreach ($data as $key => $value)
344
    {
345
            $data1 = explode(":", $value);
346
            foreach ($data1 as $newkey => $newvalue)
347
            {
348
                    $newarray[$data1[0]] = $data1[$newkey];
349
            }
350
    }
351
	return $newarray;
352
}
353
354
//Normalize originaion rate string which we are getting from dialplan
355
function normalize_origination_rate($dataVariable)
356
{
357
	$rates = urldecode($dataVariable);
358
	$data = explode("|", $rates);
359
	$newarray = array();
360
	$newarray1 = array();	
361
	foreach ($data as $key => $value)
362
	{
363
		$data1 = explode(":", $value);
364
		foreach ($data1 as $newkey => $newvalue)
365
		{
366
			$newarray[$data1[0]] = $data1[$newkey];
367
			if ($newvalue == "ACCID") {
368
				$newarray1[$data1[1]] = $newarray;
369
			}
370
		}
371
	}
372
		return $newarray1;
373
}
374
375
// Calculate cost for billing 
376
function calc_cost($dataVariable, $rates, $logger, $decimal_points)
377
{
378
	//$logger->log(print_r($rates,true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
379
	$duration = $dataVariable['billsec'];
380
	$call_cost = 0;  
381
	$duration -= $rates['INCLUDEDSECONDS'];
382
	if ($duration > 0 && ($dataVariable['hangup_cause'] == 'NORMAL_CLEARING' || $dataVariable['hangup_cause'] == 'ALLOTTED_TIMEOUT')) {
383
384
			$rates['INC'] = ($rates['INC'] == 0) ? 1 : $rates['INC'];
385
			$call_cost = $rates['CONNECTIONCOST'];
386
			$call_cost += ($rates['INITIALBLOCK'] * $rates['COST']) / 60;
387
			$billseconds = $duration - $rates['INITIALBLOCK'];
388
    
389
			if ($billseconds > 0)
390
			{
391
				$call_cost += (ceil($billseconds/$rates['INC'])*$rates['INC'])*($rates['COST']/60);
392
			}
393
	}
394
	$call_cost = number_format($call_cost,$decimal_points);
395
	$logger->log("Return cost ".$call_cost);
396
	return $call_cost;
397
}
398
399
// get intial package information
400
function package_calculation($destination_number,$pricelist_id,$duration,$call_direction,$accountid,$db,$logger)
401
{
402
	$package_array = array();
403
	$custom_destination = number_loop($destination_number,"patterns",$db);
404
405
	$query = "SELECT * FROM packages  as P inner join package_patterns as PKGPTR on P.id = PKGPTR.package_id WHERE ".$custom_destination." AND status = 0 AND pricelist_id = ".$pricelist_id." ORDER BY LENGTH(PKGPTR.patterns) DESC LIMIT 1";
406
407
	$package_info = $db->run($query);
408
	if($package_info){
409
		$package_info = $package_info[0];
410
411
		if( ($package_info['applicable_for'] == "0" && $call_direction == "outbound") || ($package_info['applicable_for'] == "1" && $call_direction == "inbound") || ($package_info['applicable_for'] == "2") ) {
412
	
413
			$counter_info =  get_counters($accountid,$package_info['package_id'],$db,$logger);
414
415
			if(!$counter_info) {
416
				$Insert_Query = "INSERT INTO counters (package_id,accountid) VALUES (".$package_info['package_id'].",".$accountid.")";		
417
				$logger->log("Insert Counters  : " . $Insert_query);
0 ignored issues
show
The variable $Insert_query does not exist. Did you mean $Insert_Query?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
418
				$db->run($Insert_Query);
419
				$counter_info =  get_counters($accountid,$package_info['package_id'],$db,$logger);
420
				
421
			}	
422
			//print_r($counter_info);
423
			if ( $package_info['includedseconds'] > ($counter_info['seconds'] )) {
424
				$availableseconds = $package_info['includedseconds'] - $counter_info['seconds'];
425
				$freeseconds = ($availableseconds >= $duration) ? $duration : $availableseconds;
426
				$duration = ($availableseconds >= $duration) ? $duration : $availableseconds;
427
				$update_query = "UPDATE counters SET seconds = ".($counter_info['seconds'] + $freeseconds ). " WHERE id = ". $counter_info['id'];
428
				$logger->log("Update Counters  : " . $update_query);
429
				$db->run($update_query);
430
				$package_array['package_id']= $package_info['package_id'];
431
				$package_array['calltype'] = "FREE";
432
			}						
433
		} 
434
	}
435
	return $package_array;
436
} 
437
438
// Getting used package minutes in counter table
439
function get_counters($accountid,$package_id,$db,$logger)
440
{
441
	$query_counter = "SELECT id,seconds FROM counters  WHERE  accountid = ".$accountid." AND package_id = ".$package_id." AND status=1 LIMIT 1";
442
	$counter = $db->run($query_counter);
443
	$logger->log("GET Counters  : " . $query_counter);
444
	if($counter)
445
		return $counter[0];	
446
	else
447
		return "";
448
}
449
450
//Get user info
451
function get_accounts($parent_id,$logger, $db) {
452
	$query = "SELECT * FROM accounts WHERE id=" . $parent_id;
453
	$logger->log("GET configuration  : " . $query);
454
	$res_user = $db->run($query);
455
	return $res_user[0];
456
}
457
458
// Get configuration
459
function load_configuration($logger)
460
{
461
	$query = "SELECT name,value FROM system WHERE name='decimal_points' and group_title = 'global'";
462
	$config = $db->run($query);
0 ignored issues
show
The variable $db does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
463
	$logger->log("GET configuration  : " . $query);
464
	return $config[0];
465
}
466
467
// String append prefix for checking rates
468
/**
469
 * @param string $field
470
 */
471
function number_loop($destination,$field,$db)
0 ignored issues
show
The parameter $db is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
472
{
473
	$max_len_prefix  = strlen($destination);
474
	$number_prefix = '(';
475
	while ($max_len_prefix  > 0)
476
	{
477
		$number_prefix .= "$field='^".substr($destination,0,$max_len_prefix).".*' OR ";
478
		$max_len_prefix--;
479
	}
480
	$number_prefix .= "$field='^defaultprefix.*')";//echo $number_prefix;exit;
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
481
	return $number_prefix;
482
}
483
484
//Convert current time to GMT
485
/**
486
 * @param string $date
487
 */
488
function convert_to_gmt($date)
489
{
490
	return gmdate('Y-m-d H:i:s', strtotime($date) );
491
}
492
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
493