update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit 47263617c5
48 changed files with 418860 additions and 226988 deletions

View file

@ -0,0 +1,82 @@
<?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\Commands;
use Piwik\Container\StaticContainer;
use Piwik\Piwik;
use Piwik\Plugin\ConsoleCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
/**
* Diagnostic command that analyzes a single archive table. Displays information like # of segment archives,
* # invalidated archives, # temporary archives, etc.
*/
class AnalyzeArchiveTable extends ConsoleCommand
{
protected function configure()
{
$this->setName('diagnostics:analyze-archive-table');
$this->setDescription('Analyze an archive table and display human readable information about what is stored. '
. 'This command can be used to diagnose issues like bloated archive tables.');
$this->addArgument('table-date', InputArgument::REQUIRED, "The table's associated date, eg, 2015_01 or 2015_02");
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$tableDate = $input->getArgument('table-date');
$output->writeln("<comment>Statistics for the archive_numeric_$tableDate and archive_blob_$tableDate tables:</comment>");
$output->writeln("");
$archiveTableDao = StaticContainer::get('Piwik\DataAccess\ArchiveTableDao');
$rows = $archiveTableDao->getArchiveTableAnalysis($tableDate);
// process labels
$periodIdsToLabels = array_flip(Piwik::$idPeriods);
foreach ($rows as $key => &$row) {
list($idSite, $date1, $date2, $period) = explode('.', $key);
$periodLabel = isset($periodIdsToLabels[$period]) ? $periodIdsToLabels[$period] : "Unknown Period ($period)";
$row['label'] = $periodLabel . "[" . $date1 . " - " . $date2 . "] idSite = " . $idSite;
}
$headers = array('Group', '# Archives', '# Invalidated', '# Temporary', '# Error', '# Segment',
'# Numeric Rows', '# Blob Rows');
// display all rows
$table = new Table($output);
$table->setHeaders($headers)->setRows($rows);
$table->render();
// display summary
$totalArchives = 0;
$totalInvalidated = 0;
$totalTemporary = 0;
$totalError = 0;
$totalSegment = 0;
foreach ($rows as $row) {
$totalArchives += $row['count_archives'];
$totalInvalidated += $row['count_invalidated_archives'];
$totalTemporary += $row['count_temporary_archives'];
$totalError += $row['count_error_archives'];
$totalSegment += $row['count_segment_archives'];
}
$output->writeln("");
$output->writeln("Total # Archives: <comment>$totalArchives</comment>");
$output->writeln("Total # Invalidated Archives: <comment>$totalInvalidated</comment>");
$output->writeln("Total # Temporary Archives: <comment>$totalTemporary</comment>");
$output->writeln("Total # Error Archives: <comment>$totalError</comment>");
$output->writeln("Total # Segment Archives: <comment>$totalSegment</comment>");
$output->writeln("");
}
}

View file

@ -0,0 +1,89 @@
<?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\Commands;
use Piwik\Container\StaticContainer;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult;
use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResultItem;
use Piwik\Plugins\Diagnostics\DiagnosticService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Run the diagnostics.
*/
class Run extends ConsoleCommand
{
protected function configure()
{
$this->setName('diagnostics:run')
->setDescription('Run diagnostics to check that Piwik is installed and runs correctly')
->addOption('all', null, InputOption::VALUE_NONE, 'Show all diagnostics, including those that passed with success');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// Replace this with dependency injection once available
/** @var DiagnosticService $diagnosticService */
$diagnosticService = StaticContainer::get('Piwik\Plugins\Diagnostics\DiagnosticService');
$showAll = $input->getOption('all');
$report = $diagnosticService->runDiagnostics();
foreach ($report->getAllResults() as $result) {
$items = $result->getItems();
if (! $showAll && ($result->getStatus() === DiagnosticResult::STATUS_OK)) {
continue;
}
if (count($items) === 1) {
$output->writeln($result->getLabel() . ': ' . $this->formatItem($items[0]), OutputInterface::OUTPUT_PLAIN);
continue;
}
$output->writeln($result->getLabel() . ':');
foreach ($items as $item) {
$output->writeln("\t- " . $this->formatItem($item), OutputInterface::OUTPUT_PLAIN);
}
}
if ($report->hasWarnings()) {
$output->writeln(sprintf('<comment>%d warnings detected</comment>', $report->getWarningCount()));
}
if ($report->hasErrors()) {
$output->writeln(sprintf('<error>%d errors detected</error>', $report->getErrorCount()));
return 1;
}
return 0;
}
private function formatItem(DiagnosticResultItem $item)
{
if ($item->getStatus() === DiagnosticResult::STATUS_ERROR) {
$tag = 'error';
} elseif ($item->getStatus() === DiagnosticResult::STATUS_WARNING) {
$tag = 'comment';
} else {
$tag = 'info';
}
return sprintf(
'<%s>%s %s</%s>',
$tag,
strtoupper($item->getStatus()),
preg_replace('/\<br\s*\/?\>/i', "\n", $item->getComment()),
$tag
);
}
}

