PDF rausgenommen

This commit is contained in:
aschwarz
2023-01-23 11:03:31 +01:00
parent 82d562a322
commit a6523903eb
28078 changed files with 4247552 additions and 2 deletions

View File

@ -0,0 +1,48 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\CliMulti;
use Piwik\Config;
use Piwik\Http;
use Piwik\Translation\Translator;
use Piwik\Url;
/**
* Check if cron archiving can run through CLI.
*/
class CronArchivingCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckCronArchiveProcess');
$comment = $this->translator->translate('Installation_SystemCheckCronArchiveProcessCLI') . ': ';
$process = new CliMulti();
if ($process->supportsAsync()) {
$comment .= $this->translator->translate('General_Ok');
} else {
$comment .= $this->translator->translate('Installation_NotSupported')
. ' ' . $this->translator->translate('Goals_Optional');
}
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $comment));
}
}

View File

@ -0,0 +1,109 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\ArchiveProcessor\Rules;
use Piwik\Config;
use Piwik\CronArchive;
use Piwik\Date;
use Piwik\Metrics\Formatter;
use Piwik\Option;
use Piwik\Plugins\Intl\DateTimeFormatProvider;
use Piwik\SettingsPiwik;
use Piwik\Translation\Translator;
/**
* Check if cron archiving has run in the last 24-48 hrs.
*/
class CronArchivingLastRunCheck implements Diagnostic
{
const SECONDS_IN_DAY = 86400;
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
if (!SettingsPiwik::isMatomoInstalled()) {
return [];
}
$label = $this->translator->translate('Diagnostics_CronArchivingLastRunCheck');
$commandToRerun = '<code>' . $this->getArchivingCommand() . '</code>';
$coreArchiveShort = '<code>core:archive</code>';
$mailto = '<code>MAILTO</code>';
// check cron archiving has been enabled
$isBrowserTriggerDisabled = !Rules::isBrowserTriggerEnabled();
if (!$isBrowserTriggerDisabled) {
$comment = $this->translator->translate('Diagnostics_BrowserTriggeredArchivingEnabled', [
'<a href="https://matomo.org/docs/setup-auto-archiving/" target="_blank" rel="noreferrer noopener">', '</a>']);
return [DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)];
}
// check archiving has been run
$lastRunTime = (int)Option::get(CronArchive::OPTION_ARCHIVING_FINISHED_TS);
if (empty($lastRunTime)) {
$comment = $this->translator->translate('Diagnostics_CronArchivingHasNotRun')
. '<br/><br/>' . $this->translator->translate('Diagnostics_CronArchivingRunDetails', [$coreArchiveShort, $mailto, $commandToRerun]);;
return [DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_ERROR, $comment)];
}
$lastRunTimePretty = Date::factory($lastRunTime)->getLocalized(DateTimeFormatProvider::DATETIME_FORMAT_LONG);
$diffTime = self::getTimeSinceLastSuccessfulRun($lastRunTime);
$formatter = new Formatter();
$diffTimePretty = $formatter->getPrettyTimeFromSeconds($diffTime);
$errorComment = $this->translator->translate('Diagnostics_CronArchivingHasNotRunInAWhile', [$lastRunTimePretty, $diffTimePretty])
. '<br/><br/>' . $this->translator->translate('Diagnostics_CronArchivingRunDetails', [$coreArchiveShort, $mailto, $commandToRerun]);
// check archiving has been run recently
if ($diffTime > self::SECONDS_IN_DAY * 2) {
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_ERROR, $errorComment);
} else if ($diffTime > self::SECONDS_IN_DAY) {
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $errorComment);
} else {
$comment = $this->translator->translate('Diagnostics_CronArchivingRanSuccessfullyXAgo', $diffTimePretty);
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $comment);
}
return [$result];
}
private function getArchivingCommand()
{
$domain = Config::getHostname();
return PIWIK_INCLUDE_PATH . ' --matomo-domain=' . $domain . ' core:archive';
}
public static function getTimeSinceLastSuccessfulRun($lastRunTime = null)
{
if (empty($lastRunTime)) {
$lastRunTime = (int)Option::get(CronArchive::OPTION_ARCHIVING_FINISHED_TS);
}
if (empty($lastRunTime)) {
return null;
}
$now = Date::now()->getTimestamp();
$diffTime = $now - $lastRunTime;
return $diffTime;
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Db\Adapter;
use Piwik\SettingsServer;
use Piwik\Translation\Translator;
/**
* Check supported DB adapters are available.
*/
class DbAdapterCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$results = array();
$results[] = $this->checkPdo();
$results = array_merge($results, $this->checkDbAdapters());
return $results;
}
private function checkPdo()
{
$label = 'PDO ' . $this->translator->translate('Installation_Extension');
if (extension_loaded('PDO')) {
$status = DiagnosticResult::STATUS_OK;
} else {
$status = DiagnosticResult::STATUS_WARNING;
}
return DiagnosticResult::singleResult($label, $status);
}
private function checkDbAdapters()
{
$results = array();
$adapters = Adapter::getAdapters();
foreach ($adapters as $adapter => $port) {
$label = $adapter . ' ' . $this->translator->translate('Installation_Extension');
$results[] = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK);
}
if (empty($adapters)) {
$label = $this->translator->translate('Installation_SystemCheckDatabaseExtensions');
$comment = $this->translator->translate('Installation_SystemCheckDatabaseHelp');
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_ERROR, $comment);
$result->setLongErrorMessage($this->getLongErrorMessage());
$results[] = $result;
}
return $results;
}
private function getLongErrorMessage()
{
$message = '<p>';
if (SettingsServer::isWindows()) {
$message .= $this->translator->translate(
'Installation_SystemCheckWinPdoAndMysqliHelp',
array('<br /><br /><code>extension=php_mysqli.dll</code><br /><code>extension=php_pdo.dll</code><br /><code>extension=php_pdo_mysql.dll</code><br />')
);
} else {
$message .= $this->translator->translate(
'Installation_SystemCheckPdoAndMysqliHelp',
array(
'<br /><br /><code>--with-mysqli</code><br /><code>--with-pdo-mysql</code><br /><br />',
'<br /><br /><code>extension=mysqli.so</code><br /><code>extension=pdo.so</code><br /><code>extension=pdo_mysql.so</code><br />'
)
);
}
$message .= $this->translator->translate('Installation_RestartWebServer') . '<br/><br/>';
$message .= $this->translator->translate('Installation_SystemCheckPhpPdoAndMysqli', array(
'<a style="color:red" href="http://php.net/pdo">',
'</a>',
'<a style="color:red" href="http://php.net/mysqli">',
'</a>',
));
$message .= '</p>';
return $message;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Db;
use Piwik\MetricsFormatter;
use Piwik\Piwik;
use Piwik\SettingsPiwik;
use Piwik\Translation\Translator;
/**
* Check if Piwik is connected with database through ssl.
*/
class DbMaxPacket implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
const MIN_VALUE_MAX_PACKET_MB = 64;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
if (!SettingsPiwik::isPiwikInstalled()) {
return array(); // only possible to perform check once we have DB connection
}
$maxPacketBytes = Db::fetchRow("SHOW VARIABLES LIKE 'max_allowed_packet'");
$status = DiagnosticResult::STATUS_OK;
$label = $this->translator->translate('Diagnostics_MysqlMaxPacketSize');
$comment = '';
$minSize = self::MIN_VALUE_MAX_PACKET_MB * 1000 * 1000; // not using 1024 just in case... this amount be good enough
if (!empty($maxPacketBytes['Value']) && $maxPacketBytes['Value'] < $minSize) {
$status = DiagnosticResult::STATUS_WARNING;
$pretty = MetricsFormatter::getPrettySizeFromBytes($maxPacketBytes['Value'], 'M');
$configured = str_replace(array(' M', '&nbsp;M'), 'MB', $pretty);
$comment = Piwik::translate('Diagnostics_MysqlMaxPacketSizeWarning', array('64MB', $configured));
}
return array(DiagnosticResult::singleResult($label, $status, $comment));
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Common;
use Piwik\Config;
use Piwik\Db;
use Piwik\Translation\Translator;
/**
* Check if Piwik is connected with database through ssl.
*/
class DbOverSSLCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$enable_ssl = Config::getInstance()->database['enable_ssl'];
if (!$enable_ssl) {
return array();
}
$label = $this->translator->translate('Installation_SystemCheckDatabaseSSL');
$cipher = Db::fetchRow("show status like 'Ssl_cipher'");
if(!empty($cipher['Value'])) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $this->translator->translate('Installation_SystemCheckDatabaseSSLCipher') . ': ' . $cipher['Value']));
}
//no cipher, not working
$comment = sprintf($this->translator->translate('Installation_SystemCheckDatabaseSSLNotWorking'), "enable_ssl") . "<br />";
// test ssl support
$ssl_support = Db::fetchRow("SHOW VARIABLES LIKE 'have_ssl'");
if(!empty($ssl_support['Value'])) {
switch ($ssl_support['Value']) {
case 'YES':
$comment .= $this->translator->translate('Installation_SystemCheckDatabaseSSLOn');
break;
case 'DISABLED':
$comment .= $this->translator->translate('Installation_SystemCheckDatabaseSSLDisabled');
break;
case 'NO':
$comment .= $this->translator->translate('Installation_SystemCheckDatabaseSSLNo');
break;
}
}
$comment .= '<br />' . '<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/"> FAQ on matomo.org</a>';
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
/**
* Performs a diagnostic on the system or Piwik.
*
* Example:
*
* class MyDiagnostic implements Diagnostic
* {
* public function execute()
* {
* $results = array();
*
* // First check (error)
* $status = testSomethingIsOk() ? DiagnosticResult::STATUS_OK : DiagnosticResult::STATUS_ERROR;
* $results[] = DiagnosticResult::singleResult('First check', $status);
*
* // Second check (warning)
* $status = testSomethingElseIsOk() ? DiagnosticResult::STATUS_OK : DiagnosticResult::STATUS_WARNING;
* $results[] = DiagnosticResult::singleResult('Second check', $status);
*
* return $results;
* }
* }
*
* Diagnostics are loaded with dependency injection support.
*
* @api
*/
interface Diagnostic
{
/**
* @return DiagnosticResult[]
*/
public function execute();
}

