123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242 |
- <?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 ROUTE_EXPLICT = 'explict';
- const PROUTE_DATE_FROM = 'datefrom';
- const PROUTE_DATE_TO = 'dateto';
- const PROUTE_TIME_FROM = 'timefrom';
- const PROUTE_TIME_TO = 'timeto';
- 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'));
- $ofUseMikrotikGraphs = wf_getBoolFromVar($ubillingConfig->getAlterParam('OPHANIM_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' and !$ofUseMikrotikGraphs) {
- // 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;
- $urls['explict'] = $bwdUrl . '/?module=graph&period=explict&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);
- }
- /**
- * Returns explict time interval selection form and results
- *
- * @param string $explictUrl base64 encoded base charts URL
- *
- * @return void
- */
- public function renderExplictChartsForm($explictUrl) {
- $result = '';
- if (!empty($explictUrl)) {
- $baseUrl = base64_decode($explictUrl);
- $dateFrom = (ubRouting::checkPost(self::PROUTE_DATE_FROM)) ? ubRouting::post(self::PROUTE_DATE_FROM) : curdate();
- $dateTo = (ubRouting::checkPost(self::PROUTE_DATE_TO)) ? ubRouting::post(self::PROUTE_DATE_TO) : curdate();
- $timeFrom = (ubRouting::checkPost(self::PROUTE_TIME_FROM)) ? ubRouting::post(self::PROUTE_TIME_FROM) : '00:00';
- $timeTo = (ubRouting::checkPost(self::PROUTE_TIME_TO)) ? ubRouting::post(self::PROUTE_TIME_TO) : '23:59';
- $timestampFrom = strtotime($dateFrom . ' ' . $timeFrom . ':00');
- $timestampTo = strtotime($dateTo . ' ' . $timeTo . ':59');
- //interval selection form here
- $inputs = '';
- $inputs .= __('From') . ': ';
- $inputs .= wf_DatePickerPreset(self::PROUTE_DATE_FROM, $dateFrom, true);
- $inputs .= wf_TimePickerPreset(self::PROUTE_TIME_FROM, $timeFrom);
- $inputs .= __('To') . ': ';
- $inputs .= wf_DatePickerPreset(self::PROUTE_DATE_TO, $dateTo, true);
- $inputs .= wf_TimePickerPreset(self::PROUTE_TIME_TO, $timeTo) . ' ';
- $inputs .= wf_Submit(__('Show'));
- $result .= wf_Form('', 'POST', $inputs, 'glamour');
- //charts rendering
- if ($timestampFrom <= $timestampTo) {
- $completeUrl = $baseUrl . '&from=' . $timestampFrom . '&to=' . $timestampTo;
- $downloadUrl = zb_BandwidthdImgLink(($completeUrl . '&dir=R'));
- $uploadUrl = zb_BandwidthdImgLink(($completeUrl . '&dir=S'));
- $result .= wf_delimiter();
- $result .= wf_img_sized($downloadUrl, __('Downloaded'), '100%');
- $result .= wf_delimiter(0);
- $result .= wf_img_sized($uploadUrl, __('Uploaded'), '100%');
- } else {
- $result .= $this->messages->getStyledMessage(__('Wrong date format'), 'error');
- $result .= wf_delimiter(0);
- $result .= wf_tag('center') . wf_img('skins/unicornwrong.png') . wf_tag('center', true);
- $result .= wf_delimiter();
- }
- }
- $result .= wf_delimiter();
- $result .= wf_BackLink(self::URL_ME . '&' . self::ROUTE_LOGIN . '=' . $this->login);
- return ($result);
- }
- /**
- * 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_link($zbxLink, $zbxIcon . ' ' . __('Go to graph on Zabbix server'), false, 'ubButton', 'target="__blank"');
- $bwcells .= 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 .= $defLink;
- } else {
- $chartBody = wf_tag('div', false, '', 'style="width:100%;"') . $chartBody . wf_tag('div', true);
- $bwcells .= 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);
- }
- }
- }
- // Explict ophanim charts controls here
- if (isset($bwd['explict'])) {
- $encUrl = base64_encode($bwd['explict']);
- $explictUrl = self::URL_ME . '&' . self::ROUTE_LOGIN . '=' . $this->login . '&' . self::ROUTE_EXPLICT . '=' . $encUrl;
- $bwcells .= wf_Link($explictUrl, web_icon_calendar() . ' ' . __('Explict interval'), false, 'ubButton');
- }
- // Adding graphs buttons to result:
- $result .= $bwcells;
- 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);
- }
- }
|