* @license GPL 2 (http://www.gnu.org/licenses/gpl.html) */ class helper_plugin_statdisplay_table extends DokuWiki_Plugin { /** @var helper_plugin_statdisplay_log */ private $log = null; /** @var Doku_Renderer */ private $R = null; /** * @param Doku_Renderer $R * @param string $command type of statistic * @param string $from restrict to this month * @param string $to end interval * @return void */ public function table($R, $command, $from = '', $to = '') { $this->R = $R; $this->log = plugin_load('helper', 'statdisplay_log'); switch ($command) { case 'all': $this->summary($from, $to); break; case 'one month': $this->month($from); break; case 'month by day': $this->monthby('day', $from); break; case 'month by hour': $this->monthby('hour', $from); break; case 'top referers': $this->referer($from); break; case 'top entries': $this->entry($from); break; case 'top urls': $this->url($from); break; case 'top bytes': break; case 'user agents': $this->ua($from); break; case 'progress bar': $this->progress(); break; case 'traffic by user': $this->userdownloads($from); break; default: $R->cdata('No such table: ' . $command); } } private function progress() { $pct = sprintf('%.2f', $this->log->progress()); $this->R->doc .= '
'; } /** * Print referers for a given month * * @param string $date */ private function referer($date = '') { if (!$date) $date = date('Y-m'); $this->listtable( $this->log->logdata[$date]['referer_url'], $this->log->logdata[$date]['referer']['count'], sprintf($this->getLang('t_topReferrer'), $date) ); } /** * Print top entry pages for a given month * * @param string $date */ private function entry($date = '') { if (!$date) $date = date('Y-m'); $this->listtable( $this->log->logdata[$date]['entry'], $this->log->logdata[$date]['page']['all']['count'], sprintf($this->getLang('t_topEntry'), $date) ); } /** * Print top user agents for a given month * * @param string $date */ private function ua($date = '') { if (!$date) $date = date('Y-m'); $this->listtable( $this->log->logdata[$date]['useragent'], $this->log->logdata[$date]['page']['all']['count'], sprintf($this->getLang('t_topUserAgents'), $date) ); } /** * Print top pages for a given month * * @param string $date */ private function url($date = '') { if (!$date) $date = date('Y-m'); $this->listtable( $this->log->logdata[$date]['page_url'], $this->log->logdata[$date]['page']['all']['count'], sprintf($this->getLang('t_topPages'), $date) ); } /** * Print daily or hourly statistics * * @param string $by either 'day' or 'hour' * @param string $date */ private function monthby($by, $date = '') { if (!$date) $date = date('Y-m'); $data = $this->log->logdata[$date]; $title = sprintf($this->getLang('t_' . $by), $date); $this->R->table_open(); $this->R->tablerow_open(); $this->head($title, 11); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->head($this->getLang($by)); $this->head($this->getLang('hits'), 2); $this->head($this->getLang('media'), 2); $this->head($this->getLang('pages'), 2); $this->head($this->getLang('visitors'), 2); $this->head($this->getLang('traffic'), 2); $this->R->tablerow_close(); $keys = array_keys((array)$data['hits'][$by]); sort($keys); foreach ($keys as $idx) { $this->R->tablerow_open(); $this->hcell($idx); $this->cell($data['hits'][$by][$idx]['count']); $this->cell($this->pct($data['hits'][$by][$idx]['count'], $data['hits']['all']['count'])); $this->cell($data['media'][$by][$idx]['count']); $this->cell($this->pct($data['media'][$by][$idx]['count'], $data['media']['all']['count'])); $this->cell($data['page'][$by][$idx]['count']); $this->cell($this->pct($data['page'][$by][$idx]['count'], $data['page']['all']['count'])); $this->cell($data['hits'][$by][$idx]['visitor']); $this->cell($this->pct($data['hits'][$by][$idx]['visitor'], $data['hits']['all']['visitor'])); $this->cell(filesize_h($data['hits'][$by][$idx]['bytes'])); $this->cell($this->pct($data['hits'][$by][$idx]['bytes'], $data['hits']['all']['bytes'])); $this->R->tablerow_close(); } $this->R->table_close(); } /** * print a single month * * @param $date */ private function month($date = '') { if (!$date) $date = date('Y-m'); $data = $this->log->logdata[$date]; $this->R->table_open(); $this->R->tablerow_open(); $this->head(sprintf($this->getLang('t_statisticMonth'), $date), 3); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('totalHits')); $this->cell($data['page']['all']['count'] + $data['media']['all']['count'], 2); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('totalFiles')); $this->cell($data['media']['all']['count'], 2); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('totalPages')); $this->cell($data['page']['all']['count'], 2); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('totalVisitors')); $this->cell($data['page']['all']['visitor'], 2); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('totalBytes')); $this->cell(filesize_h($data['page']['all']['bytes']), 2); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->head(''); $this->head($this->getLang('avg')); $this->head($this->getLang('max')); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('hitsHour')); $this->cell($this->log->avg($data['hits']['hour'], 'count')); $this->cell($this->log->max($data['hits']['hour'], 'count')); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('hitsDay')); $this->cell($this->log->avg($data['hits']['day'], 'count')); $this->cell($this->log->max($data['hits']['day'], 'count')); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('filesDay')); $this->cell($this->log->avg($data['media']['day'], 'count')); $this->cell($this->log->max($data['media']['day'], 'count')); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('pagesDay')); $this->cell($this->log->avg($data['page']['day'], 'count')); $this->cell($this->log->max($data['page']['day'], 'count')); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->hcell($this->getLang('bytesDay')); $this->cell(filesize_h($this->log->avg($data['hits']['day'], 'bytes'))); $this->cell(filesize_h($this->log->max($data['hits']['day'], 'bytes'))); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->head($this->getLang('hitsStatusCode'), 3); $this->R->tablerow_close(); foreach ((array)$this->log->logdata[$date]['status']['all'] as $code => $count) { $this->R->tablerow_open(); $this->hcell('Status ' . $code . ' - ' . $this->getLang('status_' . $code)); $this->cell($count, 2); $this->R->tablerow_close(); } $this->R->table_close(); } /** * print the whole summary table * * @param string $from unused * @param string $to unsused */ private function summary($from = '', $to = '') { $this->R->table_open(); $this->R->tablerow_open(); $this->head($this->getLang('summaryMonth'), 10); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->head($this->getLang('month'), 1, 2); $this->head($this->getLang('dailyavg'), 4); $this->head($this->getLang('totals'), 5); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->head($this->getLang('hits')); $this->head($this->getLang('files')); $this->head($this->getLang('pages')); $this->head($this->getLang('visitors')); $this->head($this->getLang('hits')); $this->head($this->getLang('files')); $this->head($this->getLang('pages')); $this->head($this->getLang('visitors')); $this->head($this->getLang('bytes')); $this->R->tablerow_close(); foreach ((array)$this->log->logdata as $month => $data) { if ($month[0] == '_') continue; if (!empty($from) && $month < $from) continue; if (!empty($to) && $month > $to) break; $this->R->tablerow_open(); $this->cell($month, 1, false); // Month // ---- averages ---- $this->cell(round($this->log->avg($data['hits']['day'] ?? [], 'count'))); // Hits $this->cell(round($this->log->avg($data['media']['day'] ?? [], 'count'))); // Files $this->cell(round($this->log->avg($data['page']['day'] ?? [], 'count'))); // Pages $this->cell(round($this->log->avg($data['hits']['day'] ?? [], 'visitor'))); // Visits // ---- totals ---- $this->cell($data['hits']['all']['count']); // Hits $this->cell($data['media']['all']['count']); // Files $this->cell($data['page']['all']['count']); // Pages $this->cell($data['hits']['all']['visitor']); // Visitors $this->cell(filesize_h($data['hits']['all']['bytes'])); // kBytes $this->R->tablerow_close(); } $this->R->table_close(); } /** * @param string $date month to display */ private function userdownloads($date) { $usertraffic = $this->log->usertraffic($date); $this->listtable($usertraffic, $this->log->sum($usertraffic), $this->getLang('t_usertraffic'), true); } /** * Print a simple listing table * * @param array $data * @param float $max * @param string $title * @param bool $istraffic * @return void */ private function listtable(&$data, $max, $title, $istraffic = false) { if (!$data) $data = array(); arsort($data); $row = 1; $this->R->table_open(); $this->R->tablerow_open(); $this->head($title, 4); $this->R->tablerow_close(); $this->R->tablerow_open(); $this->head('#'); $this->head($this->getLang('name')); if ($istraffic) { $this->head($this->getLang('traffic'), 2); } else { $this->head($this->getLang('hits'), 2); } $this->R->tablerow_close(); foreach ($data as $key => $count) { if ($istraffic) { $val = filesize_h($count); } else { $val = $count; } $this->R->tablerow_open(); $this->cell($row); $this->hcell($key); $this->cell($val); $this->cell($this->pct($count, $max)); $this->R->tablerow_close(); $row++; if ($row > $this->log->top_limit) break; } $this->R->table_close(); } /** * Calculate and format a percent value * * @param $val * @param $max * @return string */ private function pct($val, $max) { if (!$max) return '0.00%'; return sprintf("%.2f%%", $val * 100 / $max); } /** * print a table header cell * * @param string $data * @param int $col * @param int $row */ private function head($data = '', $col = 1, $row = 1) { $this->R->tableheader_open($col, 'center', $row); $this->R->cdata($data); $this->R->tableheader_close(); } /** * print a non numeric data cell * * @param string $data * @param int $span */ private function hcell($data = '', $span = 1) { $this->cell($data, $span, false); } /** * print a numeric data cell * * @param string $data * @param int $span * @param bool $number */ private function cell($data = '', $span = 1, $number = true) { if ($number) { if (!$data) $data = 0; $align = 'right'; } else { $align = null; } $this->R->tablecell_open($span, $align); $this->R->cdata($data); $this->R->tablecell_close(); } }