Skip to content

Commit

Permalink
Merge pull request #4 from JamesPhillipsUK/v-1.1-dev
Browse files Browse the repository at this point in the history
Version 2 Development
  • Loading branch information
JamesPhillipsUK authored Dec 26, 2019
2 parents 22b78eb + 90feb92 commit b79da42
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 244 deletions.
6 changes: 0 additions & 6 deletions DataBaseDetails.inc

This file was deleted.

58 changes: 58 additions & 0 deletions IPStatistics/IPStatistics.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* IPStatistics is a simple, database-driven PHP Analytics API that can be run as a plugin for PHP websites..
*
* Copyright (C) 2016 - 2019 James Phillips, Released under the GNU GPL v3.0 or later.
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version. This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
**/
namespace IPStatistics
{
/**
* Driver class for the IPStatistics API. You'll want to call this.
**/
define("AccessToken", true);// Make the API files accessible.
require_once("databaseLogin.php");// Login details.
require_once("connector.php");// Connects the database to the UI.
require_once("userInterface.php");// Calls the UI components.

class IPStatistics
{
public function __construct()// Unused constructor.
{
}

/**
* Records a visit to the site.
**/
public function record()
{
connector::recordData();
}

/**
* Outputs raw visit data to the page.
**/
public function data()
{
$data = connector::getData();
userInterface::buildDataInterface($data);
}

/**
* Outputs the visit graph for the past year.
**/
public function graph()
{
$data = connector::getData();
userInterface::buildGraphInterface($data);
}
}
}
?>
98 changes: 98 additions & 0 deletions IPStatistics/connector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php
namespace IPStatistics
{
defined('AccessToken') or die(header('HTTP/1.0 403 Forbidden'));// Security check.
abstract class connector
{
/**
* Connects to the database using the namespace-level constants defined in databaseLogin.
* @return connection a MySLQi database connection object.
**/
private static function connect()
{
$connection = mysqli_connect(DATABASESERVER, DATABASEUSER, DATABASEPASSWORD, DATABASENAME);
if (!$connection)
die('Could not connect to database');
return $connection;
}

/**
* Closes a database connection using the namespace-level constants defined in databaseLogin.
* @param connection a MySLQi database connection object.
**/
private static function close($conection)
{
if (!empty($connection))
mysqli_close($connection);
}

/**
* Records a visit to the website and adds it to the database.
**/
public static function recordData()
{
$connection = connector::connect();
$iP = mysqli_real_escape_string($connection,mb_convert_encoding($_SERVER["REMOTE_ADDR"], "UTF-8"));
$date = mysqli_real_escape_string($connection,mb_convert_encoding(date("Y-m-d"), "UTF-8"));
$time = mysqli_real_escape_string($connection,mb_convert_encoding(date("h:i:sa"), "UTF-8"));
$month = mysqli_real_escape_string($connection,mb_convert_encoding(date("n"), "UTF-8"));
$query = "INSERT INTO `IPTable` (`IP`, `Date`, `Time`,`Month`) VALUES ('$iP', '$date', '$time', '$month');";
mysqli_query($connection,$query);
connector::close($connection);
}

/**
* Gets all of the visit data for a year and returns it as an array.
* @return array the array of database data.
**/
public static function getData()
{
$totalVisitors = 0;
$totalDaysVisitors = 0;
$totalMonthsVisitors = 0;
$monthlyUsers = array_fill(0,12,0);
$lastMonthVisitors = array();
$lastDayVisitors = array();
$monthlyUsersAsPercentage = array();
$connection = connector::connect();
$query = "SELECT * FROM IPTable WHERE ID > 0 AND Date > CURDATE() - INTERVAL 1 YEAR;";
$result = mysqli_query($connection,$query) or die('Failed to get values from database.');
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC))
{
$iD = $row['ID'];
$iP = $row['IP'];
$date = $row['Date'];
$time = $row['Time'];
$month = $row['Month'];
$today = date("Y-m-d");
if ($date == $today)
{
$lastDayVisitors[$totalDaysVisitors] = $iP;
$totalDaysVisitors = $totalDaysVisitors + 1;
}
if (strtotime($date) > strtotime('-30 days'))
{
$lastMonthVisitors[$totalMonthsVisitors] = $iP;
$totalMonthsVisitors = $totalMonthsVisitors + 1;
}
for($count = 1; $count < 13; $count++)
{
if ($count == $month)
$monthlyUsers[$count - 1]++;
}
$totalVisitors++;
}
connector::close($connection);
$count = 0;
foreach($monthlyUsers as $amount)
{
$monthlyUsersAsPercentage[$count] = ($amount/$totalVisitors)*100;
$count++;
}
unset($count);

return array($totalVisitors, $totalDaysVisitors, $totalMonthsVisitors, $monthlyUsers, $lastMonthVisitors, $lastDayVisitors, $monthlyUsersAsPercentage);
}
}
}
?>
13 changes: 13 additions & 0 deletions IPStatistics/databaseLogin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
namespace IPStatistics
{
/**
* Defined constants for the database access needed for the API.
**/
defined('AccessToken') or die(header('HTTP/1.0 403 Forbidden'));// Security check.
const DATABASESERVER = "";// Insert your database server IP here.
const DATABASEUSER = "";// Insert your database username here.
const DATABASEPASSWORD = "";// Insert your database password here.
const DATABASENAME = "";// Insert your database name here.
}
?>
92 changes: 92 additions & 0 deletions IPStatistics/userInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php
namespace IPStatistics
{
defined('AccessToken') or die(header('HTTP/1.0 403 Forbidden'));// Security check.
abstract class userInterface
{
/**
* Builds the raw data interface from data preformatted by connector::getData and prints it to screen.
* @param data - the data preformatted by connector::getData
**/
public static function buildDataInterface($data)
{
$totalDaysVisitors = $data[1];// Total number of visits today.
$lastDayVisitors = $data[5];// An array of their IP addresses.
$totalMonthsVisitors = $data[2];// Total number of visits this month.
$lastMonthVisitors = $data[4];// An array of their IP addresses.
echo
'<div id="today">
<h2>Today&#39;s Stats</h1>
<p>Number of visitors today:';
echo $totalDaysVisitors . '</p>
<p>IP Addresses of visitors today:<br />
<pre style="font-size:0.9rem;">';
print_r(array_count_values($lastDayVisitors));
echo '</pre>
</p>
</div>
<div id="month">
<h2>This Month&#39;s Stats</h1>
<p>Number of visitors this month (last 30 days):';
echo $totalMonthsVisitors . '</p>
<p>IP Addresses of visitors this month (last 30 days):<br />
<pre style="font-size:0.9rem;">';
print_r(array_count_values($lastMonthVisitors));
echo '</pre>
</p>
</div>';
}

/**
* Builds the graph interface from data preformatted by connector::getData and prints it to screen.
* @param data - the data preformatted by connector::getData
**/
public static function buildGraphInterface($data)
{
$monthlyUsersAsPercentage = $data[6];
$totalVisitors = $data[0];
echo '<style>#graph{margin:0 auto; width:80%; background-color:#EFEFEF;padding:0;}#graph *{padding:0;margin:0;}.month{display:block;text-overflow:clip;white-space:nowrap;overflow:hidden;float:left;}</style>';// Some basic styling needed to make the graph work.
echo '<div id="graph">
<h1>Your visitors over the past year</h1>
<p>Total: ' . $totalVisitors . '</p>
<div style="background-color:#FFFF66;width:' . $monthlyUsersAsPercentage[0] . '%;" class="month">
<p>Jan, ' . round($monthlyUsersAsPercentage[0], 3) . '&#37;</p>
</div>
<div style="background-color:#99FF33;width:' . $monthlyUsersAsPercentage[1] . '%;" class="month">
<p>Feb, ' . round($monthlyUsersAsPercentage[1], 3) . '&#37;</p>
</div>
<div style="background-color:#FF9966;width:' . $monthlyUsersAsPercentage[2] . '%;" class="month">
<p>Mar, ' . round($monthlyUsersAsPercentage[2], 3) . '&#37;</p>
</div>
<div style="background-color:#00FFFF;width:' . $monthlyUsersAsPercentage[3] . '%;" class="month">
<p>Apr, ' . round($monthlyUsersAsPercentage[3], 3) . '&#37;</p>
</div>
<div style="background-color:#CC99FF;width:' . $monthlyUsersAsPercentage[4] . '%;" class="month">
<p>May, ' . round($monthlyUsersAsPercentage[4], 3) . '&#37;</p>
</div>
<div style="background-color:#FF66CC;width:' . $monthlyUsersAsPercentage[5] . '%;" class="month">
<p>Jun, ' . round($monthlyUsersAsPercentage[5], 3) . '&#37;</p>
</div>
<div style="background-color:#66FFCC;width:' . $monthlyUsersAsPercentage[6] . '%;" class="month">
<p>Jul, ' . round($monthlyUsersAsPercentage[6], 3) . '&#37;</p>
</div>
<div style="background-color:#996633;width:' . $monthlyUsersAsPercentage[7] . '%;" class="month">
<p>Aug, ' . round($monthlyUsersAsPercentage[7], 3) . '&#37;</p>
</div>
<div style="background-color:#FF6600;width:' . $monthlyUsersAsPercentage[8] . '%;" class="month">
<p>Sep, ' . round($monthlyUsersAsPercentage[8], 3) . '&#37;</p>
</div>
<div style="background-color:#FF0000;width:' . $monthlyUsersAsPercentage[9] . '%;" class="month">
<p>Oct, ' . round($monthlyUsersAsPercentage[9], 3) . '&#37;</p>
</div>
<div style="background-color:#993399;width:' . $monthlyUsersAsPercentage[10] . '%;" class="month">
<p>Nov, ' . round($monthlyUsersAsPercentage[10], 3) . '&#37;</p>
</div>
<div style="background-color:#0000CC;width:' . $monthlyUsersAsPercentage[11] . '%;" class="month">
<p>Dec, ' . round($monthlyUsersAsPercentage[11], 3) . '&#37;</p>
</div>
</div>';
}
}
}
?>
60 changes: 42 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,62 @@
# IPStatistics
IPStatistics, Originally created by James Phillips <[james@jamesphillipsuk.com](mailto:james@jamesphillipsuk.com "Send a Message")> 2016 - released to GitHub 2017.
IPStatistics is a PHP plugin to allow website admins to monitor their analytics.