View File

@ -0,0 +1,121 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
/**
* The result of a diagnostic.
*
* @api
*/
class DiagnosticResult
{
const STATUS_ERROR = 'error';
const STATUS_WARNING = 'warning';
const STATUS_OK = 'ok';
/**
* @var string
*/
private $label;
/**
* @var string
*/
private $longErrorMessage = '';
/**
* @var DiagnosticResultItem[]
*/
private $items = array();
public function __construct($label)
{
$this->label = $label;
}
/**
* @param string $label
* @param string $status
* @param string $comment
* @return DiagnosticResult
*/
public static function singleResult($label, $status, $comment = '')
{
$result = new self($label);
$result->addItem(new DiagnosticResultItem($status, $comment));
return $result;
}
/**
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* @return DiagnosticResultItem[]
*/
public function getItems()
{
return $this->items;
}
public function addItem(DiagnosticResultItem $item)
{
$this->items[] = $item;
}
/**
* @param DiagnosticResultItem[] $items
*/
public function setItems(array $items)
{
$this->items = $items;
}
/**
* @return string
*/
public function getLongErrorMessage()
{
return $this->longErrorMessage;
}
/**
* @param string $longErrorMessage
*/
public function setLongErrorMessage($longErrorMessage)
{
$this->longErrorMessage = $longErrorMessage;
}
/**
* Returns the worst status of the items.
*
* @return string One of the `STATUS_*` constants.
*/
public function getStatus()
{
$status = self::STATUS_OK;
foreach ($this->getItems() as $item) {
if ($item->getStatus() === self::STATUS_ERROR) {
return self::STATUS_ERROR;
}
if ($item->getStatus() === self::STATUS_WARNING) {
$status = self::STATUS_WARNING;
}
}
return $status;
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
/**
* @api
*/
class DiagnosticResultItem
{
/**
* @var string
*/
private $status;
/**
* Optional comment about the item.
*
* @var string
*/
private $comment;
public function __construct($status, $comment = '')
{
$this->status = $status;
$this->comment = $comment;
}
/**
* @return string
*/
public function getStatus()
{
return $this->status;
}
/**
* @return string
*/
public function getComment()
{
return $this->comment;
}
}

View File

@ -0,0 +1,55 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Development;
use Piwik\FileIntegrity;
use Piwik\Translation\Translator;
/**
* Check the files integrity.
*/
class FileIntegrityCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckFileIntegrity');
if(Development::isEnabled()) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, '(Disabled in development mode)'));
}
list($ok, $messages) = FileIntegrity::getFileIntegrityInformation();
if ($ok) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, implode('<br/>', $messages)));
}
$comment = $this->translator->translate('General_FileIntegrityWarning');
// Keep only the 20 first lines else it becomes unmanageable
if (count($messages) > 20) {
$messages = array_slice($messages, 0, 20);
$messages[] = '...';
}
$comment .= '<br/><br/><pre style="overflow-x: scroll;max-width: 600px;">'
. implode("\n", $messages) . '</pre>';
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* Matomo - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\ProxyHttp;
use Piwik\Translation\Translator;
use Piwik\Url;
/**
* Check that Matomo is configured to force SSL.
*/
class ForceSSLCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('General_ForcedSSL');
// special handling during install
$isPiwikInstalling = !Config::getInstance()->existsLocalConfig();
if ($isPiwikInstalling) {
if (ProxyHttp::isHttps()) {
return [];
}
$message = $this->translator->translate('General_UseSSLInstall', [
'<a href="https://'. Url::getCurrentHost() . Url::getCurrentScriptName(false) . Url::getCurrentQueryString() .'">',
'</a>'
]);
return [DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $message)];
}
$forceSSLEnabled = (Config::getInstance()->General['force_ssl'] == 1);
if ($forceSSLEnabled) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
}
$comment = $this->translator->translate('General_ForceSSLRecommended', ['<code>force_ssl = 1</code>', '<code>General</code>']);
if (!ProxyHttp::isHttps()) {
$comment .= '<br /><br />' . $this->translator->translate('General_NotPossibleWithoutHttps');
}
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\SettingsServer;
use Piwik\Translation\Translator;
/**
* Check that the GD extension is installed and the correct version.
*/
class GdExtensionCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckGDFreeType');
if (SettingsServer::isGdExtensionEnabled()) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
}
$comment = sprintf(
'%s<br />%s',
$this->translator->translate('Installation_SystemCheckGDFreeType'),
$this->translator->translate('Installation_SystemCheckGDHelp')
);
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\Filechecks;
use Piwik\Http;
use Piwik\Translation\Translator;
/**
* Check that Piwik's HTTP client can work correctly.
*/
class HttpClientCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckOpenURL');
$httpMethod = Http::getTransportMethod();
if ($httpMethod) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $httpMethod));
}
$canAutoUpdate = Filechecks::canAutoUpdate();
$comment = $this->translator->translate('Installation_SystemCheckOpenURLHelp');
if (! $canAutoUpdate) {
$comment .= '<br/>' . $this->translator->translate('Installation_SystemCheckAutoUpdateHelp');
}
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,87 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Common;
use Piwik\Config;
use Piwik\Db;
use Piwik\Translation\Translator;
/**
* Check if Piwik can use LOAD DATA INFILE.
*/
class LoadDataInfileCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$isPiwikInstalling = !Config::getInstance()->existsLocalConfig();
if ($isPiwikInstalling) {
// Skip the diagnostic if Piwik is being installed
return array();
}
$label = $this->translator->translate('Installation_DatabaseAbilities');
$optionTable = Common::prefixTable('option');
$testOptionNames = array('test_system_check1', 'test_system_check2');
$loadDataInfile = false;
$errorMessage = null;
try {
$loadDataInfile = Db\BatchInsert::tableInsertBatch(
$optionTable,
array('option_name', 'option_value'),
array(
array($testOptionNames[0], '1'),
array($testOptionNames[1], '2'),
),
$throwException = true,
$charset = 'latin1'
);
} catch (\Exception $ex) {
$errorMessage = str_replace("\n", "<br/>", $ex->getMessage());
}
// delete the temporary rows that were created
Db::exec("DELETE FROM `$optionTable` WHERE option_name IN ('" . implode("','", $testOptionNames) . "')");
if ($loadDataInfile) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, 'LOAD DATA INFILE'));
}
$comment = sprintf(
'LOAD DATA INFILE<br/>%s<br/>%s',
$this->translator->translate('Installation_LoadDataInfileUnavailableHelp', array(
'LOAD DATA INFILE',
'FILE',
)),
$this->translator->translate('Installation_LoadDataInfileRecommended')
);
if ($errorMessage) {
$comment .= sprintf(
'<br/><strong>%s:</strong> %s<br/>%s',
$this->translator->translate('General_Error'),
$errorMessage,
'Troubleshooting: <a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/troubleshooting/#faq_194">FAQ on matomo.org</a>'
);
}
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,57 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\SettingsServer;
use Piwik\Translation\Translator;
/**
* Check that the memory limit is enough.
*/
class MemoryLimitCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
/**
* @var int
*/
private $minimumMemoryLimit;
public function __construct(Translator $translator, $minimumMemoryLimit)
{
$this->translator = $translator;
$this->minimumMemoryLimit = $minimumMemoryLimit;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckMemoryLimit');
SettingsServer::raiseMemoryLimitIfNecessary();
$memoryLimit = SettingsServer::getMemoryLimitValue();
$comment = $memoryLimit . 'M';
if ($memoryLimit >= $this->minimumMemoryLimit) {
$status = DiagnosticResult::STATUS_OK;
} else {
$status = DiagnosticResult::STATUS_WARNING;
$comment .= sprintf(
'<br />%s<br />%s',
$this->translator->translate('Installation_SystemCheckMemoryLimitHelp'),
$this->translator->translate('Installation_RestartWebServer')
);
}
return array(DiagnosticResult::singleResult($label, $status, $comment));
}
}

