Passed
Push — master ( 0baeb0...d4017c )
by Tony
19:18 queued 08:55
created

includes/billing.php (4 issues)

1
<?php
2
3
use LibreNMS\Config;
4
5
function format_bytes_billing($value)
6
{
7
    return format_number($value, Config::get('billing.base')).'B';
8
}//end format_bytes_billing()
9
10
11
function format_bytes_billing_short($value)
12
{
13
    return format_number($value, Config::get('billing.base'), 2, 3);
14
}//end format_bytes_billing_short()
15
16
17
function getDates($dayofmonth, $months = 0)
18
{
19
    $dayofmonth = zeropad($dayofmonth);
20
    $year       = date('Y');
21
    $month      = date('m');
22
23
    if (date('d') > $dayofmonth) {
24
        // Billing day is past, so it is next month
25
        $date_end   = date_create($year.'-'.$month.'-'.$dayofmonth);
26
        $date_start = date_create($year.'-'.$month.'-'.$dayofmonth);
27
        date_add($date_end, date_interval_create_from_date_string('1 month'));
0 ignored issues
show
It seems like $date_end can also be of type false; however, parameter $object of date_add() does only seem to accept DateTime, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

27
        date_add(/** @scrutinizer ignore-type */ $date_end, date_interval_create_from_date_string('1 month'));
Loading history...
28
    } else {
29
        // Billing day will happen this month, therefore started last month
30
        $date_end   = date_create($year.'-'.$month.'-'.$dayofmonth);
31
        $date_start = date_create($year.'-'.$month.'-'.$dayofmonth);
32
        date_sub($date_start, date_interval_create_from_date_string('1 month'));
0 ignored issues
show
It seems like $date_start can also be of type false; however, parameter $object of date_sub() does only seem to accept DateTime, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

32
        date_sub(/** @scrutinizer ignore-type */ $date_start, date_interval_create_from_date_string('1 month'));
Loading history...
33
    }
34
35
    if ($months > 0) {
36
        date_sub($date_start, date_interval_create_from_date_string($months.' month'));
37
        date_sub($date_end, date_interval_create_from_date_string($months.' month'));
38
    }
39
40
    // date_sub($date_start, date_interval_create_from_date_string('1 month'));
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
41
    date_sub($date_end, date_interval_create_from_date_string('1 day'));
42
43
    $date_from = date_format($date_start, 'Ymd').'000000';
44
    $date_to   = date_format($date_end, 'Ymd').'235959';
45
46
    date_sub($date_start, date_interval_create_from_date_string('1 month'));
47
    date_sub($date_end, date_interval_create_from_date_string('1 month'));
48
49
    $last_from = date_format($date_start, 'Ymd').'000000';
50
    $last_to   = date_format($date_end, 'Ymd').'235959';
51
52
    $return      = array();
53
    $return['0'] = $date_from;
54
    $return['1'] = $date_to;
55
    $return['2'] = $last_from;
56
    $return['3'] = $last_to;
57
58
    return ($return);
59
}//end getDates()
60
61
function getPredictedUsage($bill_day, $cur_used)
62
{
63
64
    $tmp = getDates($bill_day, 0);
65
    $start = new DateTime($tmp[0], new DateTimeZone(date_default_timezone_get()));
66
    $end   = new DateTime($tmp[1], new DateTimeZone(date_default_timezone_get()));
67
    $now   = new DateTime(date("Y-m-d"), new DateTimeZone(date_default_timezone_get()));
68
    $total = $end->diff($start)->format("%a");
69
    $since = $now->diff($start)->format("%a");
70
    return($cur_used/$since*$total);
71
}
72
73
function getValue($host, $port, $id, $inout)
74
{
75
    $oid    = 'IF-MIB::ifHC'.$inout.'Octets.'.$id;
76
    $device = dbFetchRow("SELECT * from `devices` WHERE `hostname` = ? LIMIT 1", array($host));
77
    $value  = snmp_get($device, $oid, '-Oqv');
78
79
    if (!is_numeric($value)) {
80
        $oid   = 'IF-MIB::if'.$inout.'Octets.'.$id;
81
        $value = snmp_get($device, $oid, '-Oqv');
82
    }
83
84
    return $value;
85
}//end getValue()
86
87
function getLastPortCounter($port_id, $bill_id)
88
{
89
    $return = array();
90
    $row    = dbFetchRow("SELECT timestamp, in_counter, in_delta, out_counter, out_delta FROM bill_port_counters WHERE `port_id` = ? AND `bill_id` = ?", array($port_id, $bill_id));
91
    if (!is_null($row)) {
92
        $return['timestamp']   = $row['timestamp'];
93
        $return['in_counter']  = $row['in_counter'];
94
        $return['in_delta']    = $row['in_delta'];
95
        $return['out_counter'] = $row['out_counter'];
96
        $return['out_delta']   = $row['out_delta'];
97
        $return['state']       = 'ok';
98
    } else {
99
        $return['state']       = 'failed';
100
    }
101
    return $return;
102
}//end getLastPortCounter()
103
104
105
function getLastMeasurement($bill_id)
106
{
107
    $return = array();
108
    $row    = dbFetchRow("SELECT timestamp,delta,in_delta,out_delta FROM bill_data WHERE bill_id = ? ORDER BY timestamp DESC LIMIT 1", array($bill_id));
109
    if (!is_null($row)) {
110
        $return['delta']     = $row['delta'];
111
        $return['delta_in']  = $row['delta_in'];
112
        $return['delta_out'] = $row['delta_out'];
113
        $return['timestamp'] = $row['timestamp'];
114
        $return['state']     = 'ok';
115
    } else {
116
        $return['state'] = 'failed';
117
    }
118
    return ($return);
119
}//end getLastMeasurement()
120
121
function get95thagg($bill_id, $datefrom, $dateto)
122
{
123
    $mq_sql           = "SELECT count(delta) FROM bill_data WHERE bill_id = ?";
124
    $mq_sql          .= " AND timestamp > ? AND timestamp <= ?";
125
    $measurements     = dbFetchCell($mq_sql, array($bill_id, $datefrom, $dateto));
126
    $measurement_95th = (round(($measurements / 100 * 95)) - 1);
127
128
    $q_95_sql  = "SELECT (delta / period * 8) AS rate FROM bill_data  WHERE bill_id = ?";
129
    $q_95_sql .= " AND timestamp > ? AND timestamp <= ? ORDER BY rate ASC";
130
    $a_95th    = dbFetchColumn($q_95_sql, array($bill_id, $datefrom, $dateto));
131
    $m_95th    = $a_95th[$measurement_95th];
132
133
    return (round($m_95th, 2));
134
}//end get95thagg()
135
136
137
function get95thIn($bill_id, $datefrom, $dateto)
138
{
139
    $mq_sql           = "SELECT count(delta) FROM bill_data WHERE bill_id = ?";
140
    $mq_sql          .= " AND timestamp > ? AND timestamp <= ?";
141
    $measurements     = dbFetchCell($mq_sql, array($bill_id, $datefrom, $dateto));
142
    $measurement_95th = (round(($measurements / 100 * 95)) - 1);
143
144
    $q_95_sql  = "SELECT (in_delta / period * 8) AS rate FROM bill_data  WHERE bill_id = ?";
145
    $q_95_sql .= " AND timestamp > ? AND timestamp <= ? ORDER BY rate ASC";
146
    $a_95th    = dbFetchColumn($q_95_sql, array($bill_id, $datefrom, $dateto));
147
    $m_95th    = $a_95th[$measurement_95th];
148
149
    return (round($m_95th, 2));
150
}//end get95thIn()
151
152
153
function get95thout($bill_id, $datefrom, $dateto)
154
{
155
    $mq_sql           = "SELECT count(delta) FROM bill_data WHERE bill_id = ?";
156
    $mq_sql          .= " AND timestamp > ? AND timestamp <= ?";
157
    $measurements     = dbFetchCell($mq_sql, array($bill_id, $datefrom, $dateto));
158
    $measurement_95th = (round(($measurements / 100 * 95)) - 1);
159
160
    $q_95_sql  = "SELECT (out_delta / period * 8) AS rate FROM bill_data  WHERE bill_id = ?";
161
    $q_95_sql .= " AND timestamp > ? AND timestamp <= ? ORDER BY rate ASC";
162
    $a_95th    = dbFetchColumn($q_95_sql, array($bill_id, $datefrom, $dateto));
163
    $m_95th    = $a_95th[$measurement_95th];
164
165
    return (round($m_95th, 2));
166
}//end get95thout()
167
168
169
function getRates($bill_id, $datefrom, $dateto, $dir_95th)
170
{
171
    $data = [];
172
173
    $sum_data = getSum($bill_id, $datefrom, $dateto);
174
    $mtot     = $sum_data['total'];
175
    $mtot_in  = $sum_data['inbound'];
176
    $mtot_out = $sum_data['outbound'];
177
    $ptot     = $sum_data['period'];
178
179
    $data['rate_95th_in']  = get95thIn($bill_id, $datefrom, $dateto);
180
    $data['rate_95th_out'] = get95thout($bill_id, $datefrom, $dateto);
181
182
    if ($dir_95th == 'agg') {
183
        $data['rate_95th'] = get95thagg($bill_id, $datefrom, $dateto);
184
        $data['dir_95th'] = 'agg';
185
    } else {
186
        if ($data['rate_95th_out'] > $data['rate_95th_in']) {
187
            $data['rate_95th'] = $data['rate_95th_out'];
188
            $data['dir_95th']  = 'out';
189
        } else {
190
            $data['rate_95th'] = $data['rate_95th_in'];
191
            $data['dir_95th']  = 'in';
192
        }
193
    }
194
195
    $data['total_data']     = $mtot;
196
    $data['total_data_in']  = $mtot_in;
197
    $data['total_data_out'] = $mtot_out;
198
    $data['rate_average']   = ($mtot / $ptot * 8);
199
    $data['rate_average_in']   = ($mtot_in / $ptot * 8);
200
    $data['rate_average_out']  = ($mtot_out / $ptot * 8);
201
202
    // print_r($data);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
203
    return ($data);
204
}//end getRates()
205
206
207
function getTotal($bill_id, $datefrom, $dateto)
208
{
209
    $mtot = dbFetchCell("SELECT SUM(delta) FROM bill_data WHERE bill_id = ? AND timestamp > ? AND timestamp <= ?", array($bill_id, $datefrom, $dateto));
210
    return ($mtot);
211
}//end getTotal()
212
213
214
function getSum($bill_id, $datefrom, $dateto)
215
{
216
    $sum = dbFetchRow("SELECT SUM(period) as period, SUM(delta) as total, SUM(in_delta) as inbound, SUM(out_delta) as outbound FROM bill_data WHERE bill_id = ? AND timestamp > ? AND timestamp <= ?", array($bill_id, $datefrom, $dateto));
217
    return ($sum);
218
}//end getSum()
219
220
221
function getPeriod($bill_id, $datefrom, $dateto)
222
{
223
    $ptot = dbFetchCell("SELECT SUM(period) FROM bill_data WHERE bill_id = ? AND timestamp > ? AND timestamp <= ?", array($bill_id, $datefrom, $dateto));
224
    return ($ptot);
225
}//end getPeriod()
226
227
function getBillingHistoryBitsGraphData($bill_id, $bill_hist_id, $reducefactor)
228
{
229
    $histrow = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to`, rate_95th, rate_average, bill_type FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($bill_id, $bill_hist_id));
230
231
    if (is_null($histrow)) {
232
        return null;
233
    }
234
235
    $graph_data = getBillingBitsGraphData($bill_id, $histrow['from'], $histrow['to'], $reducefactor);
236
237
    // Overwrite the rate data with the historical version
238
    $graph_data['rate_95th']    = $histrow['rate_95th'];
239
    $graph_data['rate_average'] = $histrow['rate_average'];
240
    $graph_data['bill_type']    = $histrow['bill_type'];
241
242
    return $graph_data;
243
}
244
245
function getBillingBitsGraphData($bill_id, $from, $to, $reducefactor)
246
{
247
    $i          = '0';
248
    $iter       = 0;
249
    $first      = null;
250
    $last       = null;
251
    $iter_in    = 0;
252
    $iter_out   = 0;
253
    $iter_period = 0;
254
    $max_in     = 0;
255
    $max_out    = 0;
256
    $tot_in     = 0;
257
    $tot_out    = 0;
258
    $tot_period = 0;
259
    $in_delta   = null;
260
    $out_delta  = null;
261
    $period     = null;
262
    $in_data    = array();
263
    $out_data   = array();
264
    $tot_data   = array();
265
    $ticks      = array();
266
267
    if (!isset($reducefactor) || !is_numeric($reducefactor) || $reducefactor < 1) {
268
        // Auto calculate reduce factor
269
        $expectedpoints = ceil(($to - $from) / 300);
270
        $desiredpoints = 400;
271
        $reducefactor = max(1, floor($expectedpoints / $desiredpoints));
272
    }
273
274
    $bill_data    = dbFetchRow('SELECT * from `bills` WHERE `bill_id`= ? LIMIT 1', array($bill_id));
275
276
    foreach (dbFetch('SELECT *, UNIX_TIMESTAMP(timestamp) AS formatted_date FROM bill_data WHERE bill_id = ? AND `timestamp` >= FROM_UNIXTIME( ? ) AND `timestamp` <= FROM_UNIXTIME( ? ) ORDER BY timestamp ASC', array($bill_id, $from, $to)) as $row) {
277
        $timestamp = $row['formatted_date'];
278
        if (!$first) {
279
            $first = $timestamp;
280
        }
281
282
        $period    = $row['period'];
283
        $in_delta  = $row['in_delta'] * 8;
284
        $out_delta = $row['out_delta'] * 8;
285
        $last      = $timestamp;
286
287
        $iter_in     += $in_delta;
288
        $iter_out    += $out_delta;
289
        $iter_period += $period;
290
291
        if ($period > 0) {
292
            $max_in    = max($max_in, $in_delta / $period);
293
            $max_out   = max($max_out, $out_delta / $period);
294
            $tot_in    += $in_delta;
295
            $tot_out   += $out_delta;
296
            $tot_period+= $period;
297
298
            if (++$iter >= $reducefactor) {
299
                $out_data[$i] = round(($iter_out / $iter_period), 2);
300
                $in_data[$i]  = round(($iter_in / $iter_period), 2);
301
                $tot_data[$i] = ($out_data[$i] + $in_data[$i]);
302
                $ticks[$i]    = $timestamp;
303
                $i++;
304
                $iter         = 0;
305
                unset($iter_out, $iter_in, $iter_period);
306
            }
307
        }
308
    }//end foreach
309
310
    if (!empty($iter_in)) {  // Write last element
311
        $out_data[$i] = round(($iter_out / $iter_period), 2);
312
        $in_data[$i]  = round(($iter_in / $iter_period), 2);
313
        $tot_data[$i] = ($out_data[$i] + $in_data[$i]);
314
        $ticks[$i]    = $timestamp;
315
        $i++;
316
    }
317
    $result = array(
318
        'from'          => $from,
319
        'to'            => $to,
320
        'first'         => $first,
321
        'last'          => $last,
322
323
        'in_data'       => $in_data,
324
        'out_data'      => $out_data,
325
        'tot_data'      => $tot_data,
326
        'ticks'         => $ticks,
327
328
        'rate_95th'     => $bill_data['rate_95th'],
329
        'rate_average'  => $bill_data['rate_average'],
330
        'bill_type'     => $bill_data['bill_type']
331
    );
332
333
    if ($period) {
334
        $result['max_in']   = $max_in;
335
        $result['max_out']  = $max_out;
336
        $result['ave_in']   = $tot_in / $tot_period;
337
        $result['ave_out']  = $tot_out / $tot_period;
338
        $result['last_in']  = $in_delta / $period;
339
        $result['last_out'] = $out_delta / $period;
340
    }
341
    return $result;
342
}//end getBillingBitsGraphData
343
344
function getHistoricTransferGraphData($bill_id)
345
{
346
    $i = '0';
347
348
    $in_data      = array();
349
    $out_data     = array();
350
    $tot_data     = array();
351
    $allow_data   = array();
352
    $ave_data     = array();
353
    $overuse_data = array();
354
    $ticklabels   = array();
355
    $allowed_val  = null;
356
357
    foreach (dbFetchRows('SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY `bill_datefrom` DESC LIMIT 12', array($bill_id)) as $data) {
358
        $datefrom          = strftime('%Y-%m-%d', strtotime($data['bill_datefrom']));
359
        $dateto        = strftime('%Y-%m-%d', strtotime($data['bill_dateto']));
360
        $datelabel     = $datefrom." - ".$dateto;
361
362
        array_push($ticklabels, $datelabel);
363
        array_push($in_data, $data['traf_in']);
364
        array_push($out_data, $data['traf_out']);
365
        array_push($tot_data, $data['traf_total']);
366
        array_push($allow_data, $allowed_val = ($data['bill_type'] == 'Quota' ? $data['bill_allowed'] : 0));
367
        array_push($overuse_data, $data['bill_type'] == 'Quota' ? $data['bill_overuse'] : 0);
368
        $i++;
369
    }//end foreach
370
371
    if ($i < 12) {
372
        $y = (12 - $i);
373
        for ($x = 0; $x < $y; $x++) {
374
            $allowed = (($x == '0') ? $allowed_val : '0' );
375
            array_push($in_data, '0');
376
            array_push($out_data, '0');
377
            array_push($tot_data, '0');
378
            array_push($allow_data, $allowed);
379
            array_push($overuse_data, '0');
380
            array_push($ticklabels, '');
381
        }
382
    }
383
384
    $graph_name = 'Historical bandwidth over the last 12 billing periods';
385
386
    return array(
387
        'graph_name'        => $graph_name,
388
        'in_data'           => $in_data,
389
        'out_data'          => $out_data,
390
        'tot_data'          => $tot_data,
391
        'allow_data'        => $allow_data,
392
        'ave_data'          => $ave_data,
393
        'overuse_data'      => $overuse_data,
394
        'ticklabels'        => $ticklabels
395
    );
396
}
397
398
function getBillingBandwidthGraphData($bill_id, $bill_hist_id, $from, $to, $imgtype)
399
{
400
    if (is_numeric($bill_hist_id)) {
401
        $histrow = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to`, rate_95th, rate_average FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($bill_id, $bill_hist_id));
