diff --git a/admin_traffic.php b/admin_traffic.php index 0077f63d..c2ab51b8 100644 --- a/admin_traffic.php +++ b/admin_traffic.php @@ -26,118 +26,20 @@ const AREA = 'admin'; require __DIR__ . '/lib/init.php'; -use Froxlor\Database\Database; -use Froxlor\PhpHelper; -use Froxlor\Settings; +use Froxlor\Traffic\Traffic; use Froxlor\UI\Panel\UI; use Froxlor\UI\Request; +use Froxlor\UI\Response; -$id = (int)Request::get('id'); - -$months = [ - '0' => 'empty', - '1' => 'jan', - '2' => 'feb', - '3' => 'mar', - '4' => 'apr', - '5' => 'may', - '6' => 'jun', - '7' => 'jul', - '8' => 'aug', - '9' => 'sep', - '10' => 'oct', - '11' => 'nov', - '12' => 'dec' -]; +$range = Request::get('range', 'days:30'); if ($page == 'overview' || $page == 'customers') { - $minyear_stmt = Database::query("SELECT `year` FROM `" . TABLE_PANEL_TRAFFIC . "` ORDER BY `year` ASC LIMIT 1"); - $minyear = $minyear_stmt->fetch(PDO::FETCH_ASSOC); - - if (!isset($minyear['year']) || $minyear['year'] == 0) { - $maxyears = 0; - } else { - $maxyears = date("Y") - $minyear['year']; + try { + $context = Traffic::getCustomerStats($userinfo, $range); + } catch (Exception $e) { + Response::dynamicError($e->getMessage()); } - $params = []; - if ($userinfo['customers_see_all'] == '0') { - $params = [ - 'id' => $userinfo['adminid'] - ]; - } - - $customer_name_list_stmt = Database::prepare(" - SELECT `customerid`,`company`,`name`,`firstname` - FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : ' AND `adminid` = :id') . " - ORDER BY name"); - - $traffic_list_stmt = Database::prepare(" - SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic - FROM `" . TABLE_PANEL_TRAFFIC . "` - WHERE year = :year AND `customerid` = :id - GROUP BY month ORDER BY month"); - - $stats = []; - - for ($years = 0; $years <= $maxyears; $years++) { - $totals = [ - 'jan' => 0, - 'feb' => 0, - 'mar' => 0, - 'apr' => 0, - 'may' => 0, - 'jun' => 0, - 'jul' => 0, - 'aug' => 0, - 'sep' => 0, - 'oct' => 0, - 'nov' => 0, - 'dec' => 0 - ]; - - Database::pexecute($customer_name_list_stmt, $params); - - $data = []; - while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) { - $virtual_host = [ - 'name' => ($customer_name['company'] == '' ? $customer_name['name'] . ", " . $customer_name['firstname'] : $customer_name['company']), - 'customerid' => $customer_name['customerid'], - 'jan' => '-', - 'feb' => '-', - 'mar' => '-', - 'apr' => '-', - 'may' => '-', - 'jun' => '-', - 'jul' => '-', - 'aug' => '-', - 'sep' => '-', - 'oct' => '-', - 'nov' => '-', - 'dec' => '-' - ]; - - Database::pexecute($traffic_list_stmt, [ - 'year' => (date("Y") - $years), - 'id' => $customer_name['customerid'] - ]); - - while ($traffic_month = $traffic_list_stmt->fetch(PDO::FETCH_ASSOC)) { - $virtual_host[$months[(int)$traffic_month['month']]] = PhpHelper::sizeReadable($traffic_month['traffic'], 'GiB', 'bi', '%01.' . (int)Settings::Get('panel.decimal_places') . 'f %s'); - $totals[$months[(int)$traffic_month['month']]] += $traffic_month['traffic']; - } - - $data = $virtual_host; - } - $stats[] = [ - 'year' => date("Y") - $years, - 'type' => lng('traffic.customer'), - 'data' => $data, - ]; - } - - UI::view('user/traffic.html.twig', [ - 'stats' => $stats - ]); + // pass metrics to the view + UI::view('user/traffic.html.twig', $context); } diff --git a/customer_traffic.php b/customer_traffic.php index a5c01d34..aba995c3 100644 --- a/customer_traffic.php +++ b/customer_traffic.php @@ -24,7 +24,6 @@ */ const AREA = 'customer'; -$intrafficpage = 1; require __DIR__ . '/lib/init.php'; use Froxlor\Database\Database; @@ -38,131 +37,13 @@ if (Settings::IsInList('panel.customer_hide_options', 'traffic')) { Response::redirectTo('customer_index.php'); } -$traffic = ''; -$month = null; -$year = null; +if ($page === null || $page == 'overview') { + +} elseif ($page == 'current') { -if (Request::exist('month') && Request::exist('year')) { - $month = (int)Request::get('month'); - $year = (int)Request::get('year'); -} elseif (isset($_GET['page']) && $_GET['page'] == 'current') { - if (date('d') != '01') { - $month = date('m'); - $year = date('Y'); - } elseif (date('m') == '01') { - $month = 12; - $year = date('Y') - 1; - } else { - $month = date('m') - 1; - $year = date('Y'); - } } -if (!is_null($month) && !is_null($year)) { - $result_stmt = Database::prepare("SELECT SUM(`http`) as 'http', SUM(`ftp_up`) AS 'ftp_up', SUM(`ftp_down`) as 'ftp_down', SUM(`mail`) as 'mail', `day`, `month`, `year` - FROM `" . TABLE_PANEL_TRAFFIC . "` - WHERE `customerid`= :customerid - AND `month` = :month - AND `year` = :year - GROUP BY `day` - ORDER BY `day` DESC"); - $params = [ - "customerid" => $userinfo['customerid'], - "month" => $month, - "year" => $year - ]; - Database::pexecute($result_stmt, $params); - $traf['byte'] = 0; - $traffic_complete['http'] = 0; - $traffic_complete['ftp'] = 0; - $traffic_complete['mail'] = 0; - $traf['days'] = []; - $traf['http_data'] = []; - $traf['ftp_data'] = []; - $traf['mail_data'] = []; - - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - $http = $row['http']; - $traf['http_data'][] = (float)$http; - $ftp = $row['ftp_up'] + $row['ftp_down']; - $traf['ftp_data'][] = (float)$ftp; - $mail = $row['mail']; - $traf['mail_data'][] = (float)$mail; - $traf['byte'] = $http + $ftp + $mail; - $traffic_complete['http'] += $http; - $traffic_complete['ftp'] += $ftp; - $traffic_complete['mail'] += $mail; - $traf['days'][] = $row['day']; - } - - UI::view('user/traffic.html.twig', [ - 'traffic_complete_http' => $traffic_complete['http'], - 'traffic_complete_ftp' => $traffic_complete['ftp'], - 'traffic_complete_mail' => $traffic_complete['mail'], - 'traffic_complete_total' => $traf['byte'], - 'labels' => $traf['days'], - 'http_data' => $traf['http_data'], - 'ftp_data' => $traf['ftp_data'], - 'mail_data' => $traf['mail_data'], - ]); -} else { - // default to the last 36 months - $from_date = (new DateTime)->modify("last day of last months")->setTime(23, 59, 59)->sub(new \DateInterval('P3Y'))->format('U'); - $result_stmt = Database::prepare(" - SELECT `month`, `year`, SUM(`http`) AS http, SUM(`ftp_up`) AS ftp_up, SUM(`ftp_down`) AS ftp_down, SUM(`mail`) AS mail - FROM `" . TABLE_PANEL_TRAFFIC . "` - WHERE `customerid` = :customerid AND `stamp` = :fromdate - GROUP BY `year`, `month` - ORDER BY `year` ASC, `month` ASC - "); - Database::pexecute($result_stmt, [ - "customerid" => $userinfo['customerid'], - "fromdate" => $from_date - ]); - $traffic_complete['http'] = 0; - $traffic_complete['ftp'] = 0; - $traffic_complete['mail'] = 0; - $traf['days'] = []; - $traf['http_data'] = []; - $traf['ftp_data'] = []; - $traf['mail_data'] = []; - - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - $http = $row['http']; - $traf['http_data'][] = (int)$http / 1024 / 1024; - $ftp_up = $row['ftp_up']; - $ftp_down = $row['ftp_down']; - $traf['ftp_data'][] = (int)($ftp_up + $ftp_down) / 1024 / 1024; - $mail = $row['mail']; - $traf['mail_data'][] = (int)$mail / 1024 / 1024; - $traffic_complete['http'] += $http; - $traffic_complete['ftp'] += $ftp_up + $ftp_down; - $traffic_complete['mail'] += $mail; - $traf['month'] = $row['month']; - $traf['year'] = $row['year']; - $traf['monthname'] = lng('traffic.months.' . intval($row['month'])) . " " . $row['year']; - $traf['byte'] = $http + $ftp_up + $ftp_down + $mail; - $traf['byte_total'] = $traf['byte_total'] + $http + $ftp_up + $ftp_down + $mail; - $traf['days'][] = $traf['monthname']; - } - - UI::view('user/traffic.html.twig', [ - 'traffic_complete_http' => $traffic_complete['http'], - 'traffic_complete_ftp' => $traffic_complete['ftp'], - 'traffic_complete_mail' => $traffic_complete['mail'], - 'traffic_complete_total' => $traf['byte_total'], - 'labels' => $traf['days'], - 'http_data' => $traf['http_data'], - 'ftp_data' => $traf['ftp_data'], - 'mail_data' => $traf['mail_data'], - ]); -} - -function getReadableTraffic(&$traf, $index, $value, $divisor, $desc = "") -{ - if (extension_loaded('bcmath')) { - $traf[$index] = bcdiv($value, $divisor, Settings::Get('panel.decimal_places')) . (!empty($desc) ? " " . $desc : ""); - } else { - $traf[$index] = round($value / $divisor, Settings::Get('panel.decimal_places')) . (!empty($desc) ? " " . $desc : ""); - } -} +UI::view('user/traffic.html.twig', [ + 'metrics' => \Froxlor\Traffic\Traffic::getCustomerMetrics($userinfo), + 'chart' => \Froxlor\Traffic\Traffic::getCustomerChart($userinfo, 30), +]); diff --git a/lib/Froxlor/Traffic/Traffic.php b/lib/Froxlor/Traffic/Traffic.php new file mode 100644 index 00000000..63f1b284 --- /dev/null +++ b/lib/Froxlor/Traffic/Traffic.php @@ -0,0 +1,100 @@ + + * @license https://files.froxlor.org/misc/COPYING.txt GPLv2 + */ + +namespace Froxlor\Traffic; + +use Froxlor\Api\Commands\Customers; +use Froxlor\UI\Collection; + +class Traffic +{ + public static function getCustomerStats($userinfo, $range = null): array + { + $trafficCollection = (new Collection(\Froxlor\Api\Commands\Traffic::class, $userinfo, self::getParamsByRange($range, ['customer_traffic' => true,]))) + ->has('customer', Customers::class, 'customerid', 'customerid') + ->get(); + + // build stats for each user + $users = []; + foreach ($trafficCollection['data']['list'] as $item) { + $users[$item['customerid']]['loginname'] = $item['customer']['loginname']; + $users[$item['customerid']]['total'] += ($item['http'] + $item['ftp_up'] + $item['ftp_down'] + $item['mail']); + $users[$item['customerid']]['http'] += $item['http']; + $users[$item['customerid']]['ftp'] += ($item['ftp_up'] + $item['ftp_down']); + $users[$item['customerid']]['mail'] += $item['mail']; + } + + // calculate overview for given range from users + $metrics = []; + foreach ($users as $user) { + $metrics['total'] += $user['total']; + $metrics['http'] += $user['http']; + $metrics['ftp'] += $user['ftp']; + $metrics['mail'] += $user['mail']; + } + + return [ + 'metrics' => $metrics, + 'users' => $users, + ]; + } + + private static function getParamsByRange(string $range, array $params = []) + { + $dateParams = []; + + if (preg_match("/year:([0-9]{4})/", $range, $matches)) { + $dateParams = ['year' => $matches[1]]; + } + + // TODO: get params by range: hours:x, days:x, months:x + + return array_merge($dateParams, $params); + } + + public static function getCustomerChart($userinfo, $range = 30): array + { + // FIXME: this is currently an example for the chart + + $data = []; + + for ($i = 0; $i < $range; $i++) { + $data['labels'][] = date("d.m", strtotime('-' . $i . ' days')); + + // put data for given date + $data['http'][] = 0; + $data['ftp'][] = 0; + $data['mail'][] = 0; + } + + return [ + 'labels' => array_reverse($data['labels']), + 'http' => array_reverse($data['http']), + 'ftp' => array_reverse($data['ftp']), + 'mail' => array_reverse($data['mail']), + 'range' => $range, + ]; + } +} diff --git a/lib/Froxlor/Traffic/index.html b/lib/Froxlor/Traffic/index.html new file mode 100644 index 00000000..e69de29b diff --git a/templates/Froxlor/user/traffic.html.twig b/templates/Froxlor/user/traffic.html.twig index f0558c13..3e56963c 100644 --- a/templates/Froxlor/user/traffic.html.twig +++ b/templates/Froxlor/user/traffic.html.twig @@ -13,84 +13,76 @@ {% block content %} + + +
+ +
+ +
-

{{ traffic_complete_http|formatBytes }}

+

{{ metrics.total|formatBytes }}

+ Total +
+
+

{{ metrics.http|formatBytes }}

HTTP
-

{{ traffic_complete_ftp|formatBytes }}

+

{{ metrics.ftp|formatBytes }}

FTP
-

{{ traffic_complete_mail|formatBytes }}

+

{{ metrics.mail|formatBytes }}

Mail
-
-

{{ traffic_complete_total|formatBytes }}

- Total -
-
-
- Traffic + + + {% if users is not empty %} +
+ + + + + + + + + + + + {% for user in users %} + + + + + + + + {% endfor %} + +
{{ lng('login.username') }}TotalHTTPFTPMail +
{{ user.loginname }}{{ user.total|formatBytes }}{{ user.http|formatBytes }}{{ user.ftp|formatBytes }}{{ user.mail|formatBytes }}
-
- -
-
- - {% if stats is defined %} - {% for yearly_stats in stats %} + {% else %}
-
- Traffic per {{ yearly_stats.type }} in {{ yearly_stats.year }} -
-
- {{ yearly_stats.data|json_encode }} +
+

No data for given range found.

- {% endfor %} {% endif %} - - {% endblock %} diff --git a/templates/misc/standardcustomer/index.html b/templates/misc/standardcustomer/index.html index e1ae6495..ce271854 100644 --- a/templates/misc/standardcustomer/index.html +++ b/templates/misc/standardcustomer/index.html @@ -67,7 +67,7 @@ a:hover { - © 2009-2021 by the Froxlor + © 2009-2022 by the Froxlor Team