Source of file api.traffstats.php
Size: 48,399 Bytes - Last Modified: 2024-04-27T15:26:05+03:00
/tmp/current_snapshot/api/libs/api.traffstats.php
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174 | <?php /** * Basic traffic stats/charts report implementation */ class TraffStats { /** * System alter config as key=>value * * @var array */ protected $altCfg = array(); /** * Ishimura enabled flag * * @var string */ protected $ishimuraFlag = false; /** * Ishimura database abstraction layer * * @var object */ protected $ishimuraDb = ''; /** * OphanimFlow integration flag * * @var bool */ protected $ophanimFlag = false; /** * OphanimFlow object instance * * @var object */ protected $ophanimFlow = ''; /** * Contains all available users data * * @var array */ protected $userData = array(); /** * Contains ishimura user traffic stats * * @var array */ protected $ishimuraData = array(); /** * Contains TRAFFSIZE option value * * @var string */ protected $trafScale = 'float'; /** * Previous months traffic stats database abstraction layer * * @var object */ protected $statsDb = ''; /** * Contains previous user traffic stats as year=>month=>data * * @var array */ protected $trafStats = array(); /** * Contains available traffic directions/classes as index=>ruleNum * * @var array */ protected $dirs = array(); /** * Contains current instance login * * @var string */ protected $login = ''; /** * On-demand charts loading flag * * @var bool */ protected $ondemandFlag = true; /** * System caching object instance * * @var object */ protected $cache = ''; /** * Default caching timeout * * @var int */ protected $cachingTimeout = 3600; /** * System messages helper object placeholder * * @var object */ protected $messages = ''; //some other predefined stuff const URL_ME = '?module=traffstats'; const ROUTE_PROX_IMG = 'loadimg'; const ROUTE_LOGIN = 'username'; const ROUTE_AJUSER = 'defferedgraph'; const ROUTE_AJCAT = 'grcat'; const KEY_GRAPH = 'DEFFEREDGRAPH'; const AJ_CONTAINER = 'ajdefferedcontainer'; /** * Creates new traffStats instance * * @param string $login */ public function __construct($login = '') { $this->setLogin($login); $this->initMessages(); $this->initCache(); $this->loadConfigs(); $this->initDbLayers(); } /** * Sets current instance login * * @param string $login * * @return void */ protected function setLogin($login = '') { if (!empty($login)) { $this->login = ubRouting::filters($login, 'mres'); } } /** * Inits message helper instance for further usage * * @return void */ protected function initMessages() { $this->messages = new UbillingMessageHelper(); } /** * Inits system caching engine * * @return void */ protected function initCache() { $this->cache = new UbillingCache(); } /** * Loads traffic directions * * @return void */ protected function loadDirs() { $this->dirs = zb_DirectionsGetAll(); } /** * Loads required config and sets some properties * * @return void */ protected function loadConfigs() { global $ubillingConfig; $this->altCfg = $ubillingConfig->getAlter(); $this->ondemandFlag = $ubillingConfig->getAlterParam('ONDEMAND_CHARTS', false); $this->trafScale = trim($this->altCfg['TRAFFSIZE']); if ($this->altCfg[MultiGen::OPTION_ISHIMURA]) { $this->ishimuraFlag = true; } if ($this->altCfg[OphanimFlow::OPTION_ENABLED]) { $this->ophanimFlag = true; } } /** * Loads all available users data * * @return void */ protected function loadUserData() { if (!empty($this->login)) { $this->userData = zb_UserGetStargazerData($this->login); } } /** * Inits required database abstraction layers and required objects * * @return void */ protected function initDbLayers() { $this->statsDb = new NyanORM('stat'); if ($this->ishimuraFlag) { $this->ishimuraDb = new NyanORM(MultiGen::NAS_ISHIMURA); } if ($this->ophanimFlag) { $this->ophanimFlow = new OphanimFlow(); } } /** * Loads ishimura user traffic data as year=>month=>D0/U0 * * @return void */ protected function loadIshimuraStats() { if (!empty($this->login)) { if ($this->ishimuraFlag) { $this->ishimuraDb->where('login', '=', $this->login); $rawStats = $this->ishimuraDb->getAll(); if (!empty($rawStats)) { foreach ($rawStats as $io => $each) { $this->ishimuraData[$each['year']][$each['month']] = $each; } } } } } /** * Returns native stargazer user current month traffic counters * * @param int $dirNum * * @return array */ protected function getUserDataCounters($dirNum) { $result = array(); $dClass = 'D' . $dirNum; $uClass = 'U' . $dirNum; if (isset($this->userData[$dClass])) { $result[$dClass] = $this->userData[$dClass]; $result[$uClass] = $this->userData[$uClass]; } return ($result); } /** * Returns ishimura user traffic counters for selected year/month * * @param int $year * @param int $month * * @return array */ protected function getUserIshimuraCounters($year, $month) { $result = array(); if (isset($this->ishimuraData[$year])) { if (isset($this->ishimuraData[$year][$month])) { $result['D0'] = $this->ishimuraData[$year][$month]['D0']; $result['U0'] = $this->ishimuraData[$year][$month]['U0']; } } return ($result); } /** * Returns fastly user IP from preloaded userdata * * @return string */ protected function getUserIp() { $result = ''; if (isset($this->userData['IP'])) { $result = $this->userData['IP']; } return ($result); } /** * Loads all previous user traffic stats into protected property * * @return void */ protected function loadTraffStats() { if (!empty($this->login)) { $this->statsDb->where('login', '=', $this->login); $this->statsDb->orderBy('year`,`month', 'ASC'); $this->trafStats = $this->statsDb->getAll(); } } /** * Returns stats record for selected year/month/class * * @param int $classNum * * @return array */ protected function getUserPrevMonthTraff($classNum) { $result = array(); if (!empty($this->trafStats)) { foreach ($this->trafStats as $io => $each) { if (isset($each['D' . $classNum])) { $result[] = $each; } } } return ($result); } /** * Render current month traffic report part * * @return string */ protected function renderCurMonthStats() { $result = ''; $cells = wf_TableCell(__('Traffic classes')); $cells .= wf_TableCell(__('Downloaded')); $cells .= wf_TableCell(__('Uploaded')); $cells .= wf_TableCell(__('Total')); $rows = wf_TableRow($cells, 'row1'); if (!empty($this->dirs)) { foreach ($this->dirs as $dir) { $downup = $this->getUserDataCounters($dir['rulenumber']); //yeah, no classes at all if ($dir['rulenumber'] == 0) { //ishimura enabled? if ($this->ishimuraFlag) { $dataHideki = $this->getUserIshimuraCounters(curyear(), date("n")); if (isset($downup['D0'])) { @$downup['D0'] += $dataHideki['D0']; @$downup['U0'] += $dataHideki['U0']; } else { $downup['D0'] = $dataHideki['D0']; $downup['U0'] = $dataHideki['U0']; } } //or ophanim flow may be? if ($this->ophanimFlag) { $ophanimCmonth = $this->ophanimFlow->getUserCurMonthTraff($this->login); if (isset($downup['D0'])) { $downup['D0'] += $ophanimCmonth['D0']; $downup['U0'] += $ophanimCmonth['U0']; } else { $downup['D0'] = $ophanimCmonth['D0']; $downup['U0'] = $ophanimCmonth['U0']; } } } $dLabel = zb_convertSize($downup['D' . $dir['rulenumber']], $this->trafScale); $uLabel = zb_convertSize($downup['U' . $dir['rulenumber']], $this->trafScale); $totalLabel = zb_convertSize(($downup['U' . $dir['rulenumber']] + $downup['D' . $dir['rulenumber']]), $this->trafScale); $cells = wf_TableCell($dir['rulename']); $cells .= wf_TableCell($dLabel, '', '', 'sorttable_customkey="' . $downup['D' . $dir['rulenumber']] . '"'); $cells .= wf_TableCell($uLabel, '', '', 'sorttable_customkey="' . $downup['U' . $dir['rulenumber']] . '"'); $cells .= wf_TableCell($totalLabel, '', '', 'sorttable_customkey="' . ($downup['U' . $dir['rulenumber']] + $downup['D' . $dir['rulenumber']]) . '"'); $rows .= wf_TableRow($cells, 'row3'); } } $result .= wf_tag('h3') . __('Current month traffic stats') . wf_tag('h3', true); $result .= wf_TableBody($rows, '100%', '0', 'sortable'); return ($result); } /** * Returns the custom dimensions for OphanimFlow charts. * The custom dimensions in the format '&w={width}&h={height}' or array[w,h], or an empty string|array if no dimensions are found. * * @param bool $asArray Whether to return the dimensions as an array or a string. * * @return string|array */ protected function getOphCustomDimensions($asArray = false) { $result = ($asArray) ? array() : ''; $delimiter = 'x'; if (isset($this->altCfg[OphanimFlow::OPTION_DIMENSIONS])) { $optionValue = $this->altCfg[OphanimFlow::OPTION_DIMENSIONS]; if (!empty($optionValue) and ispos($optionValue, $delimiter)) { $raw = explode($delimiter, $optionValue); if (isset($raw[0]) and isset($raw[1])) { $w = ubRouting::filters($raw[0], 'int'); $h = ubRouting::filters($raw[1], 'int'); if ($w and $h) { if ($asArray) { $result['w'] = $w; $result['h'] = $h; } else { $result .= '&w=' . $w . '&h=' . $h; } } } } } return ($result); } /** * Generates user IP graph images links array * * @return array */ protected function genGraphLinks() { global $ubillingConfig; $urls = array(); $zbxGraphsEnabled = $ubillingConfig->getAlterParam('ZABBIX_USER_TRAFFIC_GRAPHS'); $zbxGraphsSearchIdnetify = ($ubillingConfig->getAlterParam('ZABBIX_GRAPHS_SEARCHIDENTIFY')) ? $ubillingConfig->getAlterParam('ZABBIX_GRAPHS_SEARCHIDENTIFY') : 'MAC'; $zbxGraphsSearchField = ($ubillingConfig->getAlterParam('ZABBIX_GRAPHS_SEARCHFIELD')) ? $ubillingConfig->getAlterParam('ZABBIX_GRAPHS_SEARCHFIELD') : 'name'; $zbxGraphsExtended = wf_getBoolFromVar($ubillingConfig->getAlterParam('ZABBIX_GRAPHS_EXTENDED')); $mlgUseMikrotikGraphs = wf_getBoolFromVar($ubillingConfig->getAlterParam('MULTIGEN_USE_ROS_TRAFFIC_GRAPHS')); $ip = $this->getUserIp(); $bwdUrl = zb_BandwidthdGetUrl($ip); $netid = zb_NetworkGetByIp($ip); $nasid = zb_NasGetByNet($netid); if ($nasid) { $nasdata = zb_NasGetData($nasid); $nastype = ($mlgUseMikrotikGraphs) ? 'mikrotik' : $nasdata['nastype']; $zbxAllGraphs = array(); if ($zbxGraphsEnabled) { $zbxAllGraphs = getCachedZabbixNASGraphIDs(); } if (!empty($zbxAllGraphs) and isset($zbxAllGraphs[$nasdata['nasip']])) { switch ($zbxGraphsSearchIdnetify) { case 'MAC': $userSearchIdentify = zb_MultinetGetMAC($ip); break; case 'login': $userSearchIdentify = zb_UserGetLoginByIp($ip); break; default: $userSearchIdentify = $ip; } $urls = getZabbixUserGraphLinks($ip, $zbxGraphsSearchField, $userSearchIdentify, $zbxAllGraphs, $zbxGraphsExtended); } else { if (!empty($bwdUrl)) { // RouterOS graph model: if ($nastype == 'mikrotik') { // Get user's IP array: $alluserips = zb_UserGetAllIPs(); $alluserips = array_flip($alluserips); if (!ispos($bwdUrl, 'pppoe') and !$mlgUseMikrotikGraphs) { // Generate graphs paths: $urls['dayr'] = $bwdUrl . '/' . $alluserips[$ip] . '/daily.gif'; $urls['days'] = null; $urls['weekr'] = $bwdUrl . '/' . $alluserips[$ip] . '/weekly.gif'; $urls['weeks'] = null; $urls['monthr'] = $bwdUrl . '/' . $alluserips[$ip] . '/monthly.gif'; $urls['months'] = null; $urls['yearr'] = $bwdUrl . '/' . $alluserips[$ip] . '/yearly.gif'; $urls['years'] = null; } elseif ($mlgUseMikrotikGraphs) { $urls['dayr'] = $bwdUrl . '/' . 'mlg_' . $ip . '/daily.gif'; $urls['days'] = null; $urls['weekr'] = $bwdUrl . '/' . 'mlg_' . $ip . '/weekly.gif'; $urls['weeks'] = null; $urls['monthr'] = $bwdUrl . '/' . 'mlg_' . $ip . '/monthly.gif'; $urls['months'] = null; $urls['yearr'] = $bwdUrl . '/' . 'mlg_' . $ip . '/yearly.gif'; } else { $urls['dayr'] = $bwdUrl . $alluserips[$ip] . '>/daily.gif'; $urls['days'] = null; $urls['weekr'] = $bwdUrl . $alluserips[$ip] . '>/weekly.gif'; $urls['weeks'] = null; $urls['monthr'] = $bwdUrl . $alluserips[$ip] . '>/monthly.gif'; $urls['months'] = null; $urls['yearr'] = $bwdUrl . $alluserips[$ip] . '>/yearly.gif'; $urls['years'] = null; } } else { // Banwidthd graphs model: $urls['dayr'] = $bwdUrl . '/' . $ip . '-1-R.png'; $urls['days'] = $bwdUrl . '/' . $ip . '-1-S.png'; $urls['weekr'] = $bwdUrl . '/' . $ip . '-2-R.png'; $urls['weeks'] = $bwdUrl . '/' . $ip . '-2-S.png'; $urls['monthr'] = $bwdUrl . '/' . $ip . '-3-R.png'; $urls['months'] = $bwdUrl . '/' . $ip . '-3-S.png'; $urls['yearr'] = $bwdUrl . '/' . $ip . '-4-R.png'; $urls['years'] = $bwdUrl . '/' . $ip . '-4-S.png'; //OphanimFlow graphs if (ispos($bwdUrl, 'OphanimFlow') or ispos($bwdUrl, 'of/')) { $customDimensions = $this->getOphCustomDimensions(); $urls['hourr'] = $bwdUrl . '/?module=graph&dir=R&period=hour&ip=' . $ip . $customDimensions; $urls['hours'] = $bwdUrl . '/?module=graph&dir=S&period=hour&ip=' . $ip . $customDimensions; $urls['dayr'] = $bwdUrl . '/?module=graph&dir=R&period=day&ip=' . $ip . $customDimensions; $urls['days'] = $bwdUrl . '/?module=graph&dir=S&period=day&ip=' . $ip . $customDimensions; $urls['weekr'] = $bwdUrl . '/?module=graph&dir=R&period=week&ip=' . $ip . $customDimensions; $urls['weeks'] = $bwdUrl . '/?module=graph&dir=S&period=week&ip=' . $ip . $customDimensions; $urls['monthr'] = $bwdUrl . '/?module=graph&dir=R&period=month&ip=' . $ip . $customDimensions; $urls['months'] = $bwdUrl . '/?module=graph&dir=S&period=month&ip=' . $ip . $customDimensions; $urls['yearr'] = $bwdUrl . '/?module=graph&dir=R&period=year&ip=' . $ip . $customDimensions; $urls['years'] = $bwdUrl . '/?module=graph&dir=S&period=year&ip=' . $ip . $customDimensions; } } //MikroTik Multigen Hotspot users if (ispos($bwdUrl, 'mlgmths')) { $bwdUrl = str_replace('mlgmths', 'graphs/queue/', $bwdUrl); $allUserMacs = zb_UserGetAllIpMACs(); if (isset($allUserMacs[$ip])) { $userMac = $allUserMacs[$ip]; $userMacUpper = strtoupper($userMac); $queueName = '<hotspot-' . urlencode($userMacUpper); $urls['dayr'] = $bwdUrl . $queueName . '>/daily.gif'; $urls['days'] = null; $urls['weekr'] = $bwdUrl . $queueName . '>/weekly.gif'; $urls['weeks'] = null; $urls['monthr'] = $bwdUrl . $queueName . '>/monthly.gif'; $urls['months'] = null; $urls['yearr'] = $bwdUrl . $queueName . '>/yearly.gif'; $urls['years'] = null; } } //MikroTik Multigen PPP if (ispos($bwdUrl, 'mlgmtppp')) { $bwdUrl = str_replace('mlgmtppp', 'graphs/queue/', $bwdUrl); $alluserips = zb_UserGetAllIPs(); $alluserips = array_flip($alluserips); if (isset($alluserips[$ip])) { $userLogin = $alluserips[$ip]; $queueName = urlencode('<pppoe-' . $userLogin . '>'); $urls['dayr'] = $bwdUrl . $queueName . '/daily.gif'; $urls['days'] = null; $urls['weekr'] = $bwdUrl . $queueName . '/weekly.gif'; $urls['weeks'] = null; $urls['monthr'] = $bwdUrl . $queueName . '/monthly.gif'; $urls['months'] = null; $urls['yearr'] = $bwdUrl . $queueName . '/yearly.gif'; $urls['years'] = null; } } //MikroTik Multigen DHCP if (ispos($bwdUrl, 'mlgmtdhcp')) { $bwdUrl = str_replace('mlgmtdhcp', 'graphs/queue/', $bwdUrl); $allUserMacs = zb_UserGetAllIpMACs(); if (isset($allUserMacs[$ip])) { $userMac = $allUserMacs[$ip]; $userMacUpper = strtoupper($userMac); $queueName = 'dhcp-ds<' . urlencode($userMacUpper); $urls['dayr'] = $bwdUrl . $queueName . '>/daily.gif'; $urls['days'] = null; $urls['weekr'] = $bwdUrl . $queueName . '>/weekly.gif'; $urls['weeks'] = null; $urls['monthr'] = $bwdUrl . $queueName . '>/monthly.gif'; $urls['months'] = null; $urls['yearr'] = $bwdUrl . $queueName . '>/yearly.gif'; $urls['years'] = null; } } } } } return ($urls); } /** * Renders user traffic charts * * @return string */ protected function renderCharts() { $result = ''; $bwd = $this->genGraphLinks(); $cachedUserCharts = array(); $cachedCharts = array(); $updateCache = false; $chartCategories = array( 'hour' => __('Hour'), 'day' => __('Graph by day'), 'week' => __('Graph by week'), 'month' => __('Graph by month'), 'year' => __('Graph by year'), ); if (!empty($bwd)) { $icon = wf_img_sized('skins/icon_stats.gif', '', '16', '16'); $result .= wf_delimiter(); $result .= wf_tag('h3') . __('Graphs') . wf_tag('h3', true); $bwcells = ''; $zbxExtended = (isset($bwd['zbxexten']) and $bwd['zbxexten'] == true); if ($zbxExtended) { $fiveminsbw = wf_img($bwd['5mins'], __('Downloaded')); $zbxLink = $bwd['zbxlink']; $zbxIcon = wf_img_sized('skins/zabbix_ico.png', '', '16', '16'); $bwcells .= wf_TableCell(wf_link($zbxLink, $zbxIcon . ' ' . __('Go to graph on Zabbix server'), false, 'ubButton', 'target="__blank"')); $bwcells .= wf_TableCell(wf_modalAuto($icon . ' ' . __('Graph by 5 minutes'), __('Graph by 5 minutes'), $fiveminsbw, 'ubButton')); } if ($this->ondemandFlag) { $cachedCharts = $this->cache->get(self::KEY_GRAPH, $this->cachingTimeout); if (!empty($cachedCharts)) { if (isset($cachedCharts[$this->login])) { $cachedUserCharts = $cachedCharts[$this->login]; } } else { $cachedCharts = array(); } } if ($this->ondemandFlag) { if (empty($cachedUserCharts)) { $updateCache = true; } } else { $updateCache = true; } //charts cats processing here if ($updateCache) { foreach ($chartCategories as $categoryId => $categoryTitle) { $chartBody = ''; $dlKey = $categoryId . 'r'; $ulKey = $categoryId . 's'; $chartTitle = $categoryTitle; if (isset($bwd[$dlKey])) { $imgLink = zb_BandwidthdImgLink($bwd[$dlKey]); $imgBody = wf_img_sized($imgLink, __('Downloaded'), '100%'); $chartBody .= $imgBody; } if (isset($bwd[$ulKey])) { $imgLink = zb_BandwidthdImgLink($bwd[$ulKey]); $imgBody = wf_delimiter() . wf_img_sized($imgLink, __('Uploaded'), '100%'); $chartBody .= $imgBody; } if (!empty($chartBody)) { if ($this->ondemandFlag) { $cachedCharts[$this->login][$categoryId] = array('title' => $chartTitle, 'body' => $chartBody); $defLink = $this->getAjChartLink($categoryId, $chartTitle); $bwcells .= wf_TableCell($defLink); } else { $chartBody = wf_tag('div', false, '', 'style="width:100%;"') . $chartBody . wf_tag('div', true); $bwcells .= wf_TableCell(wf_modalAuto($icon . ' ' . $chartTitle, $chartTitle, $chartBody, 'ubButton')); } } } //cache update if ($this->ondemandFlag) { $this->cache->set(self::KEY_GRAPH, $cachedCharts, $this->cachingTimeout); } } else { //deffered cache filled if ($this->ondemandFlag) { foreach ($chartCategories as $categoryId => $categoryTitle) { $defLink = $this->getAjChartLink($categoryId, $categoryTitle); $bwcells .= wf_TableCell($defLink); } } } // Adding graphs buttons to result: $bwrows = wf_TableRow($bwcells); $result .= wf_TableBody($bwrows, '', '0', ''); if ($this->ondemandFlag) { $result .= wf_AjaxLoader(); $result .= wf_AjaxContainer(self::AJ_CONTAINER); } $result .= wf_delimiter(); } return ($result); } /** * Returns link body for deffered charts loading * * @param string $graphCat * @param string $title * * @return string */ protected function getAjChartLink($graphCat, $title) { $result = ''; $icon = wf_img_sized('skins/icon_stats.gif', '', '16', '16'); $defUrl = self::URL_ME . '&' . self::ROUTE_AJUSER . '=' . $this->login . '&' . self::ROUTE_AJCAT . '=' . $graphCat; $result .= wf_AjaxLink($defUrl, $icon . ' ' . $title, self::AJ_CONTAINER, false, 'ubButton'); return ($result); } /** * Renders all previous months user traffic stats * * @return string */ protected function renderPrevMonthStats() { $result = ''; $ishimuraTable = 'mlg_ishimura'; $monthNames = months_array_wz(); $result .= wf_tag('h3') . __('Previous month traffic stats') . wf_tag('h3', true); $cells = wf_TableCell(__('Year')); $cells .= wf_TableCell(__('Month')); $cells .= wf_TableCell(__('Traffic classes')); $cells .= wf_TableCell(__('Downloaded')); $cells .= wf_TableCell(__('Uploaded')); $cells .= wf_TableCell(__('Total')); $cells .= wf_TableCell(__('Cash')); $rows = wf_TableRow($cells, 'row1'); if (!empty($this->dirs)) { foreach ($this->dirs as $dir) { $prevmonths = $this->getUserPrevMonthTraff($dir['rulenumber']); //and again no classes if ($dir['rulenumber'] == 0) { //ishimura traffic accounting? if ($this->ishimuraFlag) { $dataHideki = $this->ishimuraData; if (!empty($dataHideki)) { foreach ($dataHideki as $year => $month) { foreach ($month as $each) { foreach ($prevmonths as $ia => $stgEach) { if ($stgEach['year'] == $each['year'] and $stgEach['month'] == $each['month']) { $prevmonths[$ia]['D0'] += $each['D0']; $prevmonths[$ia]['U0'] += $each['U0']; } } } } } } //or just OphanimFlow integration? if ($this->ophanimFlag) { $ophRaw = $this->ophanimFlow->getUserAllTraff($this->login); if (!empty($ophRaw)) { foreach ($ophRaw as $io => $each) { foreach ($prevmonths as $ia => $stgEach) { if ($stgEach['year'] == $each['year'] and $stgEach['month'] == $each['month']) { $prevmonths[$ia]['D0'] += $each['D0']; $prevmonths[$ia]['U0'] += $each['U0']; } } } } } } if (!empty($prevmonths)) { $prevmonths = array_reverse($prevmonths); } if (!empty($prevmonths)) { foreach ($prevmonths as $prevmonth) { $cells = wf_TableCell($prevmonth['year']); $cells .= wf_TableCell(rcms_date_localise($monthNames[$prevmonth['month']])); $cells .= wf_TableCell($dir['rulename']); $cells .= wf_TableCell(stg_convert_size($prevmonth['D' . $dir['rulenumber']]), '', '', 'sorttable_customkey="' . $prevmonth['D' . $dir['rulenumber']] . '"'); $cells .= wf_TableCell(stg_convert_size($prevmonth['U' . $dir['rulenumber']]), '', '', 'sorttable_customkey="' . $prevmonth['U' . $dir['rulenumber']] . '"'); $cells .= wf_TableCell(stg_convert_size(($prevmonth['U' . $dir['rulenumber']] + $prevmonth['D' . $dir['rulenumber']])), '', '', 'sorttable_customkey="' . ($prevmonth['U' . $dir['rulenumber']] + $prevmonth['D' . $dir['rulenumber']]) . '"'); $cells .= wf_TableCell(round($prevmonth['cash'], 2)); $rows .= wf_TableRow($cells, 'row3'); } } } } $result .= wf_TableBody($rows, '100%', '0', 'sortable'); return ($result); } /** * Generates user`s traffic full statistics report * * @param string $login * * @return string */ public function renderUserTraffStats() { $result = ''; $this->loadUserData(); if (!empty($this->userData)) { $this->loadDirs(); $this->loadTraffStats(); $this->loadIshimuraStats(); // Current month traffic stats $result .= $this->renderCurMonthStats(); // Some charts here $result .= $this->renderCharts(); // Traffic statistic by previous months $result .= $this->renderPrevMonthStats(); // and some user controls $result .= web_UserControls($this->login); } else { $result .= $this->messages->getStyledMessage(__('Strange exception') . ': EMPTY_DATABASE_USERDATA', 'error'); $result .= wf_delimiter(0); $result .= wf_tag('center') . wf_img('skins/unicornwrong.png') . wf_tag('center', true); $result .= wf_delimiter(); } return ($result); } /** * Catches image proxy request and renders some image * * @return void */ public function catchImgProxyRequest() { if ($this->altCfg['BANDWIDTHD_PROXY']) { if (ubRouting::checkGet(self::ROUTE_PROX_IMG)) { $remoteImageUrl = base64_decode(ubRouting::get(self::ROUTE_PROX_IMG)); $remoteImageUrl = trim($remoteImageUrl); if (!empty($remoteImageUrl)) { $remoteImg = new OmaeUrl($remoteImageUrl); $remoteImg->setTimeout(1); $rawImg = $remoteImg->response(); $recvErr = $remoteImg->error(); $type = ''; if (ispos($remoteImageUrl, '.png') or ispos($remoteImageUrl, 'module=graph')) { $type = 'png'; } else { if (ispos($remoteImageUrl, '.gif')) { $type = 'gif'; } } if (empty($recvErr) and !ispos($rawImg, '404')) { if (!empty($type)) { header('Content-Type: image/' . $type); } die($rawImg); } else { header('Content-Type: image/jpeg'); $noImage = file_get_contents('skins/noimage.jpg'); die($noImage); } } else { header('Content-Type: image/jpeg'); $noImage = file_get_contents('skins/noimage.jpg'); die($noImage); } } } } /** * Renders deffered chart request data * * @return void */ public function catchDefferedCallback() { $result = ''; $notice = __('Something went wrong') . ': '; if ($this->ondemandFlag) { if (ubRouting::checkGet(array(self::ROUTE_AJUSER, self::ROUTE_AJCAT))) { $userLogin = ubRouting::get(self::ROUTE_AJUSER, 'mres'); $chartCat = ubRouting::get(self::ROUTE_AJCAT, 'mres'); if ($userLogin and $chartCat) { $cachedCharts = $this->cache->get(self::KEY_GRAPH, $this->cachingTimeout); if (!empty($cachedCharts)) { if (isset($cachedCharts[$userLogin])) { $userCache = $cachedCharts[$userLogin]; if (isset($userCache[$chartCat])) { $styling = 'width:1540px; height:810px; border:0px solid;'; $chartBody = wf_tag('div', false, '', 'style="' . $styling . '"') . $userCache[$chartCat]['body'] . wf_tag('div', true); $result .= wf_modalOpenedAuto($userCache[$chartCat]['title'], $chartBody); } else { $result .= $this->messages->getStyledMessage($notice . __('no cached cat') . ' [' . $chartCat . ']', 'error'); } } else { $result .= $this->messages->getStyledMessage($notice . __('No user charts'), 'error'); } } else { $result .= $this->messages->getStyledMessage($notice . __('Empty charts cache'), 'error'); } } else { $result .= $this->messages->getStyledMessage($notice . __('Empty params'), 'error'); } } else { $result .= $this->messages->getStyledMessage($notice . __('Missed params'), 'error'); } } else { $result .= $this->messages->getStyledMessage($notice . __('Disabled'), 'error'); } die($result); } //TODO: refactor following two methods of global traffic report. They was backported as is. /** * Renders the global traffic report. * * This method retrieves traffic data for each traffic class and generates a report. * It calculates the total traffic for each class by summing the download and upload traffic values from the 'users' table. * If the traffic class is 0, it also includes additional traffic data from the 'ishimura' table and the 'ophanim' flow. * * @return string */ public function renderTrafficReport() { $ishimuraOption = MultiGen::OPTION_ISHIMURA; $ishimuraTable = MultiGen::NAS_ISHIMURA; $allclasses = zb_DirectionsGetAll(); $classtraff = array(); $traffCells = wf_TableCell(__('Traffic classes'), '20%'); $traffCells .= wf_TableCell(__('Traffic'), '20%'); $traffCells .= wf_TableCell(__('Traffic classes')); $traffRows = wf_TableRow($traffCells, 'row1'); if (!empty($allclasses)) { foreach ($allclasses as $eachclass) { $d_name = 'D' . $eachclass['rulenumber']; $u_name = 'U' . $eachclass['rulenumber']; $query_d = "SELECT SUM(`" . $d_name . "`) FROM `users`"; $query_u = "SELECT SUM(`" . $u_name . "`) FROM `users`"; $classdown = simple_query($query_d); $classdown = $classdown['SUM(`' . $d_name . '`)']; $classup = simple_query($query_u); $classup = $classup['SUM(`' . $u_name . '`)']; $classtraff[$eachclass['rulename']] = $classdown + $classup; //Yep, no traffic classes at all. Just internet accounting here. if ($eachclass['rulenumber'] == 0) { //ishimura data if ($this->altCfg[$ishimuraOption]) { $query_hideki = "SELECT SUM(`D0`) as `downloaded`, SUM(`U0`) as `uploaded` from `" . $ishimuraTable . "` WHERE `month`='" . date("n") . "' AND `year`='" . curyear() . "'"; $dataHideki = simple_query($query_hideki); if (isset($classtraff[$eachclass['rulename']])) { @$classtraff[$eachclass['rulename']] += $dataHideki['downloaded'] + $dataHideki['uploaded']; } else { $classtraff[$eachclass['rulename']] = $dataHideki['downloaded'] + $dataHideki['uploaded']; } } //or ophanim flow may be? if ($this->altCfg[OphanimFlow::OPTION_ENABLED]) { $ophanim = new OphanimFlow(); $ophTraff = $ophanim->getAllUsersAggrTraff(); if (!empty($ophTraff)) { foreach ($ophTraff as $io => $each) { $classtraff[$eachclass['rulename']] += $each; } } } } } if (!empty($classtraff)) { $total = max($classtraff); foreach ($classtraff as $name => $count) { $traffCells = wf_TableCell($name); $traffCells .= wf_TableCell(stg_convert_size($count), '', '', 'sorttable_customkey="' . $count . '"'); $traffCells .= wf_TableCell(web_bar($count, $total), '', '', 'sorttable_customkey="' . $count . '"'); $traffRows .= wf_TableRow($traffCells, 'row3'); } } } $result = wf_TableBody($traffRows, '100%', 0, 'sortable'); return ($result); } /** * Renders the traffic report NAS charts. * * This method retrieves the NAS list with bandwidthd set up and generates charts for each NAS. * The charts include daily, weekly, monthly, and yearly traffic data. * * @return string */ public function renderTrafficReportNasCharts() { // Get NAS list with bandwidth setted up: $query = 'SELECT * FROM `nas` WHERE `bandw` != "" GROUP by `bandw`'; $result = simple_queryall($query); // Check presence of any entry: if (!empty($result)) { $graphRows = null; foreach ($result as $nas) { $bwd = $nas['bandw']; switch ($nas['nastype']) { case 'local': case 'radius': case 'rscriptd': //normal bandwidthd if (!ispos($bwd, 'mlgmths') and !ispos($bwd, 'mlgmtppp') and !ispos($bwd, 'mlgmtdhcp')) { // Extention: $ext = '.png'; // Modals: $width = 940; $height = 666; // Links: $d_day = $bwd . 'Total-1-R' . $ext; $d_week = $bwd . 'Total-2-R' . $ext; $d_month = $bwd . 'Total-3-R' . $ext; $d_year = $bwd . 'Total-4-R' . $ext; $u_day = $bwd . 'Total-1-S' . $ext; $u_week = $bwd . 'Total-2-S' . $ext; $u_month = $bwd . 'Total-3-S' . $ext; $u_year = $bwd . 'Total-4-S' . $ext; //OphanimFlow graphs if (ispos($bwd, 'OphanimFlow') or ispos($bwd, 'of/')) { $width = 1540; //defaults $height = 400; $offsetX = 60; //window size offsets $offsetY = 60; $custParams = ''; $customDimensions = $this->getOphCustomDimensions(true); if ($customDimensions) { $custParams = $this->getOphCustomDimensions(false); //as string $width = $customDimensions['w']; $height = $customDimensions['h']; } $d_day = $bwd . '/?module=graph&ip=0.0.0.0&dir=R&period=day' . $custParams; $d_week = $bwd . '/?module=graph&ip=0.0.0.0&dir=R&period=week' . $custParams; $d_month = $bwd . '/?module=graph&ip=0.0.0.0&dir=R&period=month' . $custParams; $d_year = $bwd . '/?module=graph&ip=0.0.0.0&dir=R&period=year' . $custParams; $u_day = $bwd . '/?module=graph&ip=0.0.0.0&dir=S&period=day' . $custParams; $u_week = $bwd . '/?module=graph&ip=0.0.0.0&dir=S&period=week' . $custParams; $u_month = $bwd . '/?module=graph&ip=0.0.0.0&dir=S&period=month' . $custParams; $u_year = $bwd . '/?module=graph&ip=0.0.0.0&dir=S&period=year' . $custParams; $width = $width + $offsetX; $height = ($height * 2) + ($offsetY * 2); } $daygraph = __('Downloaded') . wf_img(zb_BandwidthdImgLink($d_day)) . wf_tag('br') . __('Uploaded') . wf_tag('br') . wf_img(zb_BandwidthdImgLink($u_day)); $weekgraph = __('Downloaded') . wf_img(zb_BandwidthdImgLink($d_week)) . wf_tag('br') . __('Uploaded') . wf_tag('br') . wf_img(zb_BandwidthdImgLink($u_week)); $monthgraph = __('Downloaded') . wf_img(zb_BandwidthdImgLink($d_month)) . wf_tag('br') . __('Uploaded') . wf_tag('br') . wf_img(zb_BandwidthdImgLink($u_month)); $yeargraph = __('Downloaded') . wf_img(zb_BandwidthdImgLink($d_year)) . wf_tag('br') . __('Uploaded') . wf_tag('br') . wf_img(zb_BandwidthdImgLink($u_year)); $graphLegend = wf_tag('br') . wf_img('skins/bwdlegend.gif'); } else { //Multigen Mikrotik hotspot $bwd = str_replace('mlgmths', 'graphs/iface/bridge', $bwd); $bwd = str_replace('mlgmtppp', 'graphs/iface/bridge', $bwd); $bwd = str_replace('mlgmtdhcp', 'graphs/iface/bridge', $bwd); $ext = '.gif'; $daily = $bwd . '/daily' . $ext; $weekly = $bwd . '/weekly' . $ext; $monthly = $bwd . '/monthly' . $ext; $yearly = $bwd . '/yearly' . $ext; // Modals: $width = 530; $height = 250; $daygraph = wf_img(zb_BandwidthdImgLink($daily)); $weekgraph = wf_img(zb_BandwidthdImgLink($weekly)); $monthgraph = wf_img(zb_BandwidthdImgLink($monthly)); $yeargraph = wf_img(zb_BandwidthdImgLink($yearly)); $graphLegend = ''; } break; case 'mikrotik': if (!ispos($bwd, 'pppoe')) { $options = zb_NasOptionsGet($nas['id']); if (!empty($options['graph_interface'])) { // Extention: $ext = '.gif'; // Links: $daily = $bwd . '/../iface/' . $options['graph_interface'] . '/daily' . $ext; $weekly = $bwd . '/../iface/' . $options['graph_interface'] . '/weekly' . $ext; $monthly = $bwd . '/../iface/' . $options['graph_interface'] . '/monthly' . $ext; $yearly = $bwd . '/../iface/' . $options['graph_interface'] . '/yearly' . $ext; // Modals: $width = 530; $height = 230; $daygraph = wf_img($daily); $weekgraph = wf_img($weekly); $monthgraph = wf_img($monthly); $yeargraph = wf_img($yearly); $graphLegend = ''; break; } else { show_error(__('For NAS') . ' `' . $nas['nasname'] . '` ' . __('was not set correct graph interface')); } } else { $width = 530; $height = 230; $daygraph = ''; $weekgraph = ''; $monthgraph = ''; $yeargraph = ''; $graphLegend = ''; } } if (!ispos($bwd, 'OphanimFlow') and !ispos($bwd, 'of/')) { $graphLegend = wf_tag('br') . wf_img('skins/bwdlegend.gif'); } else { $graphLegend = ''; } // Buttons: $gday = wf_modal(__('Graph by day'), __('Graph by day'), $daygraph . $graphLegend, '', $width, $height); $gweek = wf_modal(__('Graph by week'), __('Graph by week'), $weekgraph . $graphLegend, '', $width, $height); $gmonth = wf_modal(__('Graph by month'), __('Graph by month'), $monthgraph . $graphLegend, '', $width, $height); $gyear = wf_modal(__('Graph by year'), __('Graph by year'), $yeargraph . $graphLegend, '', $width, $height); // Put buttons to table row: $graphCells = wf_TableCell($nas['nasname'], '', 'row2'); $graphCells .= wf_TableCell($gday); $graphCells .= wf_TableCell($gweek); $graphCells .= wf_TableCell($gmonth); $graphCells .= wf_TableCell($gyear); $graphRows .= wf_TableRow($graphCells, 'row3'); } $result = wf_TableBody($graphRows, '100%', 0, ''); } else { $result = ''; } return ($result); } } |