402
403
        if (is_null($histrow)) {
404
            return null;
405
        }
406
        $from  = $histrow['from'];
407
        $to    = $histrow['to'];
408
    } else {
409
        if (!is_numeric($from) || !is_numeric($to)) {
410
            die('Must supply from and to if bill_hist_id is not supplied');
411
        }
412
    }
413
414
    $in_data      = array();
415
    $out_data     = array();
416
    $tot_data     = array();
417
    $allow_data   = array();
418
    $ave_data     = array();
419
    $overuse_data = array();
420
    $ticklabels   = array();
421
422
    $data    = array();
423
    $average = 0;
424
    if ($imgtype == 'day') {
425
        foreach (dbFetch('SELECT DISTINCT UNIX_TIMESTAMP(timestamp) as timestamp, SUM(delta) as traf_total, SUM(in_delta) as traf_in, SUM(out_delta) as traf_out FROM bill_data WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME(?) AND `timestamp` <= FROM_UNIXTIME(?) GROUP BY DATE(timestamp) ORDER BY timestamp ASC', array($bill_id, $from, $to)) as $data) {
426
            array_push($ticklabels, strftime("%Y-%m-%d", $data['timestamp']));
427
            array_push($in_data, isset($data['traf_in']) ? $data['traf_in'] : 0);
428
            array_push($out_data, isset($data['traf_out']) ? $data['traf_out'] : 0);
429
            array_push($tot_data, isset($data['traf_total']) ? $data['traf_total'] : 0);
430
            $average += $data['traf_total'];
431
        }
432
433
        $ave_count = count($tot_data);
434
435
        // Add empty items for the days not yet passed
436
        $days = (strftime('%e', date($to - $from)) - $ave_count - 1);
437
        for ($x = 0; $x < $days; $x++) {
438
            array_push($ticklabels, '');
439
            array_push($in_data, 0);
440
            array_push($out_data, 0);
441
            array_push($tot_data, 0);
442
        }
443
    } elseif ($imgtype == 'hour') {
444
        foreach (dbFetch('SELECT DISTINCT HOUR(timestamp) as hour, SUM(delta) as traf_total, SUM(in_delta) as traf_in, SUM(out_delta) as traf_out FROM bill_data WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME(?) AND `timestamp` <= FROM_UNIXTIME(?) GROUP BY HOUR(timestamp) ORDER BY HOUR(timestamp) ASC', array($bill_id, $from, $to)) as $data) {
445
            array_push($ticklabels, sprintf('%02d', $data['hour']) . ":00");
446
            array_push($in_data, isset($data['traf_in']) ? $data['traf_in'] : 0);
447
            array_push($out_data, isset($data['traf_out']) ? $data['traf_out'] : 0);
448
            array_push($tot_data, isset($data['traf_total']) ? $data['traf_total'] : 0);
449
            $average += $data['traf_total'];
450
        }
451
452
        $ave_count = count($tot_data);
453
    } else {
454
        die("Unknown graph type $imgtype");
455
    }//end if
456
457
    $average = ($average / $ave_count);
458
    $tot_data_size = count($tot_data);
459
    for ($x = 0; $x <= $tot_data_size; $x++) {
460
        array_push($ave_data, $average);
461
    }
462
463
    $graph_name = date('M j g:ia', $from).' - '.date('M j g:ia', $to);
464
465
    return array(
466
        'graph_name'        => $graph_name,
467
        'in_data'           => $in_data,
468
        'out_data'          => $out_data,
469
        'tot_data'          => $tot_data,
470
        'allow_data'        => $allow_data,
471
        'ave_data'          => $ave_data,
472
        'overuse_data'      => $overuse_data,
473
        'ticklabels'        => $ticklabels
474
    );
475
}
476
//end getBillingBandwidthGraphData
477