View File

@ -0,0 +1,55 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\Filesystem;
use Piwik\Translation\Translator;
/**
* Checks if the filesystem Piwik stores sessions in is NFS or not.
*
* This check is done in order to avoid using file based sessions on NFS system,
* since on such a filesystem file locking can make file based sessions incredibly slow.
*/
class NfsDiskCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_Filesystem');
if (! Filesystem::checkIfFileSystemIsNFS()) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
}
$isPiwikInstalling = !Config::getInstance()->existsLocalConfig();
if ($isPiwikInstalling) {
$help = 'Installation_NfsFilesystemWarningSuffixInstall';
} else {
$help = 'Installation_NfsFilesystemWarningSuffixAdmin';
}
$comment = sprintf(
'%s<br />%s',
$this->translator->translate('Installation_NfsFilesystemWarning'),
$this->translator->translate($help)
);
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\Http;
use Piwik\Translation\Translator;
use Piwik\Url;
use Psr\Log\LoggerInterface;
/**
* Check that mod_pagespeed is not enabled.
*/
class PageSpeedCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(Translator $translator, LoggerInterface $logger)
{
$this->translator = $translator;
$this->logger = $logger;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckPageSpeedDisabled');
if (! $this->isPageSpeedEnabled()) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
}
$comment = $this->translator->translate('Installation_SystemCheckPageSpeedWarning', array(
'(eg. Apache, Nginx or IIS)',
));
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
private function isPageSpeedEnabled()
{
$url = Url::getCurrentUrlWithoutQueryString() . '?module=Installation&action=getEmptyPageForSystemCheck';
try {
$page = Http::sendHttpRequest($url,
$timeout = 1,
$userAgent = null,
$destinationPath = null,
$followDepth = 0,
$acceptLanguage = false,
$byteRange = false,
// Return headers
$getExtendedInfo = true
);
} catch(\Exception $e) {
$this->logger->info('Unable to test if mod_pagespeed is enabled: the request to {url} failed', array(
'url' => $url,
));
// If the test failed, we assume Page speed is not enabled
return false;
}
return isset($page['headers']['X-Mod-Pagespeed']) || isset($page['headers']['X-Page-Speed']);
}
}

