From 8d8982cfce1c9b608065f2f4c261d36df00a38ec Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Tue, 1 May 2018 13:33:30 -0600 Subject: [PATCH] Add basic analytics capture (issue #8) --- .gitignore | 3 +- composer.json | 3 +- composer.lock | 214 +++++++++++++++++++++++++++++++++++++++- database.mwb | Bin 12694 -> 12890 bytes lib/gatheranalytics.php | 98 ++++++++++++++++++ lib/requiredpublic.php | 14 +++ public/index.php | 2 + settings.template.php | 9 +- 8 files changed, 338 insertions(+), 5 deletions(-) create mode 100644 lib/gatheranalytics.php diff --git a/.gitignore b/.gitignore index e1da2a6..f6ec423 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ vendor settings.php nbproject/private *.sync-conflict* -*.bak \ No newline at end of file +*.bak +GeoLite2-City.mmdb \ No newline at end of file diff --git a/composer.json b/composer.json index fb37c32..d2aa591 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "type": "project", "require": { "catfan/medoo": "^1.5", - "guzzlehttp/guzzle": "^6.2" + "guzzlehttp/guzzle": "^6.2", + "geoip2/geoip2": "~2.0" }, "license": "MPL-2.0", "authors": [ diff --git a/composer.lock b/composer.lock index f1d9d09..5ad0e7f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5c7439c6e041764f2f6b0270a95ab3ae", - "content-hash": "e4e700119f47d2f68b0ed82abaf8c5c6", + "hash": "a05b32c4ba7d59c1fa2dc87ef59b238d", + "content-hash": "2b47ec7e64412178507c9e9362debc56", "packages": [ { "name": "catfan/medoo", @@ -66,6 +66,114 @@ ], "time": "2018-03-26 17:54:24" }, + { + "name": "composer/ca-bundle", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/d2c0a83b7533d6912e8d516756ebd34f893e9169", + "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2018-03-29 19:57:20" + }, + { + "name": "geoip2/geoip2", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/GeoIP2-php.git", + "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/a807fbf65212eef5d8d2db1a1b31082b53633d77", + "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77", + "shasum": "" + }, + "require": { + "maxmind-db/reader": "~1.0", + "maxmind/web-service-common": "~0.5", + "php": ">=5.4" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "2.*", + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "GeoIp2\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "http://www.maxmind.com/" + } + ], + "description": "MaxMind GeoIP2 PHP API", + "homepage": "https://github.com/maxmind/GeoIP2-php", + "keywords": [ + "IP", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "time": "2018-04-10 15:32:59" + }, { "name": "guzzlehttp/guzzle", "version": "6.3.2", @@ -247,6 +355,108 @@ ], "time": "2017-03-20 17:10:46" }, + { + "name": "maxmind-db/reader", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", + "reference": "e042b4f8a2dff41e19019faf16427178b07fbd58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/e042b4f8a2dff41e19019faf16427178b07fbd58", + "reference": "e042b4f8a2dff41e19019faf16427178b07fbd58", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "2.*", + "phpunit/phpunit": "4.* || 5.*", + "satooshi/php-coveralls": "1.0.*", + "squizlabs/php_codesniffer": "3.*" + }, + "suggest": { + "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" + }, + "type": "library", + "autoload": { + "psr-4": { + "MaxMind\\Db\\": "src/MaxMind/Db" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "http://www.maxmind.com/" + } + ], + "description": "MaxMind DB Reader API", + "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", + "keywords": [ + "database", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "time": "2018-02-21 21:23:33" + }, + { + "name": "maxmind/web-service-common", + "version": "v0.5.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/web-service-common-php.git", + "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/61a9836fa3bb1743ab89752bae5005d71e78c73b", + "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0.3", + "ext-curl": "*", + "ext-json": "*", + "php": ">=5.4" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "2.*", + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MaxMind\\Exception\\": "src/Exception", + "MaxMind\\WebService\\": "src/WebService" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory Oschwald", + "email": "goschwald@maxmind.com" + } + ], + "description": "Internal MaxMind Web Service API", + "homepage": "https://github.com/maxmind/web-service-common-php", + "time": "2018-02-12 22:31:54" + }, { "name": "psr/http-message", "version": "1.0.1", diff --git a/database.mwb b/database.mwb index 90dbd3cc3ba909271b3d515eaf429c27868d1d3d..45ff6c3bd237d98beff2b3daf7fb7529c38d7ae1 100644 GIT binary patch literal 12890 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 + + $country = $record->country->name; + $region = $record->mostSpecificSubdivision->name; + $city = $record->city->name; + $lat = $record->location->latitude; + $lon = $record->location->longitude; + +// +// Save the page visit +// + + $database->insert("analytics", [ + "siteid" => getsiteid(), + "pageid" => getpageid(), + "uuid" => $uuid, + "country" => $country, + "region" => $region, + "city" => $city, + "lat" => $lat, + "lon" => $lon, + "time" => $time + ]); +} catch (GeoIp2\Exception\AddressNotFoundException $e) { + if (DEBUG) { + echo ""; + } +} catch (Exception $e) { + // Silently fail so the rest of the site still works +} \ No newline at end of file diff --git a/lib/requiredpublic.php b/lib/requiredpublic.php index e5eef9f..6e4be53 100644 --- a/lib/requiredpublic.php +++ b/lib/requiredpublic.php @@ -120,6 +120,20 @@ function getpageslug() { return null; } +function getpageid() { + global $database; + if (isset($_GET['id'])) { + $id = $_GET['id']; + } else { + $id = "index"; + } + $siteid = getsiteid(); + if ($database->has("pages", ["AND" => ["slug" => $id, "siteid" => $siteid]])) { + return $database->get("pages", "pageid", ["AND" => ["slug" => $id, "siteid" => $siteid]]); + } + return null; +} + function getpagetemplate() { global $database; $slug = getpageslug(); diff --git a/public/index.php b/public/index.php index 9b9f6bf..11898fa 100644 --- a/public/index.php +++ b/public/index.php @@ -8,6 +8,8 @@ require_once __DIR__ . "/../lib/requiredpublic.php"; require_once __DIR__ . "/../lib/themefunctions.php"; +include __DIR__ . "/../lib/gatheranalytics.php"; + if (!getsiteid()) { sendError("No website has been created yet. Please open " . SITE_TITLE . " and make one."); } diff --git a/settings.template.php b/settings.template.php index 8bf762d..34e86ca 100644 --- a/settings.template.php +++ b/settings.template.php @@ -37,6 +37,13 @@ define('URL', '/sitewriter'); // Folder for public files define('FILE_UPLOAD_PATH', __DIR__ . '/public/files'); +// Location of MaxMind GeoIP database +// +// I'll just leave this here: +// This product includes GeoLite2 data created by MaxMind, available from +// http://www.maxmind.com +define('GEOIP_DB', __DIR__ . "/GeoLite2-City.mmdb"); + // Use Captcheck on login screen // https://captcheck.netsyms.com define("CAPTCHA_ENABLED", FALSE); @@ -47,4 +54,4 @@ define('LANGUAGE', "en_us"); define("FOOTER_TEXT", ""); -define("COPYRIGHT_NAME", "Netsyms Technologies"); \ No newline at end of file +define("COPYRIGHT_NAME", "Netsyms Technologies");