WebOrbiton
v1.0.1

PriviMetrics 2

131 lines · 4.2 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. require_once __DIR__ . '/functions.php';
  5. ​
  6. if (!envIsInstalled()) {
  7. pmEmitPixelAndExit();
  8. }
  9. require_once __DIR__ . '/storage.php';
  10. ​
  11. header('Content-Type: image/gif');
  12. header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
  13. header('Pragma: no-cache');
  14. ​
  15. if (env('RESPECT_DNT', 'true') === 'true' && isDNTEnabled()) {
  16. echo pmPixel();
  17. exit;
  18. }
  19. ​
  20. $trackingCode = sanitize($_GET['t'] ?? '');
  21. if ($trackingCode === '') {
  22. echo pmPixel();
  23. exit;
  24. }
  25. ​
  26. $pageUrl = sanitize($_GET['p'] ?? '');
  27. $pageTitle = sanitize($_GET['title'] ?? '');
  28. $referrer = sanitize($_GET['r'] ?? '');
  29. ​
  30. $storage = new StorageManager();
  31. $site = $storage->findSiteByTrackingCode($trackingCode);
  32. ​
  33. if (!$site) {
  34. echo pmPixel();
  35. exit;
  36. }
  37. ​
  38. $domain = parse_url($pageUrl, PHP_URL_HOST) ?? '';
  39. if (!checkDomainMatch($site['domain'], $domain, $site['restriction_mode'])) {
  40. echo pmPixel();
  41. exit;
  42. }
  43. ​
  44. $rateLimit = pmRateLimitFor($site['storage'] ?? 'xml');
  45. if ($rateLimit['requests'] === 0) {
  46. http_response_code(204);
  47. exit;
  48. }
  49. if (!checkRateLimit('privimetrics_' . $trackingCode, $rateLimit['requests'], $rateLimit['window'])) {
  50. http_response_code(204);
  51. exit;
  52. }
  53. ​
  54. $parsedUrl = parse_url($pageUrl);
  55. $cleanUrl = ($parsedUrl['scheme'] ?? 'http') . '://' . ($parsedUrl['host'] ?? '');
  56. if (isset($parsedUrl['port'])) $cleanUrl .= ':' . $parsedUrl['port'];
  57. $cleanUrl .= $parsedUrl['path'] ?? '';
  58. ​
  59. $collectSearchQueries = pmFeatureEnabledForSite($site, 'search_queries');
  60. $collectTrafficSources = pmFeatureEnabledForSite($site, 'traffic_sources');
  61. $collectVisitorCountries = pmFeatureEnabledForSite($site, 'visitor_countries');
  62. ​
  63. $searchQuery = '';
  64. if ($collectSearchQueries && !empty($parsedUrl['query'])) {
  65. parse_str($parsedUrl['query'], $queryParams);
  66. foreach (['q', 'search', 'results'] as $param) {
  67. if (!empty($queryParams[$param])) {
  68. $searchQuery = sanitize($queryParams[$param]);
  69. break;
  70. }
  71. }
  72. }
  73. ​
  74. $utmSource = $collectTrafficSources ? extractUtmSource($pageUrl) : '';
  75. ​
  76. function pmIsExternalReferrer(string $referrer, string $pageUrl): bool
  77. {
  78. if ($referrer === '' || $pageUrl === '') return false;
  79. $refHost = parse_url($referrer, PHP_URL_HOST);
  80. $pageHost = parse_url($pageUrl, PHP_URL_HOST);
  81. if (!$refHost || !$pageHost) return false;
  82. $refHost = preg_replace('/^www\./i', '', strtolower($refHost));
  83. $pageHost = preg_replace('/^www\./i', '', strtolower($pageHost));
  84. return $refHost !== $pageHost;
  85. }
  86. ​
  87. function pmReferrerDomain(string $referrer): string
  88. {
  89. $host = parse_url($referrer, PHP_URL_HOST);
  90. if (!$host) return '';
  91. return preg_replace('/^www\./i', '', strtolower($host));
  92. }
  93. ​
  94. $trackIpParam = $_GET['track-ip'] ?? (env('TRACK_IP_DEFAULT', 'false') === 'true' ? 'true' : 'false');
  95. $trackIp = !in_array(strtolower((string) $trackIpParam), ['0', 'false', 'no'], true);
  96. ​
  97. if ($trackIp) {
  98. $realIP = getClientIP();
  99. $anonIP = '0.0.0.0';
  100. if (filter_var($realIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
  101. $parts = explode('.', $realIP);
  102. $anonIP = ($parts[0] ?? '0') . '.' . ($parts[1] ?? '0') . '.X.X';
  103. } elseif (filter_var($realIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
  104. $parts = explode(':', $realIP);
  105. $anonIP = ($parts[0] ?? '') . ':' . ($parts[1] ?? '') . ':XXXX:XXXX:XXXX:XXXX:XXXX:XXXX';
  106. }
  107. $geo = $collectVisitorCountries ? getCountryFromIP($realIP) : ['country' => 'Unknown', 'code' => 'XX'];
  108. } else {
  109. $anonIP = '0.0.0.0';
  110. $geo = $collectVisitorCountries ? getCountryFromIP($anonIP) : ['country' => 'Unknown', 'code' => 'XX'];
  111. }
  112. $userHash = pmVisitorHash(getClientIP(), getUserAgent(), (string) $domain);
  113. ​
  114. $hit = [
  115. 'user_hash' => $userHash,
  116. 'ip' => $anonIP,
  117. 'country' => $collectVisitorCountries ? ($geo['country'] ?? 'Unknown') : 'Unknown',
  118. 'country_code' => $collectVisitorCountries ? ($geo['code'] ?? 'XX') : 'XX',
  119. 'user_agent' => getUserAgent(),
  120. 'page_url' => $cleanUrl,
  121. 'page_title' => $pageTitle,
  122. 'search_query' => $searchQuery,
  123. 'referrer' => ($collectTrafficSources && pmIsExternalReferrer($referrer, $pageUrl)) ? pmReferrerDomain($referrer) : '',
  124. 'utm_source' => $utmSource,
  125. ];
  126. ​
  127. $storage->saveHit($site, $hit);
  128. ​
  129. echo pmPixel();
  130. exit;
  131. ​