View File

@ -0,0 +1,85 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Translation\Translator;
/**
* Check the PHP extensions.
*/
class PhpExtensionsCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckExtensions');
$result = new DiagnosticResult($label);
$longErrorMessage = '';
$requiredExtensions = $this->getRequiredExtensions();
foreach ($requiredExtensions as $extension) {
if (! extension_loaded($extension)) {
$status = DiagnosticResult::STATUS_ERROR;
$comment = $extension . ': ' . $this->translator->translate('Installation_RestartWebServer');
$longErrorMessage .= '<p>' . $this->getHelpMessage($extension) . '</p>';
} else {
$status = DiagnosticResult::STATUS_OK;
$comment = $extension;
}
$result->addItem(new DiagnosticResultItem($status, $comment));
}
$result->setLongErrorMessage($longErrorMessage);
return array($result);
}
/**
* @return string[]
*/
private function getRequiredExtensions()
{
$requiredExtensions = array(
'zlib',
'SPL',
'iconv',
'json',
'mbstring',
'Reflection',
);
return $requiredExtensions;
}
private function getHelpMessage($missingExtension)
{
$messages = array(
'zlib' => 'Installation_SystemCheckZlibHelp',
'SPL' => 'Installation_SystemCheckSplHelp',
'iconv' => 'Installation_SystemCheckIconvHelp',
'json' => 'Installation_SystemCheckWarnJsonHelp',
'mbstring' => 'Installation_SystemCheckMbstringHelp',
'Reflection' => 'Required extension that is built in PHP, see http://www.php.net/manual/en/book.reflection.php',
);
return $this->translator->translate($messages[$missingExtension]);
}
}