IPStatistics, Originally created by James Phillips <[james@jamesphillipsuk.com](mailto:james@jamesphillipsuk.com "Send a Message")> in 2016 - released to GitHub under the GNU GPL v3.0 or later in 2017.
IPStatistics is a PHP API to allow website admins to monitor their analytics based on the IP addresses of visitors.

## About
IPStatistics is a simple, database-driven PHP Analytics plugin for websites. It consists of two main scripts: Stat.php - which logs statistics when run on every page, and Analyse.php - which analyses and formats these statistics for your use.

IPStatistics is a simple, database-driven PHP Analytics API that can be run as a plugin for PHP websites. It consists of one namespace (IPStatistics), and a driver class (also called IPStatistics), with three API calls: record, graph, and data. A quick how-to for using IPStatistics can be found in step 4 of the Installation instructions below.

### Simplicity
In an aim to be as simple and efficient as possible, this plugin consists of only:

| Code | Amount | Purpose |
|:--------------- |:--------- |:------------------------------------------------------------------------------------------------------ |
| Includes (.inc) | 6 lines | To hold database login data above the web root. |
| PHP | 220 lines | This is a combination of both: the mechanism that gathers analytic data, and the one that analyses it. |
In an aim to be as simple and efficient as possible, this API consists of only:

| Code | Amount | Purpose |
|:---- |:------ |:------- |
| PHP | 261 lines | This is the entire API. Short, sweet, and simple. (Not including the example file) |
| Markdown | 63 lines | The README file. |
| Text | 675 lines | The license file |

