From a711d9bb754072e2194e0e95ce2e7397d15951a9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 7 Sep 2014 19:58:04 -0600 Subject: [PATCH] Add visitors support and refactored --- admin.php | 5 +- admin.yaml | 3 +- classes/popularity.php | 136 +++++++++++++++++++++++++++++++---------- 3 files changed, 108 insertions(+), 36 deletions(-) diff --git a/admin.php b/admin.php index c5e76be4..70577fe7 100644 --- a/admin.php +++ b/admin.php @@ -163,10 +163,9 @@ class AdminPlugin extends Plugin require_once PLUGINS_DIR . 'admin/classes/popularity.php'; $popularity = new Popularity(); - // if in admin, try to flush data + // if in admin, flush old monthly data if ($this->active) { - $popularity->flushData(); - + $popularity->flushMonthly(); // else track data } else { $popularity->trackHit(); diff --git a/admin.yaml b/admin.yaml index 7d587a3c..23001554 100644 --- a/admin.yaml +++ b/admin.yaml @@ -2,5 +2,6 @@ enabled: true route: '/admin' popularity: enabled: true - ignore: ['/test/*','/modular'] + ignore: ['/test*','/modular'] + visitors: 20 theme: grav diff --git a/classes/popularity.php b/classes/popularity.php index 131417be..403a8085 100644 --- a/classes/popularity.php +++ b/classes/popularity.php @@ -18,23 +18,37 @@ class Popularity { use GravTrait; + + protected $config; protected $data_path; - protected $data_file; + + protected $monthly_file; + protected $totals_file; + protected $visitors_file; + + protected $monthly_data; + protected $totals_data; + protected $visitors_data; const MONTHLY_FILE = 'monthly.json'; const TOTALS_FILE = 'totals.json'; + const VISITORS_FILE = 'visitors.json'; public function __construct() { + $this->config = self::$grav['config']; + $this->data_path = LOG_DIR . 'popularity'; - $this->data_file = date('W-Y') . '.json'; + $this->monthly_file = $this->data_path.'/'.self::MONTHLY_FILE; + $this->totals_file = $this->data_path.'/'.self::TOTALS_FILE; + $this->visitors_file = $this->data_path.'/'.self::VISITORS_FILE; + } public function trackHit() { $page = self::$grav['page']; - $config = self::$grav['config']; - $relative_url = str_replace($config->get('system.base_url_relative'), '', $page->url()); + $relative_url = str_replace($this->config->get('system.base_url_relative'), '', $page->url()); // Don't track error pages or pages that have no route if ($page->template() == 'error' || !$page->route()) { @@ -42,60 +56,118 @@ class Popularity } // Make sure no 'widcard-style' ignore matches this url - foreach ((array) self::$grav['config']->get('plugins.admin.popularity.ignore') as $ignore) { + foreach ((array) $this->config->get('plugins.admin.popularity.ignore') as $ignore) { if (fnmatch($ignore, $relative_url)) { return; } } - // Used more than once, so make a variable! - $monthly_file = $this->data_path.'/'.self::MONTHLY_FILE; - $totals_file = $this->data_path.'/'.self::TOTALS_FILE; - // initial creation if it doesn't exist if (!file_exists($this->data_path)) { mkdir($this->data_path); - file_put_contents($monthly_file, array()); - file_put_contents($totals_file, array()); + file_put_contents($this->monthly_file, array()); + file_put_contents($this->totals_file, array()); + file_put_contents($this->visitors_file, array()); } // Update the data we want to track - $this->updateMonthly($monthly_file); - $this->updateTotals($totals_file, $relative_url); + $this->updateMonthly(); + $this->updateTotals($page->route()); + $this->updateVisitors(self::$grav['uri']->ip()); } - public function flushData($weeks = 52) + protected function updateMonthly() { - // flush data older than 1 year + if (!$this->monthly_data) { + $this->monthly_data = $this->getData($this->monthly_file); + } - } - - protected function updateMonthly($path) - { - $data = (array) @json_decode(file_get_contents($path), true); $month_year = date('m-Y'); - if (array_key_exists($month_year, $data)) { - $data[$month_year] = intval($data[$month_year]) + 1; + // get the monthly access count + if (array_key_exists($month_year, $this->monthly_data)) { + $this->monthly_data[$month_year] = intval($this->monthly_data[$month_year]) + 1; } else { - $data[$month_year] = 1; + $this->monthly_data[$month_year] = 1; } - file_put_contents($path, json_encode($data)); + file_put_contents($this->monthly_file, json_encode($this->monthly_data)); } - protected function updateTotals($path, $url) + protected function updateTotals($url) { - $data = (array) @json_decode(file_get_contents($path), true); - - if (array_key_exists($url, $data)) { - $data[$url] = intval($data[$url]) + 1; - } else { - $data[$url] = 1; + if (!$this->totals_data) { + $this->totals_data = $this->getData($this->totals_file); } - file_put_contents($path, json_encode($data)); + // get the totals for this url + if (array_key_exists($url, $this->totals_data)) { + $this->totals_data[$url] = intval($this->totals_data[$url]) + 1; + } else { + $this->totals_data[$url] = 1; + } + + file_put_contents($this->totals_file, json_encode($this->totals_data)); + } + + protected function updateVisitors($ip) + { + if (!$this->visitors_data) { + $this->visitors_data = $this->getData($this->visitors_file); + } + + $count = intval($this->config->get('plugins.admin.popularity.visitors', 20)); + + // update with current timestamp + $this->visitors_data[$ip] = time(); + + $visitors = $this->visitors_data; + arsort($visitors); + + $this->visitors_data = array_slice($visitors, 0, $count); + + file_put_contents($this->visitors_file, json_encode($this->visitors_data)); + } + + protected function getData($path) + { + return (array) @json_decode(file_get_contents($path), true); + } + + + public function flushMonthly($months = 12) + { + // flush data older than 1 year + if (!$this->monthly_data) { + $this->monthly_data = $this->getData($this->monthly_file); + } + + // If there are more than $months worth of data remove the old + if (count($this->monthly_data) > $months) { + $new_monthly = array(); + for ($x = 0; $x < intval($months); $x++) { + $date = date('m-Y', strtotime("now - $x month")); + if (isset($this->monthly_data[$date])) { + $new_monthly[$date] = $this->monthly_data[$date]; + } + } + + $this->monthly_data = $new_monthly; + file_put_contents($this->monthly_file, json_encode($this->monthly_data)); + } + } + + public function flushTotals() + { + // flush all totals + file_put_contents($this->totals_file, json_encode(array())); + } + + public function flushVisitors() + { + // flush all the visitor data + file_put_contents($this->visitors_file, json_encode(array())); } }