View File

@ -0,0 +1,113 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Translation\Translator;
/**
* Check the enabled PHP functions.
*/
class PhpFunctionsCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckFunctions');
$result = new DiagnosticResult($label);
foreach ($this->getRequiredFunctions() as $function) {
if (! self::functionExists($function)) {
$status = DiagnosticResult::STATUS_ERROR;
$comment = sprintf(
'%s <br/><br/><em>%s</em><br/><em>%s</em><br/>',
$function,
$this->getHelpMessage($function),
$this->translator->translate('Installation_RestartWebServer')
);
} else {
$status = DiagnosticResult::STATUS_OK;
$comment = $function;
}
$result->addItem(new DiagnosticResultItem($status, $comment));
}
return array($result);
}
/**
* @return string[]
*/
private function getRequiredFunctions()
{
return array(
'debug_backtrace',
'create_function',
'eval',
'hash',
'gzcompress',
'gzuncompress',
'pack',
);
}
/**
* Tests if a function exists. Also handles the case where a function is disabled via Suhosin.
*
* @param string $function
* @return bool
*/
public static function functionExists($function)
{
// eval() is a language construct
if ($function == 'eval') {
// does not check suhosin.executor.eval.whitelist (or blacklist)
if (extension_loaded('suhosin')) {
return @ini_get("suhosin.executor.disable_eval") != "1";
}
return true;
}
$exists = function_exists($function);
if (extension_loaded('suhosin')) {
$blacklist = @ini_get("suhosin.executor.func.blacklist");
if (!empty($blacklist)) {
$blacklistFunctions = array_map('strtolower', array_map('trim', explode(',', $blacklist)));
return $exists && !in_array($function, $blacklistFunctions);
}
}
return $exists;
}
private function getHelpMessage($missingFunction)
{
$messages = array(
'debug_backtrace' => 'Installation_SystemCheckDebugBacktraceHelp',
'create_function' => 'Installation_SystemCheckCreateFunctionHelp',
'eval' => 'Installation_SystemCheckEvalHelp',
'hash' => 'Installation_SystemCheckHashHelp',
'gzcompress' => 'Installation_SystemCheckGzcompressHelp',
'gzuncompress' => 'Installation_SystemCheckGzuncompressHelp',
'pack' => 'Installation_SystemCheckPackHelp',
);
return $this->translator->translate($messages[$missingFunction]);
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Translation\Translator;
/**
* Check some PHP INI settings.
*/
class PhpSettingsCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckSettings');
$result = new DiagnosticResult($label);
foreach ($this->getRequiredSettings() as $setting) {
if (!$setting->check()) {
$status = $setting->getErrorResult();
$comment = sprintf(
'%s <br/><br/><em>%s</em><br/><em>%s</em><br/>',
$setting,
$this->translator->translate('Installation_SystemCheckPhpSetting', array($setting)),
$this->translator->translate('Installation_RestartWebServer')
);
} else {
$status = DiagnosticResult::STATUS_OK;
$comment = $setting;
}
$result->addItem(new DiagnosticResultItem($status, $comment));
}
return array($result);
}
/**
* @return RequiredPhpSetting[]
*/
private function getRequiredSettings()
{
$requiredSettings[] = new RequiredPhpSetting('session.auto_start', 0);
$maxExecutionTime = new RequiredPhpSetting('max_execution_time', 0);
$maxExecutionTime->addRequiredValue(30, '>=');
$maxExecutionTime->setErrorResult(DiagnosticResult::STATUS_WARNING);
$requiredSettings[] = $maxExecutionTime;
if ($this->isPhpVersionAtLeast56() && ! defined("HHVM_VERSION") && !$this->isPhpVersionAtLeast70()) {
// always_populate_raw_post_data must be -1
// removed in PHP 7
$requiredSettings[] = new RequiredPhpSetting('always_populate_raw_post_data', -1);
}
return $requiredSettings;
}
private function isPhpVersionAtLeast56()
{
return version_compare(PHP_VERSION, '5.6', '>=');
}
private function isPhpVersionAtLeast70()
{
return version_compare(PHP_VERSION, '7.0.0-dev', '>=');
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Translation\Translator;
/**
* Check the PHP version.
*/
class PhpVersionCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
global $piwik_minimumPHPVersion;
$actualVersion = PHP_VERSION;
$label = sprintf(
'%s >= %s',
$this->translator->translate('Installation_SystemCheckPhp'),
$piwik_minimumPHPVersion
);
if ($this->isPhpVersionValid($piwik_minimumPHPVersion, $actualVersion)) {
$status = DiagnosticResult::STATUS_OK;
$comment = $actualVersion;
} else {
$status = DiagnosticResult::STATUS_ERROR;
$comment = sprintf(
'%s: %s',
$this->translator->translate('General_Error'),
$this->translator->translate('General_Required', array($label))
);
}
return array(DiagnosticResult::singleResult($label, $status, $comment));
}
private function isPhpVersionValid($requiredVersion, $actualVersion)
{
return version_compare($requiredVersion, $actualVersion) <= 0;
}
}