## Installation
1. Fill in the gaps in DataBaseDetails.inc with your database login details.
2. Save DataBaseDetails.inc above the web root on your server.
3. Create a MySQL database and table. The table needs to contain the following SQL structure:

1. Save the IPStatistics directory.
2. Fill in the gaps in IPStatistics/databaseLogin.php with your database login details.
3. Create a MySQL database and table containing the following SQL structure:

```SQL
CREATE TABLE IPTable('ID' BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,'IP' VARCHAR(25) NOT NULL,'Date' DATE NOT NULL,Time VARCHAR(10) NOT NULL,'Month' INT(11) NOT NULL);
CREATE TABLE IPTable (ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,IP VARCHAR(25) NOT NULL,Date DATE NOT NULL,Time VARCHAR(10) NOT NULL,Month INT(11) NOT NULL);
```
4. Save Stat.php and Analyse.php below the web root.
5. Insert the following code into each page of the site where you want to take analytics:

4. Use the following snippets of code where you want to record a visit, display a graph of your visitors over the past year, or display the corresponding raw data.

```PHP
<?php
include("./Stat.php"); //Gather stats for analytics.
include("IPStatistics/IPStatistics.php");// Include the IPStatistics API.
use IPStatistics\IPStatistics as IPStatistics;// Access the API.
$stats = new IPStatistics();// Create an instance of the Statistics.

...

$stats->record();// Record the visit.

...

$stats->graph();// Display a graph of the visit data.

...

$stats->data();// Display the raw data, including IP addresses.
?>
```
6. When you want to check your site analytics, simply navigate to your web address /Analyse.php.

