translator = $translator;
}
public function execute()
{
$isPiwikInstalling = !Config::getInstance()->existsLocalConfig();
if ($isPiwikInstalling) {
// Skip the diagnostic if Piwik is being installed
return array();
}
$result = new DiagnosticResult($this->translator->translate('Installation_DatabaseAbilities'));
$result->addItem($this->checkUtf8mb4Charset());
if (Config::getInstance()->General['enable_load_data_infile']) {
$result->addItem($this->checkLoadDataInfile());
}
$result->addItem($this->checkTemporaryTables());
$result->addItem($this->checkTransactionLevel());
return [$result];
}
protected function checkUtf8mb4Charset()
{
$dbSettings = new Db\Settings();
$charset = $dbSettings->getUsedCharset();
if (DbHelper::getDefaultCharset() === 'utf8mb4' && $charset === 'utf8mb4') {
return new DiagnosticResultItem(DiagnosticResult::STATUS_OK, 'UTF8mb4 charset');
}
if (DbHelper::getDefaultCharset() === 'utf8mb4') {
return new DiagnosticResultItem(
DiagnosticResult::STATUS_WARNING, 'UTF8mb4 charset
' .
$this->translator->translate('Diagnostics_DatabaseUtf8mb4CharsetAvailableButNotUsed', '' . PIWIK_INCLUDE_PATH . '/console core:convert-to-utf8mb4
') .
'
' .
$this->translator->translate('Diagnostics_DatabaseUtf8Requirement', ['�', '', '']) .
'
'
);
}
return new DiagnosticResultItem(
DiagnosticResult::STATUS_WARNING, 'UTF8mb4 charset
' .
$this->translator->translate('Diagnostics_DatabaseUtf8mb4CharsetRecommended') .
'
' .
$this->translator->translate('Diagnostics_DatabaseUtf8Requirement', ['�', '', '']) .
'
'
);
}
protected function checkLoadDataInfile()
{
$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", "
", $ex->getMessage());
}
// delete the temporary rows that were created
Db::exec("DELETE FROM `$optionTable` WHERE option_name IN ('" . implode("','", $testOptionNames) . "')");
if ($loadDataInfile) {
return new DiagnosticResultItem(DiagnosticResult::STATUS_OK, 'LOAD DATA INFILE');
}
$comment = sprintf(
'LOAD DATA INFILE
%s
%s',
$this->translator->translate('Installation_LoadDataInfileUnavailableHelp', array(
'LOAD DATA INFILE',
'FILE',
)),
$this->translator->translate('Installation_LoadDataInfileRecommended')
);
if ($errorMessage) {
$comment .= sprintf(
'
%s: %s
%s',
$this->translator->translate('General_Error'),
$errorMessage,
'Troubleshooting: FAQ on matomo.org'
);
}
return new DiagnosticResultItem(DiagnosticResult::STATUS_WARNING, $comment);
}
protected function checkTemporaryTables()
{
$status = DiagnosticResult::STATUS_OK;
$comment = 'CREATE TEMPORARY TABLES';
try {
// create a temporary table
Db::exec("CREATE TEMPORARY TABLE `piwik_test_table_temp` (
id INT,
val VARCHAR(5) NULL,
PRIMARY KEY (id)
)");
// insert an entry into the new temporary table
Db::exec('INSERT INTO `piwik_test_table_temp` (`id`, `val`) VALUES ("1", "val1");');
for ($i=0; $i < 5; $i++) {
// try reading the entry a few times to ensure it doesn't fail, which might be possible when using load balanced databases
$result = Db::fetchRow('SELECT * FROM `piwik_test_table_temp` WHERE `id` = 1');
if (empty($result)) {
throw new \Exception('read failed');
}
}
} catch (\Exception $e) {
$status = DiagnosticResult::STATUS_ERROR;
$comment .= '
' . $this->translator->translate('Diagnostics_MysqlTemporaryTablesWarning');
$comment .= '
Troubleshooting: FAQ on matomo.org';
}
return new DiagnosticResultItem($status, $comment);
}
protected function checkTransactionLevel()
{
$status = DiagnosticResult::STATUS_OK;
$comment = 'Changing transaction isolation level';
$level = new Db\TransactionLevel(Db::getReader());
if (!$level->setUncommitted()) {
$status = DiagnosticResult::STATUS_WARNING;
$comment .= '
' . $this->translator->translate('Diagnostics_MysqlTransactionLevel');
} else {
$level->restorePreviousStatus();
}
return new DiagnosticResultItem($status, $comment);
}
}