View File

@ -0,0 +1,77 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Translation\Translator;
/**
* Check the PHP extensions that are not required but recommended.
*/
class RecommendedExtensionsCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckOtherExtensions');
$result = new DiagnosticResult($label);
$loadedExtensions = @get_loaded_extensions();
$loadedExtensions = array_map(function ($extension) {
return strtolower($extension);
}, $loadedExtensions);
foreach ($this->getRecommendedExtensions() as $extension) {
if (! in_array(strtolower($extension), $loadedExtensions)) {
$status = DiagnosticResult::STATUS_WARNING;
$comment = $extension . '<br/>' . $this->getHelpMessage($extension);
} else {
$status = DiagnosticResult::STATUS_OK;
$comment = $extension;
}
$result->addItem(new DiagnosticResultItem($status, $comment));
}
return array($result);
}
/**
* @return string[]
*/
private function getRecommendedExtensions()
{
return array(
'json',
'libxml',
'dom',
'SimpleXML',
);
}
private function getHelpMessage($missingExtension)
{
$messages = array(
'json' => 'Installation_SystemCheckWarnJsonHelp',
'libxml' => 'Installation_SystemCheckWarnLibXmlHelp',
'dom' => 'Installation_SystemCheckWarnDomHelp',
'SimpleXML' => 'Installation_SystemCheckWarnSimpleXMLHelp',
);
return $this->translator->translate($messages[$missingExtension]);
}
}