- Don't forget to secure your webserver settings so that the IPStatistics directory can't be accessed by your website visitors.

## GDPR

>"A much discussed topic is the IP address. The GDPR states that IP addresses should be considered personal data as it enters the scope of ‘online identifiers’." - eugdprcompliant.com/personal-data.
As such, you should handle IP addresses as you would with any personal data under GDPR. I'm not here to offer legal advice, but I ask that if you choose to use software I've created - you ensure that you do so in accordance with the law.
As such, you should handle IP addresses as you would with any personal data under GDPR. I'm not here to offer legal advice, but if you choose to use software I've created - you must ensure that you do so in accordance with the law.

## Release Details
This plugin was released on 26th July 2017 under the GNU General Public License v3.0 or later by James Phillips. See the LICENSE file for more details.

This software was released on 26th July 2017 under the GNU General Public License v3.0 or later by James Phillips. See the LICENSE file for more details.
24 changes: 24 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* This file contains an example of how IPStatistics can be used. It contains all three recommended API calls: record, graph, and data.
**/
include("IPStatistics/IPStatistics.php");// Include the IPStatistics API.
use IPStatistics\IPStatistics as IPStatistics;// Access the API.

$stats = new IPStatistics();// Create an instance of the Statistics.
$stats->record();// Record the visit.
?>
<!-- This file contains an example of how IPStatistics can be used. It should not be implemented on your website as-is. Use this for inspiration for how to implement IPStatistics. -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Website Stats</title>
</head>
<body>
<h1>My Website Stats</h1>
<p>This page shouldn't be implemented on your website as-is. Use this for inspiration for how to implement IPStatistics. You may want to implement the <code>$stats->record();</code> API call on multiple pages, but you'll probably only want to implement <code>$stats->graph();</code> and <code>$stats->data();</code> in a secure backend page.</p>
<?php $stats->graph();// Display a graph of the visit data. ?>
<br />
<?php $stats->data();// Display the raw data, including IP addresses. ?>
</body>
</html>
Loading

0 comments on commit b79da42

Please sign in to comment.