View file

@ -0,0 +1,193 @@
<?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;
use Piwik\Development;
use Piwik\Ini\IniReader;
use Piwik\Application\Kernel\GlobalSettingsProvider;
use Piwik\Settings as PiwikSettings;
use Piwik\Plugin\Settings as PluginSettings;
/**
* A diagnostic report contains all the results of all the diagnostics.
*/
class ConfigReader
{
/**
* @var GlobalSettingsProvider
*/
private $settings;
/**
* @var IniReader
*/
private $iniReader;
public function __construct(GlobalSettingsProvider $settings, IniReader $iniReader)
{
$this->settings = $settings;
$this->iniReader = $iniReader;
}
public function getConfigValuesFromFiles()
{
$ini = $this->settings->getIniFileChain();
$descriptions = $this->iniReader->readComments($this->settings->getPathGlobal());
$copy = array();
foreach ($ini->getAll() as $category => $values) {
if ($this->shouldSkipCategory($category)) {
continue;
}
$local = $this->getFromLocalConfig($category);
if (empty($local)) {
$local = array();
}
$global = $this->getFromGlobalConfig($category);
if (empty($global)) {
$global = array();
}
$copy[$category] = array();
foreach ($values as $key => $value) {
$newValue = $value;
if ($this->isKeyAPassword($key)) {
$newValue = $this->getMaskedPassword();
}
$defaultValue = null;
if (array_key_exists($key, $global)) {
$defaultValue = $global[$key];
}
$description = '';
if (!empty($descriptions[$category][$key])) {
$description = trim($descriptions[$category][$key]);
}
$copy[$category][$key] = array(
'value' => $newValue,
'description' => $description,
'isCustomValue' => array_key_exists($key, $local),
'defaultValue' => $defaultValue,
);
}
}
return $copy;
}
private function shouldSkipCategory($category)
{
$category = strtolower($category);
if ($category === 'database') {
return true;
}
$developmentOnlySections = array('database_tests', 'tests', 'debugtests');
return !Development::isEnabled() && in_array($category, $developmentOnlySections);
}
public function getFromGlobalConfig($name)
{
return $this->settings->getIniFileChain()->getFrom($this->settings->getPathGlobal(), $name);
}
public function getFromLocalConfig($name)
{
return $this->settings->getIniFileChain()->getFrom($this->settings->getPathLocal(), $name);
}
private function getMaskedPassword()
{
return '******';
}
private function isKeyAPassword($key)
{
$key = strtolower($key);
$passwordFields = array(
'password', 'secret', 'apikey', 'privatekey', 'admin_pass'
);
foreach ($passwordFields as $value) {
if (strpos($key, $value) !== false) {
return true;
}
}
if ($key === 'salt') {
return true;
}
return false;
}
/**
* Adds config values that can be used to overwrite a plugin system setting and adds a description + default value
* for already existing configured config values that overwrite a plugin system setting.
*
* @param array $configValues
* @param \Piwik\Plugin\Settings[] $pluginSettings
* @return array
*/
public function addConfigValuesFromPluginSettings($configValues, $pluginSettings)
{
foreach ($pluginSettings as $pluginSetting) {
$pluginName = $pluginSetting->getPluginName();
if (empty($pluginName)) {
continue;
}
$configs[$pluginName] = array();
foreach ($pluginSetting->getSettings() as $setting) {
if ($setting instanceof PiwikSettings\SystemSetting && $setting->isReadableByCurrentUser()) {
$name = $setting->getName();
$description = '';
if (!empty($setting->description)) {
$description .= $setting->description . ' ';
}
if (!empty($setting->inlineHelp)) {
$description .= $setting->inlineHelp;
}
if (isset($configValues[$pluginName][$name])) {
$configValues[$pluginName][$name]['defaultValue'] = $setting->defaultValue;
$configValues[$pluginName][$name]['description'] = trim($description);
if ($setting->uiControlType === PluginSettings::CONTROL_PASSWORD) {
$value = $configValues[$pluginName][$name]['value'];
$configValues[$pluginName][$name]['value'] = $this->getMaskedPassword();
}
} else {
$defaultValue = $setting->getValue();
$configValues[$pluginName][$name] = array(
'value' => null,
'description' => trim($description),
'isCustomValue' => false,
'defaultValue' => $defaultValue
);
}
}
}
if (empty($configValues[$pluginName])) {
unset($configValues[$pluginName]);
}
}
return $configValues;
}
}