View File

@ -0,0 +1,77 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Translation\Translator;
/**
* Check the PHP functions that are not required but recommended.
*/
class RecommendedFunctionsCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckOtherFunctions');
$result = new DiagnosticResult($label);
foreach ($this->getRecommendedFunctions() as $function) {
if (! PhpFunctionsCheck::functionExists($function)) {
$status = DiagnosticResult::STATUS_WARNING;
$comment = $function . '<br/>' . $this->getHelpMessage($function);
} else {
$status = DiagnosticResult::STATUS_OK;
$comment = $function;
}
$result->addItem(new DiagnosticResultItem($status, $comment));
}
return array($result);
}
/**
* @return string[]
*/
private function getRecommendedFunctions()
{
return array(
'shell_exec',
'set_time_limit',
'mail',
'parse_ini_file',
'glob',
'gzopen',
'md5_file',
);
}
private function getHelpMessage($function)
{
$messages = array(
'shell_exec' => 'Installation_SystemCheckFunctionHelp',
'set_time_limit' => 'Installation_SystemCheckTimeLimitHelp',
'mail' => 'Installation_SystemCheckMailHelp',
'parse_ini_file' => 'Installation_SystemCheckParseIniFileHelp',
'glob' => 'Installation_SystemCheckGlobHelp',
'gzopen' => 'Installation_SystemCheckZlibHelp',
);
return $this->translator->translate($messages[$function]);
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace Piwik\Plugins\Diagnostics\Diagnostic;
class RequiredPhpSetting
{
/** @var string */
private $setting;
/** @var array */
private $requiredValues;
/** @var string */
private $errorResult = DiagnosticResult::STATUS_ERROR;
/**
* @param string $setting
* @param int $requiredValue
* @param string $operator
*/
public function __construct($setting, $requiredValue, $operator = '=')
{
$this->setting = $setting;
$this->addRequiredValue($requiredValue, $operator);
}
/**
* @param int $requiredValue
* @param string $operator
*
* @return $this
*/
public function addRequiredValue($requiredValue, $operator)
{
if(!is_int($requiredValue)){
throw new \InvalidArgumentException('Required value must be an integer.');
}
$this->requiredValues[] = array(
'requiredValue' => $requiredValue,
'operator' => $operator,
'isValid' => null,
);
return $this;
}
/**
* @param $errorResult
*
* @return $this
*/
public function setErrorResult($errorResult)
{
if ($errorResult !== DiagnosticResult::STATUS_WARNING && $errorResult !== DiagnosticResult::STATUS_ERROR) {
throw new \InvalidArgumentException('Error result must be either DiagnosticResult::STATUS_WARNING or DiagnosticResult::STATUS_ERROR.');
}
$this->errorResult = $errorResult;
return $this;
}
/**
* @return string
*/
public function getErrorResult()
{
return $this->errorResult;
}
/**
* Checks required values against php.ini value.
*
* @return bool
*/
public function check()
{
$currentValue = (int) ini_get($this->setting);
$return = false;
foreach($this->requiredValues as $key => $requiredValue){
$this->requiredValues[$key]['isValid'] = version_compare($currentValue, $requiredValue['requiredValue'], $requiredValue['operator']);
if($this->requiredValues[$key]['isValid']){
$return = true;
}
}
return $return;
}
public function __toString()
{
$checks = array();
foreach($this->requiredValues as $requiredValue){
$checks[] = $requiredValue['operator'] . ' ' . $requiredValue['requiredValue'];
}
return $this->setting . ' ' . implode(' OR ', $checks);
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Config;
use Piwik\SettingsServer;
use Piwik\Translation\Translator;
/**
* Check that the PHP timezone setting is set.
*/
class TimezoneCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('SitesManager_Timezone');
if (SettingsServer::isTimezoneSupportEnabled()) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
}
$comment = sprintf(
'%s<br />%s.',
$this->translator->translate('SitesManager_AdvancedTimezoneSupportNotFound'),
'<a href="http://php.net/manual/en/datetime.installation.php" rel="noreferrer noopener" target="_blank">Timezone PHP documentation</a>'
);
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\Common;
use Piwik\Translation\Translator;
/**
* Check that the tracker is working correctly.
*/
class TrackerCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckTracker');
$trackerStatus = Common::getRequestVar('trackerStatus', 0, 'int');
if ($trackerStatus == 0) {
$status = DiagnosticResult::STATUS_OK;
$comment = '';
} else {
$status = DiagnosticResult::STATUS_WARNING;
$comment = sprintf(
'%s<br />%s<br />%s',
$trackerStatus,
$this->translator->translate('Installation_SystemCheckTrackerHelp'),
$this->translator->translate('Installation_RestartWebServer')
);
}
return array(DiagnosticResult::singleResult($label, $status, $comment));
}
}

