diff options
Diffstat (limited to 'plugins/CoreUpdater')
-rw-r--r-- | plugins/CoreUpdater/Commands/ConvertToUtf8mb4.php | 141 | ||||
-rw-r--r-- | plugins/CoreUpdater/SystemSettings.php | 26 | ||||
-rw-r--r-- | plugins/CoreUpdater/Tasks.php | 28 | ||||
-rw-r--r-- | plugins/CoreUpdater/lang/en.json | 5 |
4 files changed, 199 insertions, 1 deletions
diff --git a/plugins/CoreUpdater/Commands/ConvertToUtf8mb4.php b/plugins/CoreUpdater/Commands/ConvertToUtf8mb4.php new file mode 100644 index 0000000000..141b71470c --- /dev/null +++ b/plugins/CoreUpdater/Commands/ConvertToUtf8mb4.php @@ -0,0 +1,141 @@ +<?php +/** + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\CoreUpdater\Commands; + +use Piwik\Config; +use Piwik\Db; +use Piwik\DbHelper; +use Piwik\Piwik; +use Piwik\Plugin\ConsoleCommand; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; + +/** + * @package CoreUpdater + */ +class ConvertToUtf8mb4 extends ConsoleCommand +{ + protected function configure() + { + $this->setName('core:convert-to-utf8mb4'); + + $this->setDescription('Converts the database to utf8mb4'); + + $this->addOption('show', null, InputOption::VALUE_NONE, Piwik::translate('Show all commands / queries only.')); + $this->addOption('yes', null, InputOption::VALUE_NONE, Piwik::translate('CoreUpdater_ConsoleParameterDescription')); + $this->addOption('keep-tracking', null, InputOption::VALUE_NONE, 'Do not disable tracking while conversion is running'); + } + + public function isEnabled() + { + $dbSettings = new Db\Settings(); + $charset = $dbSettings->getUsedCharset(); + + return $charset !== 'utf8mb4'; + } + + /** + * Execute command like: ./console core:convert-to-utf8mb4 --yes + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $yes = $input->getOption('yes'); + $keepTracking = $input->getOption('keep-tracking'); + $show = $input->getOption('show'); + + $queries = DbHelper::getUtf8mb4ConversionQueries(); + + if ($show) { + $this->showCommands($queries, $keepTracking, $output); + return; + } + + $output->writeln("This command will convert all Matomo database tables to utf8mb4.\n"); + + if (DbHelper::getDefaultCharset() !== 'utf8mb4') { + $this->writeSuccessMessage($output, array('Your database does not support utf8mb4')); + return; + } + + if (!$keepTracking) { + $output->writeln("Tracking will be disabled during this process.\n"); + } + + $output->writeln('If you want to see what this command is going to do use the --show option.'); + + if (!$yes) { + $yes = $this->askForUpdateConfirmation($input, $output); + } + + if ($yes) { + + if (!$keepTracking) { + $output->writeln("\n" . Piwik::translate('Disabling Matomo Tracking')); + $config = Config::getInstance(); + $config->Tracker['record_statistics'] = '0'; + $config->forceSave(); + } + + $output->writeln("\n" . Piwik::translate('CoreUpdater_ConsoleStartingDbUpgrade')); + + foreach ($queries as $query) { + $output->write("\n" . 'Executing ' . $query . '... '); + Db::get()->exec($query); + $output->write(' done.'); + } + + $output->writeln("\n" . 'Updating used database charset in config.ini.php.'); + $config = Config::getInstance(); + $config->database['charset'] = 'utf8mb4'; + + if (!$keepTracking) { + $output->writeln("\n" . Piwik::translate('Enabling Matomo Tracking')); + $config->Tracker['record_statistics'] = '1'; + } + + $config->forceSave(); + + $this->writeSuccessMessage($output, array('Conversion to utf8mb4 successful.')); + + } else { + $this->writeSuccessMessage($output, array('Database conversion skipped.')); + } + } + + protected function showCommands($queries, $keepTracking, OutputInterface $output) + { + $output->writeln("To manually convert all Matomo database tables to utf8mb4 follow these steps."); + if (!$keepTracking) { + $output->writeln(''); + $output->writeln('** Disable Matomo Tracking with this command: **'); + $output->writeln('./console config:set --section=Tracker --key=record_statistics --value=0'); + } + $output->writeln(''); + $output->writeln('** Execute the following database queries: **'); + $output->writeln(implode("\n", $queries)); + $output->writeln(''); + $output->writeln('** Change configured database charset to utf8mb4 with this command: **'); + $output->writeln('./console config:set --section=database --key=charset --value=utf8mb4'); + if (!$keepTracking) { + $output->writeln(''); + $output->writeln('** Enable Matomo Tracking again with this command: **'); + $output->writeln('./console config:set --section=Tracker --key=record_statistics --value=1'); + } + } + + private function askForUpdateConfirmation(InputInterface $input, OutputInterface $output) + { + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('<comment>Execute updates? (y/N) </comment>', false); + + return $helper->ask($input, $output, $question); + } +} diff --git a/plugins/CoreUpdater/SystemSettings.php b/plugins/CoreUpdater/SystemSettings.php index 8bf13a03b9..e8de1fb493 100644 --- a/plugins/CoreUpdater/SystemSettings.php +++ b/plugins/CoreUpdater/SystemSettings.php @@ -8,6 +8,8 @@ namespace Piwik\Plugins\CoreUpdater; +use Piwik\Db\Settings; +use Piwik\DbHelper; use Piwik\Piwik; use Piwik\Plugin\ReleaseChannels; use Piwik\Plugins\CoreAdminHome\Controller as CoreAdminController; @@ -31,6 +33,9 @@ class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings /** @var Setting */ public $sendPluginUpdateEmail; + /** @var Setting */ + public $updateToUtf8mb4; + /** * @var ReleaseChannels */ @@ -54,6 +59,12 @@ class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings $isWritable = $isWritable && PluginUpdateCommunication::canBeEnabled(); $this->sendPluginUpdateEmail = $this->createSendPluginUpdateEmail(); $this->sendPluginUpdateEmail->setIsWritableByCurrentUser($isWritable); + + $isWritable = Piwik::hasUserSuperUserAccess() && CoreAdminController::isGeneralSettingsAdminEnabled(); + $dbSettings = new Settings(); + if ($isWritable && $dbSettings->getUsedCharset() !== 'utf8mb4' && DbHelper::getDefaultCharset() === 'utf8mb4') { + $this->updateToUtf8mb4 = $this->createUpdateToUtf8mb4(); + } } private function createReleaseChannel() @@ -104,4 +115,19 @@ class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings }); } + private function createUpdateToUtf8mb4() + { + return $this->makeSetting('update_to_utf8mb4', $default = false, FieldConfig::TYPE_BOOL, function (FieldConfig $field) { + $field->introduction = Piwik::translate('CoreUpdater_ConvertToUtf8mb4'); + $field->title = Piwik::translate('CoreUpdater_TriggerDatabaseConversion'); + $field->uiControl = FieldConfig::UI_CONTROL_CHECKBOX; + $field->inlineHelp = Piwik::translate('CoreUpdater_Utf8mb4ConversionHelp', [ + '�', + '<code>' . PIWIK_INCLUDE_PATH . '/console core:convert-to-utf8mb4</code>', + '<a href="https://matomo.org/faq/how-to-update/how-to-convert-the-database-to-utf8mb4-charset/" rel="noreferrer noopener" target="_blank">', + '</a>' + ]); + }); + } + } diff --git a/plugins/CoreUpdater/Tasks.php b/plugins/CoreUpdater/Tasks.php index 7998a83925..f3ecae955d 100644 --- a/plugins/CoreUpdater/Tasks.php +++ b/plugins/CoreUpdater/Tasks.php @@ -8,11 +8,23 @@ */ namespace Piwik\Plugins\CoreUpdater; +use Piwik\Config; +use Piwik\Container\StaticContainer; +use Piwik\Db; +use Piwik\DbHelper; + class Tasks extends \Piwik\Plugin\Tasks { public function schedule() { $this->daily('sendNotificationIfUpdateAvailable', null, self::LOWEST_PRIORITY); + + $dbSettings = new \Piwik\Db\Settings(); + $settings = StaticContainer::get('Piwik\Plugins\CoreUpdater\SystemSettings'); + + if ($dbSettings->getUsedCharset() !== 'utf8mb4' && DbHelper::getDefaultCharset() === 'utf8mb4' && $settings->updateToUtf8mb4->getValue()) { + $this->daily('convertToUtf8mb4', null, self::HIGHEST_PRIORITY); + } } public function sendNotificationIfUpdateAvailable() @@ -22,4 +34,20 @@ class Tasks extends \Piwik\Plugin\Tasks $coreUpdateCommunication->sendNotificationIfUpdateAvailable(); } } + + public function convertToUtf8mb4() + { + $queries = DbHelper::getUtf8mb4ConversionQueries(); + + foreach ($queries as $query) { + Db::get()->exec($query); + } + + $config = Config::getInstance(); + $config->database['charset'] = 'utf8mb4'; + $config->forceSave(); + + $settings = StaticContainer::get('Piwik\Plugins\CoreUpdater\SystemSettings'); + $settings->updateToUtf8mb4->setValue(false); + } }
\ No newline at end of file diff --git a/plugins/CoreUpdater/lang/en.json b/plugins/CoreUpdater/lang/en.json index bc703116b8..728706f1c4 100644 --- a/plugins/CoreUpdater/lang/en.json +++ b/plugins/CoreUpdater/lang/en.json @@ -91,6 +91,9 @@ "YouMustDownloadPackageOrFixPermissions": "Matomo is unable to overwrite your current installation. You can either fix the directory\/file permissions, or download the package and install version %s manually:", "YourDatabaseIsOutOfDate": "Your Matomo database is out-of-date, and must be upgraded before you can continue.", "ViewVersionChangelog": "View the changelog for this version:", - "ReceiveEmailBecauseIsSuperUser": "You receive this email because you are a Super User on the Matomo at: %s" + "ReceiveEmailBecauseIsSuperUser": "You receive this email because you are a Super User on the Matomo at: %s", + "ConvertToUtf8mb4": "Convert database to UTF8mb4 charset", + "TriggerDatabaseConversion": "Trigger database conversion in background", + "Utf8mb4ConversionHelp": "Your database is currently not using utf8mb4 charset. This makes it impossible to store 4-byte characters, such as emojis, less common characters of asian languages, various historic scripts or mathematical symbols. Those are currently replaced with %1$s.<br /><br />Your database supports the utf8mb4 charset and it would be possible to convert it.<br /><br />If you are able to run console commands we recommend using this command: %2$s<br /><br />Alternatively you can enable the conversion here. It will then be triggered automatically as a scheduled task in the background.<br /><br />Attention: Converting the database might take up to a couple of hours depending on the database size. As tracking might not work during this process, we do not recommend to use the trigger for bigger instances.<br /><br />You can find more information about this topic in this %3$sFAQ%4$s." } } |