PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.11.5
Independent Analytics – WordPress Analytics Plugin v2.11.5
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / iawp-click-endpoint.php
independent-analytics Last commit date
IAWP 1 year ago dist 1 year ago freemius 1 year ago img 1 year ago javascript-source 1 year ago languages 1 year ago vendor 1 year ago views 1 year ago iawp-bootstrap.php 1 year ago iawp-click-endpoint.php 1 year ago iawp.php 1 year ago readme.txt 1 year ago
iawp-click-endpoint.php
186 lines
1 <?php
2
3 // Warning. This file is a standalone PHP file whose sole purpose is to sanitize input and store
4 // that input in a CSV for later processing. WordPress is not loaded and the classes from the
5 // plugin are not available.
6
7 class Cache
8 {
9 private $attributes;
10
11 public function __construct(array $attributes)
12 {
13 $this->attributes = $attributes;
14 }
15
16 public function is_pro(): bool
17 {
18 return $this->attributes['is_pro'] === true;
19 }
20
21 public function get_upload_directory(): string
22 {
23 return trim($this->attributes['upload_directory']);
24 }
25
26 public function get_custom_ip_header(): ?string
27 {
28 if (array_key_exists('custom_ip_header', $this->attributes)) {
29 return trim($this->attributes['custom_ip_header']);
30 }
31
32 return null;
33 }
34
35 public function get_visitor_token_salt(): string
36 {
37 return trim($this->attributes['visitor_token_salt']);
38 }
39 }
40
41 function get_cache(): ?Cache
42 {
43 $file = __DIR__ . "/iawp-click-config.php";
44
45 if (!is_readable($file)) {
46 return null;
47 }
48
49 $contents = file_get_contents($file);
50
51 if (false === $contents) {
52 return null;
53 }
54
55 $lines = explode("\n", $contents);
56
57 if (count($lines) !== 2) {
58 return null;
59 }
60
61 $json = trim($lines[1]);
62 $data = json_decode($json, true);
63
64 if (is_null($data)) {
65 return null;
66 }
67
68 return new Cache($data);
69
70 }
71
72 function get_ip_address(Cache $cache): ?string
73 {
74 if (defined('IAWP_TEST_IP')) {
75 return IAWP_TEST_IP;
76 }
77
78 $headers = [
79 'HTTP_X_FORWARDED_FOR',
80 'HTTP_X_FORWARDED',
81 'HTTP_FORWARDED_FOR',
82 'HTTP_FORWARDED',
83 'REMOTE_ADDR',
84 'HTTP_CF_CONNECTING_IP',
85 'HTTP_CLIENT_IP',
86 'HTTP_INCAP_CLIENT_IP',
87 'HTTP_CF_CONNECTING_IP',
88 ];
89
90 if (is_string($cache->get_custom_ip_header())) {
91 array_unshift($headers, $cache->get_custom_ip_header());
92 }
93
94 foreach ($headers as $header) {
95 if (isset($_SERVER[$header])) {
96 return explode(',', $_SERVER[$header])[0];
97 }
98 }
99
100 return null;
101 }
102
103 function get_visitor_token(Cache $cache): ?string
104 {
105 return md5($cache->get_visitor_token_salt() . get_ip_address($cache) . $_SERVER['HTTP_USER_AGENT']);
106 }
107
108 function trailing_slash(string $path): string
109 {
110 $path = rtrim($path, '/\\');
111
112 return $path . DIRECTORY_SEPARATOR;
113 }
114
115 /**
116 * Get the path to the click data file and create it if needed.
117 *
118 * @return string
119 */
120 function get_click_data_file(): string
121 {
122 $text_file = trailing_slash(sys_get_temp_dir()) . "iawp-click-data.txt";
123
124 if (is_file($text_file) && is_readable($text_file) && is_writable($text_file)) {
125 return $text_file;
126 }
127
128 if (file_put_contents($text_file, "") !== false && file_get_contents($text_file) !== false) {
129 return $text_file;
130 }
131
132 $php_file = trailing_slash(__DIR__) . "iawp-click-data.php";
133
134 if (is_file($php_file)) {
135 return $php_file;
136 }
137
138 if (file_put_contents($php_file, "<?php exit; ?>\n") !== false) {
139 return $php_file;
140 }
141
142 // Unable to create either data file so there's nowhere to store the click data
143 exit;
144 }
145
146 $cache = get_cache();
147
148 if (is_null($cache) || is_null(get_ip_address($cache))) {
149 exit;
150 }
151
152 if (!$cache->is_pro()) {
153 exit;
154 }
155
156 $json_body = file_get_contents('php://input');
157 $body = json_decode($json_body, true);
158
159 if (is_null($body)) {
160 exit;
161 }
162
163 $click_data_file = get_click_data_file();
164 $data = [
165 'href' => $body['href'],
166 'classes' => $body['classes'],
167 'ids' => $body['ids'],
168 'payload' => json_encode($body['payload']),
169 'signature' => $body['signature'],
170 'visitor_token' => get_visitor_token($cache),
171 'created_at' => time(),
172 ];
173
174 if (!is_readable($click_data_file) || !is_writable($click_data_file)) {
175 exit;
176 }
177
178 $file_resource = fopen($click_data_file, 'a');
179
180 if (false === $file_resource) {
181 exit;
182 }
183
184 fwrite($file_resource, json_encode($data) . "\n");
185 fclose($file_resource);
186