From a4fa35db6048f78403177ae5bea3a99dd6323c01 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sat, 19 Nov 2016 21:07:36 +0100 Subject: [PATCH] Disallow rebuilding data before encoding conversion --- .../files/acp/templates/rebuildData.tpl | 21 ++++++++++----- .../lib/acp/page/RebuildDataPage.class.php | 26 +++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/wcfsetup/install/files/acp/templates/rebuildData.tpl b/wcfsetup/install/files/acp/templates/rebuildData.tpl index 9988c47e0d..fc50f88e75 100644 --- a/wcfsetup/install/files/acp/templates/rebuildData.tpl +++ b/wcfsetup/install/files/acp/templates/rebuildData.tpl @@ -31,18 +31,25 @@ {foreach from=$objectTypes item=objectType} + {assign var=_allowRebuild value=true} + {if !$convertEncoding && $objectType->objectType != 'com.woltlab.wcf.databaseConvertEncoding'} + {assign var=_allowRebuild value=false} + {/if} +
- {lang}wcf.acp.rebuildData.{@$objectType->objectType}{/lang} + {lang}wcf.acp.rebuildData.{@$objectType->objectType}{/lang} {lang}wcf.acp.rebuildData.{@$objectType->objectType}.description{/lang} - + + {/if}
{/foreach} diff --git a/wcfsetup/install/files/lib/acp/page/RebuildDataPage.class.php b/wcfsetup/install/files/lib/acp/page/RebuildDataPage.class.php index c15fc4311d..7bcbb888fe 100644 --- a/wcfsetup/install/files/lib/acp/page/RebuildDataPage.class.php +++ b/wcfsetup/install/files/lib/acp/page/RebuildDataPage.class.php @@ -18,6 +18,12 @@ class RebuildDataPage extends AbstractPage { */ public $activeMenuItem = 'wcf.acp.menu.link.maintenance.rebuildData'; + /** + * disallow any rebuild actions unless `wcfN_user_storage` uses `utf8mb4` + * @var boolean + */ + public $convertEncoding = false; + /** * @inheritDoc */ @@ -66,6 +72,25 @@ class RebuildDataPage extends AbstractPage { if ($row && $row['Value'] == 1) { $this->showInnoDBWarning = true; } + + // We're disallowing rebuilding any other data unless the + // database encoding has been converted to utf8mb4. The + // user_storage table is used as a reference, as it is the + // last WCF table that holds a varchar column. + // + // Querying the columns for each table to reliably detect + // the need of an encoding conversion isn't an option, as + // it turns out to be super slow to retrieve this data. + $sql = "SHOW FULL COLUMNS FROM wcf".WCF_N."_user_storage"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute(); + while ($row = $statement->fetchArray()) { + if ($row['Field'] === 'field') { + if (preg_match('~^utf8mb4~', $row['Collation'])) { + $this->convertEncoding = true; + } + } + } } /** @@ -75,6 +100,7 @@ class RebuildDataPage extends AbstractPage { parent::assignVariables(); WCF::getTPL()->assign([ + 'convertEncoding' => $this->convertEncoding, 'objectTypes' => $this->objectTypes, 'showInnoDBWarning' => $this->showInnoDBWarning ]); -- 2.20.1