1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
/**
* This file is executed before anything else.
* It checks the minimum PHP version required to run Matomo.
* This file must be compatible with PHP 5.3.
*/
$piwik_errorMessage = '';
// Minimum requirement: stream_resolve_include_path, working json_encode in 5.3.3, namespaces in 5.3
// NOTE: when changing this variable, we also need to update
// 1) api.matomo.org
// 2) composer.json (in two places)
// 3) tests/PHPUnit/Integration/ReleaseCheckListTest.php
global $piwik_minimumPHPVersion;
$piwik_minimumPHPVersion = '7.2.5';
$piwik_currentPHPVersion = PHP_VERSION;
$minimumPhpInvalid = version_compare($piwik_minimumPHPVersion, $piwik_currentPHPVersion) > 0;
if ($minimumPhpInvalid) {
$piwik_errorMessage .= "<p><strong>To run Matomo you need at least PHP version $piwik_minimumPHPVersion</strong></p>
<p>Unfortunately it seems your webserver is using PHP version $piwik_currentPHPVersion. </p>
<p>Please try to update your PHP version, Matomo is really worth it! Nowadays most web hosts
support PHP $piwik_minimumPHPVersion.</p>";
} else {
if (!extension_loaded('session')) {
$piwik_errorMessage .= "<p><strong>Matomo and Zend_Session require the session extension</strong></p>
<p>It appears your PHP was compiled with <pre>--disable-session</pre>.
To enjoy Matomo, you need PHP compiled without that configure option.</p>";
}
if (!function_exists('ini_set')) {
$piwik_errorMessage .= "<p><strong>Matomo and Zend_Session require the <code>ini_set()</code> function</strong></p>
<p>It appears your PHP has disabled this function.
To enjoy Matomo, you need remove <pre>ini_set</pre> from your <pre>disable_functions</pre> directive in php.ini, and restart your webserver.</p>";
}
if (ini_get('mbstring.func_overload')) {
$piwik_errorMessage .= "<p><strong>Matomo does not work when PHP is configured with <pre>mbstring.func_overload = " . ini_get('mbstring.func_overload') . "</pre></strong></p>
<p>It appears your mbstring extension in PHP is configured to override string functions.
To enjoy Matomo, you need to modify php.ini <pre>mbstring.func_overload = 0</pre>, and restart your webserver.</p>";
}
if (!function_exists('json_encode')) {
$piwik_errorMessage .= "<p><strong>Matomo requires the php-json extension which provides the functions <code>json_encode()</code> and <code>json_decode()</code></strong></p>
<p>It appears your PHP has not yet installed the php-json extension.
To use Matomo, please ask your web host to install php-json or install it yourself, for example on debian system: <code>sudo apt-get install php-json</code>. <br/>Then restart your webserver and refresh this page.</p>";
}
if (!file_exists(PIWIK_VENDOR_PATH . '/autoload.php')) {
$composerInstall = "In the matomo directory, run in the command line the following (eg. via ssh): \n\n"
. "<pre> curl -sS https://getcomposer.org/installer | php \n\n php composer.phar install\n\n</pre> ";
if (DIRECTORY_SEPARATOR === '\\' /* ::isWindows() */) {
$composerInstall = "Download and run <a href=\"https://getcomposer.org/Composer-Setup.exe\"><b>Composer-Setup.exe</b></a>, it will install the latest Composer version and set up your PATH so that you can just call composer from any directory in your command line. "
. " <br>Then run this command in a terminal in the matomo directory: <br> $ php composer.phar install ";
}
$piwik_errorMessage .= "<p>It appears the <a href='https://getcomposer.org/' rel='noreferrer noopener' target='_blank'>composer</a> tool is not yet installed. You can install Composer in a few easy steps:\n\n" .
"<br/>" . $composerInstall .
" This will initialize composer for Matomo and download libraries we use in vendor/* directory." .
"\n\n<br/><br/>Then reload this page to access your analytics reports." .
"\n\n<br/><br/>For more information check out this FAQ: <a href='https://matomo.org/faq/how-to-install/faq_18271/' rel='noreferrer noopener' target='_blank'>How do I use Matomo from the Git repository?</a>." .
"\n\n<br/><br/>Note: if for some reasons you cannot install composer, instead install the latest Matomo release from " .
"<a href='https://builds.matomo.org/piwik.zip' rel='noreferrer noopener'>builds.matomo.org</a>.</p>";
}
}
define('PAGE_TITLE_WHEN_ERROR', 'Matomo › Error');
if (!function_exists('Piwik_GetErrorMessagePage')) {
/**
* Returns true if Piwik should print the backtrace with error messages.
*
* To make sure the backtrace is printed, define PIWIK_PRINT_ERROR_BACKTRACE.
*
* @return bool
*/
function Piwik_ShouldPrintBackTraceWithMessage()
{
if (!class_exists(\Piwik\ExceptionHandler::class)) {
return false;
}
return \Piwik\ExceptionHandler::shouldPrintBackTraceWithMessage();
}
/**
* Displays info/warning/error message in a friendly UI and exits.
*
* Note: this method should not be called by anyone other than FrontController.
*
* @param string $message Main message, must be html encoded before calling
* @param bool|string $optionalTrace Backtrace; will be displayed in lighter color
* @param bool $optionalLinks If true, will show links to the Piwik website for help
* @param bool $optionalLinkBack If true, displays a link to go back
* @param bool|string $logoUrl The URL to the logo to use.
* @param bool|string $faviconUrl The URL to the favicon to use.
* @param string $errorLogPrefix String to prepend to the error in log file
* @param bool $writeErrorLog If true then a webserver error log will be written, defaults to true
* @return string
*/
function Piwik_GetErrorMessagePage(
$message,
$optionalTrace = false,
$optionalLinks = false,
$optionalLinkBack = false,
$logoUrl = false,
$faviconUrl = false,
$isCli = null,
$errorLogPrefix = '',
$writeErrorLog = true,
$redirectUrl = null,
$countdown = null
) {
$hasCountdownRedirect = !empty($redirectUrl) && !empty($countdown);
if ($writeErrorLog) {
error_log(sprintf("{$errorLogPrefix}Error in Matomo: %s", str_replace("\n", " ", strip_tags($message))));
}
if (!headers_sent()) {
header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: private, no-cache, no-store');
$isInternalServerError = preg_match('/(sql|database|mysql)/i', $message);
if ($isInternalServerError) {
header('HTTP/1.1 500 Internal Server Error');
}
}
// We return only an HTML fragment for AJAX requests
if (
isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
) {
return "<div class='alert alert-danger'><strong>Error:</strong> $message</div>";
}
if (empty($logoUrl)) {
$logoUrl = "plugins/Morpheus/images/logo.svg";
}
if (empty($faviconUrl)) {
$faviconUrl = "plugins/CoreHome/images/favicon.png";
}
if ($optionalTrace) {
$optionalTrace = '<h2>Stack trace</h2><pre>' . htmlentities($optionalTrace, ENT_COMPAT | ENT_HTML401, 'UTF-8') . '</pre>';
}
if ($isCli === null) {
$isCli = PHP_SAPI == 'cli';
}
if ($optionalLinks) {
$adjustUrl = function ($url) {
if (class_exists(\Piwik\Url::class)) {
return \Piwik\Url::addCampaignParametersToMatomoLink($url);
}
return $url;
};
$optionalLinks = '<ul>
<li><a rel="noreferrer noopener" target="_blank" href="' . $adjustUrl('https://matomo.org') . '">Matomo.org homepage</a></li>
<li><a rel="noreferrer noopener" target="_blank" href="' . $adjustUrl('https://matomo.org/faq/') . '">Frequently Asked Questions</a></li>
<li><a rel="noreferrer noopener" target="_blank" href="' . $adjustUrl('https://matomo.org/docs/') . '">User Guides</a></li>
<li><a rel="noreferrer noopener" target="_blank" href="' . $adjustUrl('https://forum.matomo.org/') . '">Matomo Forums</a></li>
<li><a rel="noreferrer noopener" target="_blank" href="' . $adjustUrl('https://matomo.org/support/') . '">Professional Support for Matomo</a></li>
</ul>';
}
if ($optionalLinkBack) {
$optionalLinkBack = '<a href="javascript:window.history.back();">Go Back</a>';
}
$headerPage = file_get_contents(MATOMO_PLUGINS_PATH . '/plugins/Morpheus/templates/simpleLayoutHeader.tpl');
$headerPage = str_replace('%logoUrl%', $logoUrl, $headerPage);
$headerPage = str_replace('%faviconUrl%', $faviconUrl, $headerPage);
$footerPage = file_get_contents(MATOMO_PLUGINS_PATH . '/plugins/Morpheus/templates/simpleLayoutFooter.tpl');
$headerPage = str_replace('{$HTML_TITLE}', PAGE_TITLE_WHEN_ERROR, $headerPage);
$backLinks = '<p>'
. $optionalLinkBack
. ' | <a href="index.php">Go to Matomo</a>'
. '</p>';
$redirectSection = '';
if ($hasCountdownRedirect) {
$redirectSection = '<p>
Please click below if you are not redirected in ' . $countdown . ' seconds</br></br>
Go to <a href="' . $redirectUrl . '">' . htmlspecialchars($redirectUrl) . '</a>
</p>
<style>.header,.footer { display:none;}</style>
<script>setTimeout(function(){window.location.href="' . $redirectUrl . '"}, ' . ($countdown * 1000) . ');</script>';
$backLinks = '';
$optionalLinks = '';
}
$content = '<h2>' . $message . '</h2>'
. $redirectSection
. $backLinks
. ' ' . (Piwik_ShouldPrintBackTraceWithMessage() ? $optionalTrace : '')
. ' ' . $optionalLinks;
$message = str_replace(array("<br />", "<br>", "<br/>", "</p>"), "\n", $message);
$message = str_replace("\t", "", $message);
$message = strip_tags($message);
if (!$isCli) {
$message = $headerPage . $content . $footerPage;
}
$message .= "\n";
return $message;
}
}
if (!empty($piwik_errorMessage)) {
echo Piwik_GetErrorMessagePage($piwik_errorMessage, false, true);
exit(1);
}
|