PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.2.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.2.0
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Tracker / Response.php
matomo / app / core / Tracker Last commit date
Db 1 year ago Handler 2 years ago Visit 1 year ago Action.php 1 year ago ActionPageview.php 2 years ago Cache.php 1 year ago Db.php 1 year ago Failures.php 1 year ago FingerprintSalt.php 1 year ago GoalManager.php 1 year ago Handler.php 2 years ago IgnoreCookie.php 1 year ago LogTable.php 1 year ago Model.php 1 year ago PageUrl.php 1 year ago Request.php 1 year ago RequestProcessor.php 1 year ago RequestSet.php 1 year ago Response.php 1 year ago ScheduledTasksRunner.php 1 year ago Settings.php 1 year ago TableLogAction.php 1 year ago TrackerCodeGenerator.php 1 year ago TrackerConfig.php 2 years ago Visit.php 1 year ago VisitExcluded.php 1 year ago VisitInterface.php 2 years ago Visitor.php 1 year ago VisitorNotFoundInDb.php 2 years ago VisitorRecognizer.php 1 year ago
Response.php
194 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 */
9 namespace Piwik\Tracker;
10
11 use Exception;
12 use Piwik\Common;
13 use Piwik\Config;
14 use Piwik\Profiler;
15 use Piwik\Timer;
16 use Piwik\Tracker;
17 use Piwik\Tracker\Db as TrackerDb;
18 use Piwik\Url;
19 class Response
20 {
21 private $timer;
22 private $content;
23 public function init(Tracker $tracker)
24 {
25 ob_start();
26 // we use ob_start only because of Common::printDebug, we should actually not really use ob_start
27 if ($tracker->isDebugModeEnabled() && \Piwik\Tracker\TrackerConfig::getConfigValue('enable_sql_profiler')) {
28 $this->timer = new Timer();
29 TrackerDb::enableProfiling();
30 }
31 }
32 public function getOutput()
33 {
34 $this->outputAccessControlHeaders();
35 if (is_null($this->content) && ob_get_level() > 0) {
36 $this->content = ob_get_clean();
37 }
38 return $this->content;
39 }
40 /**
41 * Echos an error message & other information, then exits.
42 *
43 * @param Tracker $tracker
44 * @param Exception $e
45 * @param int $statusCode eg 500
46 */
47 public function outputException(Tracker $tracker, Exception $e, $statusCode)
48 {
49 Common::sendResponseCode($statusCode);
50 $this->logExceptionToErrorLog($e);
51 if ($tracker->isDebugModeEnabled()) {
52 echo "\nAn exception occurred: " . $this->getMessageFromException($e) . "\n\n";
53 } else {
54 $this->outputApiResponse($tracker);
55 }
56 }
57 public function outputResponse(Tracker $tracker)
58 {
59 if (!$tracker->shouldRecordStatistics()) {
60 Common::sendResponseCode(503);
61 $this->outputApiResponse($tracker);
62 Common::printDebug("Logging disabled, display transparent logo");
63 } elseif (!$tracker->hasLoggedRequests()) {
64 if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) {
65 Common::sendResponseCode(400);
66 }
67 Common::printDebug("Empty request => Matomo page");
68 echo "This resource is part of Matomo. Keep full control of your data with the leading free and open source <a href='https://matomo.org' target='_blank' rel='noopener noreferrer nofollow'>web analytics & conversion optimisation platform</a>.<br>\n";
69 echo "This file is the endpoint for the Matomo tracking API. If you want to access the Matomo UI or use the Reporting API, please use <a href='index.php'>index.php</a> instead.\n";
70 } else {
71 $this->outputApiResponse($tracker);
72 Common::printDebug("Nothing to notice => default behaviour");
73 }
74 Common::printDebug("End of the page.");
75 if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) {
76 $db = Tracker::getDatabase();
77 $db->recordProfiling();
78 Profiler::displayDbTrackerProfile($db);
79 }
80 if ($tracker->isDebugModeEnabled()) {
81 Common::printDebug($_COOKIE);
82 Common::printDebug((string) $this->timer);
83 }
84 }
85 private function outputAccessControlHeaders()
86 {
87 if (!$this->isHttpGetRequest()) {
88 $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
89 Common::sendHeader('Access-Control-Allow-Origin: ' . $origin);
90 Common::sendHeader('Access-Control-Allow-Credentials: true');
91 }
92 }
93 private function isHttpGetRequest()
94 {
95 $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
96 return strtoupper($requestMethod) === 'GET';
97 }
98 private function getOutputBuffer()
99 {
100 return ob_get_contents();
101 }
102 protected function hasAlreadyPrintedOutput()
103 {
104 return strlen($this->getOutputBuffer()) > 0;
105 }
106 private function outputApiResponse(Tracker $tracker)
107 {
108 if ($tracker->isDebugModeEnabled()) {
109 return;
110 }
111 if ($this->hasAlreadyPrintedOutput()) {
112 return;
113 }
114 $request = $_GET + $_POST;
115 if ($this->isHttpGetRequest()) {
116 Common::sendHeader('Cache-Control: no-store');
117 }
118 if (array_key_exists('send_image', $request) && $request['send_image'] === '0') {
119 Common::sendResponseCode(204);
120 return;
121 }
122 // Check for a custom tracking image
123 $customImage = Config::getInstance()->Tracker['custom_image'];
124 if (!empty($customImage) && $this->outputCustomImage($customImage)) {
125 return;
126 }
127 // No custom image defined, so output the default 1x1 base64 transparent gif
128 $this->outputTransparentGif();
129 }
130 /**
131 * Output a 1px x 1px transparent gif
132 */
133 private function outputTransparentGif()
134 {
135 $transGifBase64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
136 Common::sendHeader('Content-Type: image/gif');
137 echo base64_decode($transGifBase64);
138 }
139 /**
140 * Output a custom tracking image
141 *
142 * @param string $customImage The custom image setting specified in the config
143 *
144 * @return bool True if the custom image was successfully output, else false
145 */
146 private function outputCustomImage(string $customImage) : bool
147 {
148 $supportedMimeTypes = ['image/png', 'image/gif', 'image/jpeg'];
149 $img = null;
150 $size = null;
151 if (strlen($customImage) > 2 && substr($customImage, -2) == '==') {
152 // Base64 image string
153 $img = base64_decode($customImage);
154 $size = getimagesizefromstring($img);
155 } elseif (is_file($customImage) && is_readable($customImage)) {
156 // Image file
157 $img = file_get_contents($customImage);
158 $size = getimagesize($customImage);
159 // imagesize is used to get the mime type
160 }
161 // Must have valid image data and a valid mime type to proceed
162 if ($img && $size && isset($size['mime']) && in_array($size['mime'], $supportedMimeTypes)) {
163 Common::sendHeader('Content-Type: ' . $size['mime']);
164 echo $img;
165 return \true;
166 }
167 return \false;
168 }
169 /**
170 * Gets the error message to output when a tracking request fails.
171 *
172 * @param Exception $e
173 * @return string
174 */
175 protected function getMessageFromException($e)
176 {
177 // Note: duplicated from FormDatabaseSetup.isAccessDenied
178 // Avoid leaking the username/db name when access denied
179 if ($e->getCode() == 1044 || $e->getCode() == 42000) {
180 return "Error while connecting to the Matomo database - please check your credentials in config/config.ini.php file";
181 }
182 if (Common::isPhpCliMode()) {
183 return $e->getMessage() . "\n" . $e->getTraceAsString();
184 }
185 return $e->getMessage();
186 }
187 protected function logExceptionToErrorLog($e)
188 {
189 $hostname = Url::getRFCValidHostname();
190 $hostStr = $hostname ? "[{$hostname}]" : '-';
191 error_log(sprintf("{$hostStr} Error in Matomo (tracker): %s", str_replace("\n", " ", $this->getMessageFromException($e))));
192 }
193 }
194