dbFields = array(
'enableOngoingCounter'=>false,
'resetOngoingCounterValue'=>'-1',
'chartType'=>'Weekly',
'numberOfDaysToKeep'=>7,
'numberOfWeeksToKeep'=>7,
'numberOfMonthsToKeep'=>13,
'showContentStats'=>false,
'pageSessionActiveMinutes'=>60,
'excludeAdmins'=>false
);
}
public function form()
{
global $L;
$html = '
';
$html .= $this->description();
$html .= '
';
// Define ongoing running total counter
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('ongoing-counter-tip').'';
$html .= '
';
// Controls the resetting of the ongoing counter
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('reset-counter-tip-one').'';
$html .= ''.$L->get('reset-counter-tip-two').'';
$html .= '
';
// Define the chart type
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('chart-type-tip').'';
$html .= '
';
// Define how long to keep stats. Zero also turns unwanted collections off.
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('number-of-days-tip').'';
$html .= '
';
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('number-of-weeks-tip').'';
$html .= '
';
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('number-of-months-tip').'';
$html .= '
';
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('show-content-stats-tip').'';
$html .= '
';
$html .= '';
$html .= '';
$html .= '';
$html .= ''.$L->get('page-session-active-minutes-tip').'';
$html .= '
';
// For uses of BLUDIT PRO
if (defined('BLUDIT_PRO')) {
$html .= '';
$html .= '';
$html .= '';
$html .= '
';
}
return $html;
}
public function beforeSiteLoad()
{
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
}
public function adminHead()
{
if (!in_array($GLOBALS['ADMIN_CONTROLLER'], $this->loadOnController)) {
return false;
}
// Include plugin's CSS files
$html = $this->includeCSS('chartist.min.css');
$html .= $this->includeCSS('style.css');
// Include plugin's Javascript files
$html .= $this->includeJS('chartist.min.js');
return $html;
}
public function dashboard()
{
global $L;
$currentDate = Date::current('Y-m-d');
$mondayDateThisWeek = date("Y-m-d", strtotime('monday this week'));
$firstDateOfThisThisMonth = date("Y-m-d", strtotime('first day of this month'));
$pageViewsToday = $this->getPageViewCount($currentDate, 'Daily');
$uniqueVisitorsToday = $this->getUniqueVisitorCount($currentDate, 'Daily');
$pageViewsThisWeek = $this->getPageViewCount($mondayDateThisWeek, 'Weekly');
$uniqueVisitorsThisWeek = $this->getUniqueVisitorCount($mondayDateThisWeek, 'Weekly');
$pageViewsThisMonth = $this->getPageViewCount($firstDateOfThisThisMonth, 'Monthly');
$uniqueVisitorsThisMonth = $this->getUniqueVisitorCount($firstDateOfThisThisMonth, 'Monthly');
$chartType = $this->getValue('chartType');
$runningTotals = json_decode(file_get_contents($this->workspace().'running-totals.json'),TRUE);
$pageCount = $runningTotals['runningTotals']['pageCounter'];
IF ($chartType == 'Monthly') {
$offsetNumber = $numberOfMonthsToKeep = $this->getValue('numberOfMonthsToKeep');
$chartStartDate = date('Y-m-d' , strtotime ( '-'.$offsetNumber.' month' , strtotime ( $firstDateOfThisThisMonth ) ) );
$chartEndDate = date("Y-m-d", strtotime ( $firstDateOfThisThisMonth ) );
}
ELSEIF ($chartType == 'Weekly') {
$offsetNumber = $numberOfWeeksToKeep = $this->getValue('numberOfWeeksToKeep');
$chartStartDate = date('Y-m-d' , strtotime ( '-'.$offsetNumber.' week' , strtotime ( $mondayDateThisWeek ) ) );
$chartEndDate = date("Y-m-d", strtotime ( $mondayDateThisWeek ) );
}
ELSE { // $chartType == 'Daily'
$offsetNumber = $numberOfDaysToKeep = $this->getValue('numberOfDaysToKeep');
$chartStartDate = date('Y-m-d' , strtotime ( '-'.$offsetNumber.' week' , strtotime ( $currentDate ) ) );
$chartEndDate = date("Y-m-d", strtotime ( $currentDate) );
}
$html = <<
$chartType {$L->get('stats-title-label')}($chartStartDate - $chartEndDate)
Total Page Count: $pageCount
{$L->get('page-view-today-label')}: $pageViewsToday
{$L->get('unique-visitors-today-label')}: $uniqueVisitorsToday
{$L->get('page-view-this-week-label')}: $pageViewsThisWeek
{$L->get('unique-visitors-this-week-label')}: $uniqueVisitorsThisWeek
{$L->get('page-view-this-month-label')}: $pageViewsThisMonth
{$L->get('unique-visitors-this-month-label')}: $uniqueVisitorsThisMonth
EOF;
IF ($chartType == 'Monthly') {
$numberOfMonthsToKeep = $this->getValue('numberOfMonthsToKeep');
$numberOfMonthsToKeep = $numberOfMonthsToKeep - 1;
for ($i=$numberOfMonthsToKeep; $i >= 0 ; $i--) {
$dateWithOffset = date('Y-m-d' , strtotime ( '-'.$i.' month' , strtotime ( $firstDateOfThisThisMonth ) ) );
$visits[$i] = $this->getPageViewCount($dateWithOffset, 'Monthly');
$unique[$i] = $this->getUniqueVisitorCount($dateWithOffset, 'Monthly');
$days[$i] = Date::format($dateWithOffset, 'Y-m-d', 'M y'); /// M
}
$labels = "'" . implode("','", $days) . "'";
$seriesVisits = implode(',', $visits);
$seriesUnique = implode(',', $unique);
}
ELSEIF ($chartType == 'Weekly') {
$numberOfWeeksToKeep = $this->getValue('numberOfWeeksToKeep');
$numberOfWeeksToKeep = $numberOfWeeksToKeep - 1;
for ($i=$numberOfWeeksToKeep; $i >= 0 ; $i--) {
$dateWithOffset = date('Y-m-d' , strtotime ( '-'.$i.' week' , strtotime ( $mondayDateThisWeek ) ) );
$visits[$i] = $this->getPageViewCount($dateWithOffset, 'Weekly');
$unique[$i] = $this->getUniqueVisitorCount($dateWithOffset, 'Weekly');
$days[$i] = Date::format($dateWithOffset, 'Y-m-d', 'd M');
}
$labels = "'" . implode("','", $days) . "'";
$seriesVisits = implode(',', $visits);
$seriesUnique = implode(',', $unique);
}
ELSE { // $chartType == 'Daily'
$numberOfDaysToKeep = $this->getValue('numberOfDaysToKeep');
$numberOfDaysToKeep = $numberOfDaysToKeep - 1;
for ($i=$numberOfDaysToKeep; $i >= 0 ; $i--) {
$dateWithOffset = Date::currentOffset('Y-m-d', '-'.$i.' day');
$visits[$i] = $this->getPageViewCount($dateWithOffset, 'Daily');
$unique[$i] = $this->getUniqueVisitorCount($dateWithOffset, 'Daily');
$days[$i] = Date::format($dateWithOffset, 'Y-m-d', 'D');
}
$labels = "'" . implode("','", $days) . "'";
$seriesVisits = implode(',', $visits);
$seriesUnique = implode(',', $unique);
}
$script = <<
var data = {
labels: [$labels],
series: [
[$seriesVisits],
[$seriesUnique]
]
};
var options = {
height: 250,
axisY: {
onlyInteger: true,
}
};
new Chartist.Line('.ct-chart', data, options);
EOF;
$this->deleteOldLogs( 'Daily', $this->getValue('numberOfDaysToKeep') );
$this->deleteOldLogs( 'Weekly', $this->getValue('numberOfWeeksToKeep') );
$this->deleteOldLogs( 'Monthly',$this->getValue('numberOfMonthsToKeep') );
/**
* Optional Content Stats Feature
**/
if ($this->getValue('showContentStats')) {
global $pages, $categories, $tags;
$data['title'] = $L->get('content-statistics-label');
$data['tabTitleChart'] = $L->get('tab-chart-label');
$data['tabTitleTable'] = $L->get('tab-table-label');
$data['data'][$L->get('published-label')] = count($pages->getPublishedDB());
$data['data'][$L->get('static-label')] = count($pages->getStaticDB());
$data['data'][$L->get('drafts-label')] = count($pages->getDraftDB());
$data['data'][$L->get('scheduled-label')] = count($pages->getScheduledDB());
$data['data'][$L->get('sticky-label')] = count($pages->getStickyDB());
$data['data'][$L->get('categories-label')]= count($categories->keys());
$data['data'][$L->get('tags-label')] = count($tags->keys());
$html .= $this->renderContentStatistics($data);
}
return $html.PHP_EOL.$script.PHP_EOL;
}
public function siteBodyEnd()
{
global $page;
$pageTitleHash = hash(adler32,$page->title(),false);
$pageSessionLimit = (60*$this->getValue('pageSessionActiveMinutes')); // 60*60=360
// Counters will be increased only once a page title session to prevent F5 increases.
if ( (!isset($_SESSION[$pageTitleHash])) || ((time()-$_SESSION[$pageTitleHash]) > $pageSessionLimit ) )
{
//Set Variable for this session so user cannot increase counter by pressing F5
$_SESSION[$pageTitleHash] = time();
IF ($this->getValue('numberOfDaysToKeep') > 0) {
$this->addVisitorDaily();
}
IF ($this->getValue('numberOfWeeksToKeep') > 0) {
$this->addVisitorWeekly();
}
IF ($this->getValue('numberOfMonthsToKeep') > 0) {
$this->addVisitorMonthly();
}
IF (enableOngoingCounter) {
$this->increaseCounter();
}
}
}
// Keep only number of logs defined in numberOfDaysToKeep, numberOfWeeksToKeep & numberOfMonthsToKeep.
public function deleteOldLogs( $periodType, $numberToKeep )
{
$logs = Filesystem::listFiles($this->workspace(), '*-'.$periodType, 'log', true);
$remove = array_slice($logs, $numberToKeep);
foreach ($remove as $log) {
Filesystem::rmfile($log);
}
}
// Returns the number of page visits by date per day
public function getPageViewCount($date, $periodType)
{
$file = $this->workspace().$date.'-'.$periodType.'.log';
$handle = @fopen($file, 'rb');
if ($handle===false) {
return 0;
}
// The number of page visits are 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 by date
public function getUniqueVisitorCount($date, $periodType)
{
$file = $this->workspace().$date.'-'.$periodType.'.log';
$lines = @file($file);
if (empty($lines)) {
return 0;
}
$tmp = array();
foreach ($lines as $line) {
$data = json_decode($line);
$hashIP = $data[0];
$tmp[$hashIP] = true;
}
return count($tmp);
}
public function increaseCounter()
{
$runningTotals = array();
$totalPageViews = 0;
$totalUniqueVisitors = 0;
$resetOngoingCounterValue = $this->getValue('resetOngoingCounterValue');
try
{
if (!file_exists($this->workspace().'running-totals.json') ) {
$runningTotals['runningTotals'] = array(
'pageCounter' => 0,
'uniqueCounter' => 0 // not used at the moment - would need to read today's log file to determin if visitor exists
);
}
else {
$runningTotals = json_decode(file_get_contents($this->workspace().'running-totals.json'),TRUE);
}
if ($resetOngoingCounterValue < 0 ) {
$runningTotals['runningTotals']['pageCounter']++;
}
else {
$runningTotals['runningTotals']['pageCounter'] = $resetOngoingCounterValue;
}
//Encode the array back into a JSON string.
$json = json_encode($runningTotals);
//Save the file.
file_put_contents($this->workspace().'running-totals.json', $json);
}
catch (Exception $e) {
echo 'Caught exception: '.$e->getMessage();
}
// $formatStyle=NumberFormatter::TYPE_INT32;
// $formatter= new NumberFormatter($locale, $formatStyle);
// echo "Running total = ".$formatter->format($runningTotals['runningTotals']['pageCounter']);
}
// Add a line to the current Daily log
// The line is a json array with the hash IP of the visitor and the time
public function addVisitorDaily()
{
if (Cookie::get('BLUDIT-KEY') && defined('BLUDIT_PRO') && $this->getValue('excludeAdmins')) {
return false;
}
$currentTime = Date::current('Y-m-d H:i:s');
$ip = TCP::getIP();
$hashIP = md5($ip);
$line = json_encode(array($hashIP, $currentTime));
$currentDate = Date::current('Y-m-d');
$logDailyFile = $this->workspace().$currentDate.'-Daily.log';
return file_put_contents($logDailyFile, $line.PHP_EOL, FILE_APPEND | LOCK_EX)!==false;
}
// Add a line to the current Weekly log
// The line is a json array with the hash IP of the visitor and the time
public function addVisitorWeekly()
{
if (Cookie::get('BLUDIT-KEY') && defined('BLUDIT_PRO') && $this->getValue('excludeAdmins')) {
return false;
}
$mondayDateTimeThisWeek = date("Y-m-d", strtotime('monday this week')).' '. date('H:i:s', strtotime("now"));
$ip = TCP::getIP();
$hashIP = md5($ip);
$line = json_encode(array($hashIP, $mondayDateTimeThisWeek));
$mondayDateThisWeek = date("Y-m-d", strtotime('monday this week'));
$logWeeklyFile = $this->workspace().$mondayDateThisWeek.'-Weekly.log';
return file_put_contents($logWeeklyFile, $line.PHP_EOL, FILE_APPEND | LOCK_EX)!==false;
}
// Add a line to the current Monthly log
// The line is a json array with the hash IP of the visitor and the time
public function addVisitorMonthly()
{
if (Cookie::get('BLUDIT-KEY') && defined('BLUDIT_PRO') && $this->getValue('excludeAdmins')) {
return false;
}
$firstDateTimeOfThisThisMonth = date("Y-m-d", strtotime('first day of this month')).' '. date('H:i:s', strtotime("now"));
$ip = TCP::getIP();
$hashIP = md5($ip);
$line = json_encode(array($hashIP, $firstDateTimeOfThisThisMonth));
$firstDateOfThisThisMonth = date("Y-m-d", strtotime('first day of this month'));
$logMonthyFile = $this->workspace().$firstDateOfThisThisMonth.'-Monthly.log';
return file_put_contents($logMonthyFile, $line.PHP_EOL, FILE_APPEND | LOCK_EX)!==false;
}
public function renderContentStatistics($data)
{
$html = '';
$html .= "
{$data['title']}
";
$html .= '
';
foreach ($data['data'] as $th => $td) {
$html .= "
$th |
$td |
";
}
$html .= '
';
return $html;
}
}