View file

@ -0,0 +1,66 @@
<?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;
use Piwik\Config;
use Piwik\Piwik;
use Piwik\View;
use Piwik\Settings;
class Controller extends \Piwik\Plugin\ControllerAdmin
{
/**
* @var ConfigReader
*/
private $configReader;
public function __construct(ConfigReader $configReader)
{
$this->configReader = $configReader;
parent::__construct();
}
public function configfile()
{
Piwik::checkUserHasSuperUserAccess();
$allSettings = Settings\Manager::getAllPluginSettings();
$configValues = $this->configReader->getConfigValuesFromFiles();
$configValues = $this->configReader->addConfigValuesFromPluginSettings($configValues, $allSettings);
$configValues = $this->sortConfigValues($configValues);
return $this->renderTemplate('configfile', array(
'allConfigValues' => $configValues
));
}
private function sortConfigValues($configValues)
{
// we sort by sections alphabetically
uksort($configValues, function ($section1, $section2) {
return strcasecmp($section1, $section2);
});
foreach ($configValues as $category => &$settings) {
// we sort keys alphabetically but list the ones that are changed first
uksort($settings, function ($setting1, $setting2) use ($settings) {
if ($settings[$setting1]['isCustomValue'] && !$settings[$setting2]['isCustomValue']) {
return -1;
} elseif (!$settings[$setting1]['isCustomValue'] && $settings[$setting2]['isCustomValue']) {
return 1;
}
return strcasecmp($setting1, $setting2);
});
}
return $configValues;
}
}

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,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,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,56 @@
<?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\Filechecks;
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');
$messages = Filechecks::getFileIntegrityInformation();
$ok = array_shift($messages);
if (empty($messages)) {
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK));
}
if ($ok) {
$status = DiagnosticResult::STATUS_WARNING;
return array(DiagnosticResult::singleResult($label, $status, $messages[0]));
}
$comment = $this->translator->translate('General_FileIntegrityWarningExplanation');
// 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,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" href="?module=Proxy&action=redirect&url=http://piwik.org/faq/troubleshooting/%23faq_194">FAQ on piwik.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,80 @@
<?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_SystemCheckPageSpeedWarn', 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;
}
$headers = $page['headers'];
return isset($headers['X-Mod-Pagespeed']) || isset($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,111 @@
<?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',
'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',
'gzcompress' => 'Installation_SystemCheckGzcompressHelp',
'gzuncompress' => 'Installation_SystemCheckGzuncompressHelp',
'pack' => 'Installation_SystemCheckPackHelp',
);
return $this->translator->translate($messages[$missingFunction]);
}
}

View file

@ -0,0 +1,86 @@
<?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) {
list($settingName, $requiredValue) = explode('=', $setting);
$currentValue = (int) ini_get($settingName);
if ($currentValue != $requiredValue) {
$status = DiagnosticResult::STATUS_ERROR;
$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 string[]
*/
private function getRequiredSettings()
{
$requiredSettings = array(
// setting = required value
// Note: value must be an integer only
'session.auto_start=0',
);
if ($this->isPhpVersionAtLeast56() && ! defined("HHVM_VERSION") && !$this->isPhpVersionAtLeast70()) {
// always_populate_raw_post_data must be -1
// removed in PHP 7
$requiredSettings[] = '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;
}
}

Some files were not shown because too many files have changed in this diff Show more