dbFields = array( 'label' => $L->g('Visits'), 'excludeAdmins' => false ); } public function adminHead() { if ($GLOBALS['ADMIN_VIEW'] !== 'dashboard') { return false; } $html = $this->includeCSS('chart.min.css'); $html .= $this->includeJS('chart.bundle.min.js'); return $html; } // Plugin form for settings public function form() { global $L; $html = '
'; $html .= ''; $html .= ''; $html .= '
' . $L->get('This title is almost always used in the sidebar of the site') . '
'; $html .= '
'; if (defined('BLUDIT_PRO')) { $html .= '
'; $html .= ''; $html .= ''; $html .= '
'; } return $html; } public function siteBodyEnd() { $currentDate = Date::current('Y-m-d'); $isNewDay = !file_exists($this->workspace() . $currentDate . '.log'); $visitorAdded = $this->addVisitor(); if ($isNewDay && $visitorAdded) { $this->deleteOldLogs(); } } // Delete log files older than 7 days public function deleteOldLogs() { $logs = Filesystem::listFiles($this->workspace(), '*', 'log', false); rsort($logs); $remove = array_slice($logs, 7); foreach ($remove as $log) { Filesystem::rmfile($log); } } // Returns the number of visits for a given date (YYYY-MM-DD) public function visits($date) { $file = $this->workspace() . $date . '.log'; if (!file_exists($file)) { return 0; } $handle = @fopen($file, 'rb'); if ($handle === false) { return 0; } // The amount of visits is the number of lines on the file $lines = 0; while (!feof($handle)) { $lines += substr_count(fread($handle, 8192), PHP_EOL); } @fclose($handle); return $lines; } // Returns the number of unique visitors for a given date (YYYY-MM-DD) public function uniqueVisitors($date) { $file = $this->workspace() . $date . '.log'; if (!file_exists($file)) { return 0; } $lines = @file($file); if (empty($lines)) { return 0; } $seen = array(); foreach ($lines as $line) { $data = json_decode($line, true); if (is_array($data) && isset($data[0]) && is_string($data[0]) && $data[0] !== '') { $seen[$data[0]] = true; } } return count($seen); } // Single-pass read of a day log returning [total, unique] private function readCounts($date) { $file = $this->workspace() . $date . '.log'; if (!file_exists($file)) { return array(0, 0); } $handle = @fopen($file, 'rb'); if ($handle === false) { return array(0, 0); } $total = 0; $seen = array(); while (($line = fgets($handle)) !== false) { $total++; $data = json_decode($line, true); if (is_array($data) && isset($data[0]) && is_string($data[0]) && $data[0] !== '') { $seen[$data[0]] = true; } } @fclose($handle); return array($total, count($seen)); } // Returns visits and unique-visitor counts for the last $days days // Returns ['labels'=>[], 'visits'=>[], 'unique'=>[], 'total'=>int] public function getLastDaysData($days = 7) { $result = array('labels' => array(), 'visits' => array(), 'unique' => array(), 'total' => 0); for ($i = $days - 1; $i >= 0; $i--) { $date = Date::currentOffset('Y-m-d', '-' . $i . ' day'); list($v, $u) = $this->readCounts($date); $result['labels'][] = Date::format($date, 'Y-m-d', 'D'); $result['visits'][] = $v; $result['unique'][] = $u; $result['total'] += $v; } return $result; } // Add a line to the current day log file public function addVisitor() { global $security; if (Cookie::get('BLUDIT-KEY') && defined('BLUDIT_PRO') && $this->getValue('excludeAdmins')) { return false; } $currentTime = Date::current('Y-m-d H:i:s'); $ip = $security->getUserIp(); $hashIP = md5($ip); $line = json_encode(array($hashIP, $currentTime)); $currentDate = Date::current('Y-m-d'); $logFile = $this->workspace() . $currentDate . '.log'; return file_put_contents($logFile, $line . PHP_EOL, FILE_APPEND | LOCK_EX) !== false; } }