View File

@ -0,0 +1,99 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;
use Piwik\DbHelper;
use Piwik\Filechecks;
use Piwik\Translation\Translator;
/**
* Check the permissions for some directories.
*/
class WriteAccessCheck implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
/**
* Path to the temp directory.
* @var string
*/
private $tmpPath;
/**
* @param Translator $translator
* @param string $tmpPath Path to the temp directory.
*/
public function __construct(Translator $translator, $tmpPath)
{
$this->translator = $translator;
$this->tmpPath = $tmpPath;
}
public function execute()
{
$label = $this->translator->translate('Installation_SystemCheckWriteDirs');
$result = new DiagnosticResult($label);
$directories = Filechecks::checkDirectoriesWritable($this->getDirectories());
$error = false;
foreach ($directories as $directory => $isWritable) {
if ($isWritable) {
$status = DiagnosticResult::STATUS_OK;
} else {
$status = DiagnosticResult::STATUS_ERROR;
$error = true;
}
$result->addItem(new DiagnosticResultItem($status, $directory));
}
if ($error) {
$longErrorMessage = $this->translator->translate('Installation_SystemCheckWriteDirsHelp');
$longErrorMessage .= '<ul>';
foreach ($directories as $directory => $isWritable) {
if (! $isWritable) {
$longErrorMessage .= sprintf('<li><pre>chmod a+w %s</pre></li>', $directory);
}
}
$longErrorMessage .= '</ul>';
$result->setLongErrorMessage($longErrorMessage);
}
return array($result);
}
/**
* @return string[]
*/
private function getDirectories()
{
$directoriesToCheck = array(
$this->tmpPath,
$this->tmpPath . '/assets/',
$this->tmpPath . '/cache/',
$this->tmpPath . '/climulti/',
$this->tmpPath . '/latest/',
$this->tmpPath . '/logs/',
$this->tmpPath . '/sessions/',
$this->tmpPath . '/tcpdf/',
$this->tmpPath . '/templates_c/',
);
if (! DbHelper::isInstalled()) {
// at install, need /config to be writable (so we can create config.ini.php)
$directoriesToCheck[] = '/config/';
}
return $directoriesToCheck;
}
}