isDebugModeEnabled() && TrackerConfig::getConfigValue('enable_sql_profiler')) {
$this->timer = new Timer();
TrackerDb::enableProfiling();
}
}
public function getOutput()
{
$this->outputAccessControlHeaders();
if (is_null($this->content) && ob_get_level() > 0) {
$this->content = ob_get_clean();
}
return $this->content;
}
/**
* Echos an error message & other information, then exits.
*
* @param Tracker $tracker
* @param Exception $e
* @param int $statusCode eg 500
*/
public function outputException(Tracker $tracker, Exception $e, $statusCode)
{
Common::sendResponseCode($statusCode);
$this->logExceptionToErrorLog($e);
if ($tracker->isDebugModeEnabled()) {
Common::sendHeader('Content-Type: text/html; charset=utf-8');
$trailer = 'Backtrace:
' . $e->getTraceAsString() . '
';
$headerPage = file_get_contents(PIWIK_INCLUDE_PATH . '/plugins/Morpheus/templates/simpleLayoutHeader.tpl');
$footerPage = file_get_contents(PIWIK_INCLUDE_PATH . '/plugins/Morpheus/templates/simpleLayoutFooter.tpl');
$headerPage = str_replace('{$HTML_TITLE}', 'Matomo › Error', $headerPage);
echo $headerPage . '
' . $this->getMessageFromException($e) . '
' . $trailer . $footerPage;
} else {
$this->outputApiResponse($tracker);
}
}
public function outputResponse(Tracker $tracker)
{
if (!$tracker->shouldRecordStatistics()) {
Common::sendResponseCode(503);
$this->outputApiResponse($tracker);
Common::printDebug("Logging disabled, display transparent logo");
} elseif (!$tracker->hasLoggedRequests()) {
if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) {
Common::sendResponseCode(400);
}
Common::printDebug("Empty request => Matomo page");
echo "This resource is part of Matomo. Keep full control of your data with the leading free and open source web analytics & conversion optimisation platform.
\n";
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 index.php instead.";
} else {
$this->outputApiResponse($tracker);
Common::printDebug("Nothing to notice => default behaviour");
}
Common::printDebug("End of the page.");
if ($tracker->isDebugModeEnabled()
&& $tracker->isDatabaseConnected()
&& TrackerDb::isProfilingEnabled()
) {
$db = Tracker::getDatabase();
$db->recordProfiling();
Profiler::displayDbTrackerProfile($db);
}
if ($tracker->isDebugModeEnabled()) {
Common::printDebug($_COOKIE);
Common::printDebug((string)$this->timer);
}
}
private function outputAccessControlHeaders()
{
if (!$this->isHttpGetRequest()) {
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
Common::sendHeader('Access-Control-Allow-Origin: ' . $origin);
Common::sendHeader('Access-Control-Allow-Credentials: true');
}
}
private function isHttpGetRequest()
{
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
return strtoupper($requestMethod) === 'GET';
}
private function getOutputBuffer()
{
return ob_get_contents();
}
protected function hasAlreadyPrintedOutput()
{
return strlen($this->getOutputBuffer()) > 0;
}
private function outputApiResponse(Tracker $tracker)
{
if ($tracker->isDebugModeEnabled()) {
return;
}
if ($this->hasAlreadyPrintedOutput()) {
return;
}
$request = $_GET + $_POST;
if ($this->isHttpGetRequest()) {
Common::sendHeader('Cache-Control: no-store');
}
if (array_key_exists('send_image', $request) && $request['send_image'] === '0') {
Common::sendResponseCode(204);
return;
}
$this->outputTransparentGif();
}
private function outputTransparentGif()
{
$transGifBase64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
Common::sendHeader('Content-Type: image/gif');
echo base64_decode($transGifBase64);
}
/**
* Gets the error message to output when a tracking request fails.
*
* @param Exception $e
* @return string
*/
protected function getMessageFromException($e)
{
// Note: duplicated from FormDatabaseSetup.isAccessDenied
// Avoid leaking the username/db name when access denied
if ($e->getCode() == 1044 || $e->getCode() == 42000) {
return "Error while connecting to the Matomo database - please check your credentials in config/config.ini.php file";
}
if (Common::isPhpCliMode()) {
return $e->getMessage() . "\n" . $e->getTraceAsString();
}
return $e->getMessage();
}
protected function logExceptionToErrorLog($e)
{
error_log(sprintf("Error in Matomo (tracker): %s", str_replace("\n", " ", $this->getMessageFromException($e))));
}
}