more generic setup for matomo
This commit is contained in:
1
themes/hugo-sustain/.gitignore
vendored
Normal file
1
themes/hugo-sustain/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
static/config.php
|
||||
@@ -4,9 +4,9 @@
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//mehl.mx/";
|
||||
var u={{ .Site.Params.matomo.trackedurl }};
|
||||
_paq.push(["setTrackerUrl", u+"piwik.php"]);
|
||||
_paq.push(["setSiteId", "9"]);
|
||||
_paq.push(["setSiteId", "{{ .Site.Params.matomo.siteid }}"]);
|
||||
var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0];
|
||||
g.type="text/javascript"; g.async=true; g.defer=true; g.src=u+"piwik.php"; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
|
||||
41
themes/hugo-sustain/static/config.php.sample
Normal file
41
themes/hugo-sustain/static/config.php.sample
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
// -----
|
||||
// Important: read the instructions in README.md or at:
|
||||
// https://github.com/matomo/matomo/tree/master/misc/proxy-hide-matomo-url#matomo-proxy-hide-url
|
||||
// -----
|
||||
|
||||
// Edit the line below, and replace http://your-matomo-domain.example.org/matomo/
|
||||
// with your Matomo URL ending with a slash.
|
||||
// This URL will never be revealed to visitors or search engines.
|
||||
$PIWIK_URL = 'http://your-matomo-domain.example.org/matomo/';
|
||||
|
||||
// Edit the line below and replace http://your-tracker-proxy.org/ with the URL to your tracker-proxy
|
||||
// setup. This URL will be used in Matomo output that contains the Matomo URL, so your Matomo is effectively
|
||||
// hidden.
|
||||
$PROXY_URL = 'http://your-tracker-proxy.org/';
|
||||
|
||||
// Edit the line below, and replace xyz by the token_auth for the user "UserTrackingAPI"
|
||||
// which you created when you followed instructions above.
|
||||
$TOKEN_AUTH = 'xyz';
|
||||
|
||||
// Maximum time, in seconds, to wait for the Matomo server to return the 1*1 GIF
|
||||
$timeout = 5;
|
||||
|
||||
// By default, the HTTP User Agent will be set to the user agent of the client requesting piwik.php
|
||||
// Edit the line below to force the proxy to always use a specific user agent string.
|
||||
$user_agent = '';
|
||||
|
||||
// In some situations the backend takes the sending IP address into account
|
||||
// which by default is the IP address of the server/service proxy.php is executed from.
|
||||
// If $http_forward_header is set, the clients IP address is sent over in the
|
||||
// header field with the given name. An empty string means do not send the header.
|
||||
// A common header name is 'X-Forwarded-For'.
|
||||
//
|
||||
// In order to work, the http server serving the matomo instance, has to be configured
|
||||
// to honor the additional header.
|
||||
//
|
||||
// For apache http see https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html
|
||||
// for nginx see https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/
|
||||
//
|
||||
$http_ip_forward_header = '';
|
||||
36
themes/hugo-sustain/static/matomo-proxy.php
Normal file
36
themes/hugo-sustain/static/matomo-proxy.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
define('MATOMO_PROXY_FROM_ENDPOINT', 1);
|
||||
|
||||
$path = 'index.php';
|
||||
|
||||
$SUPPORTED_METHODS = [
|
||||
'CoreAdminHome.optOut'
|
||||
];
|
||||
$VALID_FILES = [
|
||||
'plugins/CoreAdminHome/javascripts/optOut.js'
|
||||
];
|
||||
|
||||
$module = isset($_GET['module']) ? $_GET['module'] : null;
|
||||
if (empty($module)) {
|
||||
$module = isset($_POST['module']) ? $_POST['module'] : null;
|
||||
}
|
||||
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : null;
|
||||
if (empty($action)) {
|
||||
$action = isset($_POST['action']) ? $_POST['action'] : null;
|
||||
}
|
||||
|
||||
$filerequest = isset($_GET['file']) ? $_GET['file'] : null;
|
||||
if (empty($filerequest)) {
|
||||
$filerequest = isset($_POST['file']) ? $_POST['file'] : null;
|
||||
}
|
||||
|
||||
if (!(isset($filerequest) && in_array($filerequest, $VALID_FILES))
|
||||
&& !(isset($module) && isset($action) && in_array("$module.$action", $SUPPORTED_METHODS))
|
||||
) {
|
||||
http_response_code(404);
|
||||
exit;
|
||||
}
|
||||
|
||||
include dirname(__FILE__) . '/proxy.php';
|
||||
14
themes/hugo-sustain/static/piwik.php
Normal file
14
themes/hugo-sustain/static/piwik.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
* Piwik Proxy Hide URL
|
||||
*
|
||||
* @link http://piwik.org/faq/how-to/#faq_132
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
define('MATOMO_PROXY_FROM_ENDPOINT', 1);
|
||||
|
||||
$path = "piwik.php";
|
||||
|
||||
include dirname(__FILE__) . '/proxy.php';
|
||||
360
themes/hugo-sustain/static/proxy.php
Normal file
360
themes/hugo-sustain/static/proxy.php
Normal file
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
* Piwik Proxy Hide URL
|
||||
*
|
||||
* @link http://piwik.org/faq/how-to/#faq_132
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('MATOMO_PROXY_FROM_ENDPOINT')) {
|
||||
exit; // this file is not supposed to be accessed directly
|
||||
}
|
||||
|
||||
// if set to true, will print out more information about request errors so said errors can be more easily debugged.
|
||||
$DEBUG_PROXY = false;
|
||||
|
||||
// set to true if the target matomo server has a ssl certificate that will fail verification, like when testing.
|
||||
$NO_VERIFY_SSL = false;
|
||||
|
||||
if (file_exists(dirname(__FILE__) . '/config.php')) {
|
||||
include dirname(__FILE__) . '/config.php';
|
||||
}
|
||||
|
||||
// -----
|
||||
// Important: read the instructions in README.md or at:
|
||||
// https://github.com/piwik/tracker-proxy#piwik-tracker-proxy
|
||||
// -----
|
||||
|
||||
// Edit the line below, and replace http://your-piwik-domain.example.org/piwik/
|
||||
// with your Piwik URL ending with a slash.
|
||||
// This URL will never be revealed to visitors or search engines.
|
||||
if (! isset($PIWIK_URL)) {
|
||||
$PIWIK_URL = 'http://your-piwik-domain.example.org/piwik/';
|
||||
}
|
||||
|
||||
// Edit the line below, and replace xyz by the token_auth for the user "UserTrackingAPI"
|
||||
// which you created when you followed instructions above.
|
||||
if (! isset($TOKEN_AUTH)) {
|
||||
$TOKEN_AUTH = 'xyz';
|
||||
}
|
||||
|
||||
// Maximum time, in seconds, to wait for the Piwik server to return the 1*1 GIF
|
||||
if (! isset($timeout)) {
|
||||
$timeout = 5;
|
||||
}
|
||||
|
||||
// The HTTP User-Agent to set in the request sent to Piwik Tracking API
|
||||
if (empty($user_agent)) {
|
||||
$user_agent = arrayValue($_SERVER, 'HTTP_USER_AGENT', '');
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// DO NOT MODIFY BELOW THIS LINE
|
||||
// -----------------------------
|
||||
|
||||
// the HTTP response headers captured via fopen or curl
|
||||
$httpResponseHeaders = array();
|
||||
|
||||
// 1) PIWIK.JS PROXY: No _GET parameter, we serve the JS file; or we serve a requested js file
|
||||
if ((empty($_GET) && empty($_POST)) || (isset($filerequest) && substr($filerequest, -3) === '.js')) {
|
||||
$modifiedSince = false;
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
$modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
|
||||
// strip any trailing data appended to header
|
||||
if (false !== ($semicolon = strpos($modifiedSince, ';'))) {
|
||||
$modifiedSince = substr($modifiedSince, 0, $semicolon);
|
||||
}
|
||||
$modifiedSince = strtotime($modifiedSince);
|
||||
}
|
||||
// Re-download the piwik.js once a day maximum
|
||||
$lastModified = time() - 86400;
|
||||
|
||||
// set HTTP response headers
|
||||
sendHeader('Vary: Accept-Encoding');
|
||||
|
||||
// Returns 304 if not modified since
|
||||
if (!empty($modifiedSince) && $modifiedSince > $lastModified) {
|
||||
sendHeader(sprintf("%s 304 Not Modified", $_SERVER['SERVER_PROTOCOL']));
|
||||
} else {
|
||||
sendHeader('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
sendHeader('Content-Type: application/javascript; charset=UTF-8');
|
||||
|
||||
// Silent fail: hide Warning in 'piwik.js' response
|
||||
if (empty($_GET) && empty($_POST)) {
|
||||
list($content, $httpStatus) = getHttpContentAndStatus($PIWIK_URL . 'piwik.js', $timeout, $user_agent);
|
||||
} else {
|
||||
list($content, $httpStatus) = getHttpContentAndStatus($PIWIK_URL . $filerequest, $timeout, $user_agent);
|
||||
}
|
||||
if ($piwikJs = $content) {
|
||||
echo $piwikJs;
|
||||
} else {
|
||||
echo '/* there was an error loading piwik.js */';
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
@ini_set('magic_quotes_runtime', 0);
|
||||
|
||||
// 2) PIWIK.PHP PROXY: GET parameters found, this is a tracking request, we redirect it to Piwik
|
||||
if (strpos($path, '?') === false) {
|
||||
$path = $path . '?';
|
||||
}
|
||||
|
||||
$extraQueryParams = array();
|
||||
if (strpos($path, 'piwik.php') === 0) {
|
||||
$extraQueryParams = array(
|
||||
'cip' => getVisitIp(),
|
||||
'token_auth' => $TOKEN_AUTH,
|
||||
);
|
||||
}
|
||||
|
||||
$url = $PIWIK_URL . $path;
|
||||
$url .= http_build_query(array_merge($extraQueryParams, $_GET));
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
|
||||
// PHP 5.2 breaks with the new 204 status code so we force returning the image every time
|
||||
list($content, $httpStatus) = getHttpContentAndStatus($url . '&send_image=1', $timeout, $user_agent);
|
||||
$content = sanitizeContent($content);
|
||||
|
||||
forwardHeaders($content);
|
||||
|
||||
echo $content;
|
||||
|
||||
} else {
|
||||
// PHP 5.3 and above
|
||||
list($content, $httpStatus) = getHttpContentAndStatus($url, $timeout, $user_agent);
|
||||
$content = sanitizeContent($content);
|
||||
|
||||
forwardHeaders($content);
|
||||
|
||||
// Forward the HTTP response code
|
||||
if (!headers_sent() && !empty($httpStatus)) {
|
||||
header($httpStatus);
|
||||
}
|
||||
|
||||
echo $content;
|
||||
}
|
||||
|
||||
function sanitizeContent($content)
|
||||
{
|
||||
global $TOKEN_AUTH;
|
||||
global $PIWIK_URL;
|
||||
global $PROXY_URL;
|
||||
global $VALID_FILES;
|
||||
|
||||
$matomoHost = parse_url($PIWIK_URL, PHP_URL_HOST);
|
||||
$proxyHost = parse_url($PROXY_URL, PHP_URL_HOST);
|
||||
|
||||
$content = str_replace($TOKEN_AUTH, '<token>', $content);
|
||||
$content = str_replace($PIWIK_URL, $PROXY_URL, $content);
|
||||
$content = str_replace($matomoHost, $proxyHost, $content);
|
||||
|
||||
if(isset($VALID_FILES)) {
|
||||
foreach($VALID_FILES as $filepath) {
|
||||
// replace file paths to match the proxy and discard cb
|
||||
$content = preg_replace('^' . $filepath . '(\?cb\=[a-z0-9]*)?^', $PROXY_URL . 'matomo-proxy.php?file=' . $filepath, $content);
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
function forwardHeaders($content)
|
||||
{
|
||||
global $httpResponseHeaders;
|
||||
|
||||
$headersToForward = array(
|
||||
'content-type',
|
||||
'access-control-allow-origin',
|
||||
'access-control-allow-methods',
|
||||
'set-cookie',
|
||||
);
|
||||
|
||||
foreach ($httpResponseHeaders as $header) {
|
||||
$parts = explode(':', $header);
|
||||
if (empty($parts[0])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim(strtolower($parts[0]));
|
||||
if (in_array($name, $headersToForward)) {
|
||||
sendHeader($header);
|
||||
}
|
||||
}
|
||||
|
||||
sendHeader('content-length: ' . strlen($content));
|
||||
}
|
||||
|
||||
function getVisitIp()
|
||||
{
|
||||
$ipKeys = array(
|
||||
'HTTP_X_FORWARDED_FOR',
|
||||
'HTTP_CLIENT_IP',
|
||||
'HTTP_CF_CONNECTING_IP',
|
||||
);
|
||||
foreach($ipKeys as $ipKey) {
|
||||
if (isset($_SERVER[$ipKey])
|
||||
&& filter_var($_SERVER[$ipKey], FILTER_VALIDATE_IP) !== false
|
||||
) {
|
||||
return $_SERVER[$ipKey];
|
||||
}
|
||||
}
|
||||
return arrayValue($_SERVER, 'REMOTE_ADDR');
|
||||
}
|
||||
|
||||
function transformHeaderLine($headerLine)
|
||||
{
|
||||
// if we're not on an https protocol, make sure cookies do not have 'secure;'
|
||||
if (empty($_SERVER['HTTPS']) && preg_match('/^set-cookie:/i', $headerLine)) {
|
||||
$headerLine = str_replace('secure;', '', $headerLine);
|
||||
}
|
||||
return $headerLine;
|
||||
}
|
||||
|
||||
// captures a header line when using a curl request. would be better to use an anonymous function, but that would break
|
||||
// PHP 5.2 support.
|
||||
function handleHeaderLine($curl, $headerLine)
|
||||
{
|
||||
global $httpResponseHeaders;
|
||||
|
||||
$originalByteCount = strlen($headerLine);
|
||||
|
||||
$headerLine = transformHeaderLine($headerLine);
|
||||
$httpResponseHeaders[] = trim($headerLine);
|
||||
|
||||
return $originalByteCount;
|
||||
}
|
||||
|
||||
function getHttpContentAndStatus($url, $timeout, $user_agent)
|
||||
{
|
||||
global $httpResponseHeaders;
|
||||
global $DEBUG_PROXY;
|
||||
global $NO_VERIFY_SSL;
|
||||
global $http_ip_forward_header;
|
||||
|
||||
$useFopen = @ini_get('allow_url_fopen') == '1';
|
||||
|
||||
$header = array();
|
||||
$header[] = sprintf("Accept-Language: %s", str_replace(array("\n", "\t", "\r"), "", arrayValue($_SERVER, 'HTTP_ACCEPT_LANGUAGE', '')));
|
||||
|
||||
// NOTE: any changes made to Piwik\Plugins\PrivacyManager\DoNotTrackHeaderChecker must be made here as well
|
||||
if((isset($_SERVER['HTTP_X_DO_NOT_TRACK']) && $_SERVER['HTTP_X_DO_NOT_TRACK'] === '1')) {
|
||||
$header[] = "X-Do-Not-Track: 1";
|
||||
}
|
||||
|
||||
if((isset($_SERVER['HTTP_DNT']) && substr($_SERVER['HTTP_DNT'], 0, 1) === '1')) {
|
||||
$header[] = "DNT: 1";
|
||||
}
|
||||
|
||||
if (isset($_SERVER['HTTP_COOKIE'])) {
|
||||
$header[] = "Cookie: " . $_SERVER['HTTP_COOKIE'];
|
||||
}
|
||||
|
||||
$stream_options = array(
|
||||
'http' => array(
|
||||
'user_agent' => $user_agent,
|
||||
'header' => $header,
|
||||
'timeout' => $timeout,
|
||||
),
|
||||
);
|
||||
|
||||
if ($DEBUG_PROXY) {
|
||||
$stream_options['http']['ignore_errors'] = true;
|
||||
}
|
||||
|
||||
if ($NO_VERIFY_SSL) {
|
||||
$stream_options['ssl'] = array(
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
);
|
||||
}
|
||||
|
||||
// if there's POST data, send our proxy request as a POST
|
||||
if (!empty($_POST)) {
|
||||
$postBody = file_get_contents("php://input");
|
||||
|
||||
$stream_options['http']['method'] = 'POST';
|
||||
$stream_options['http']['header'][] = "Content-type: application/x-www-form-urlencoded";
|
||||
$stream_options['http']['header'][] = "Content-Length: " . strlen($postBody);
|
||||
$stream_options['http']['content'] = $postBody;
|
||||
|
||||
if(!empty($http_ip_forward_header)) {
|
||||
$visitIp = getVisitIp();
|
||||
$stream_options['http']['header'][] = "$http_ip_forward_header: $visitIp";
|
||||
}
|
||||
}
|
||||
|
||||
if($useFopen) {
|
||||
$ctx = stream_context_create($stream_options);
|
||||
|
||||
if ($DEBUG_PROXY) {
|
||||
$content = file_get_contents($url, 0, $ctx);
|
||||
} else {
|
||||
$content = @file_get_contents($url, 0, $ctx);
|
||||
}
|
||||
|
||||
$httpStatus = '';
|
||||
if (isset($http_response_header[0])) {
|
||||
$httpStatus = $http_response_header[0];
|
||||
$httpResponseHeaders = array_slice($http_response_header, 1);
|
||||
$httpResponseHeaders = array_map('transformHeaderLine', $httpResponseHeaders);
|
||||
}
|
||||
} else {
|
||||
if(!function_exists('curl_init')) {
|
||||
throw new Exception("You must either set allow_url_fopen=1 in your PHP configuration, or enable the PHP Curl extension.");
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $stream_options['http']['user_agent']);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $stream_options['http']['header']);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $stream_options['http']['timeout']);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $stream_options['http']['timeout']);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'handleHeaderLine');
|
||||
|
||||
if (!empty($stream_options['http']['method'])
|
||||
&& $stream_options['http']['method'] == 'POST'
|
||||
) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $stream_options['http']['content']);
|
||||
}
|
||||
|
||||
if (isset($stream_options['ssl']['verify_peer']) && $stream_options['ssl']['verify_peer'] == false) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
}
|
||||
|
||||
if (isset($stream_options['ssl']['verify_peer_name']) && $stream_options['ssl']['verify_peer'] == false) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
$content = curl_exec($ch);
|
||||
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if(!empty($httpStatus)) {
|
||||
$httpStatus = 'HTTP/1.1 ' . $httpStatus;
|
||||
}
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
return array(
|
||||
$content,
|
||||
$httpStatus,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function sendHeader($header, $replace = true)
|
||||
{
|
||||
headers_sent() || header($header, $replace);
|
||||
}
|
||||
|
||||
function arrayValue($array, $key, $value = null)
|
||||
{
|
||||
if (!empty($array[$key])) {
|
||||
$value = $array[$key];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
Reference in New Issue
Block a user