</header>
{foreach from=$objectTypes item=objectType}
+ {assign var=_allowRebuild value=true}
+ {if !$convertEncoding && $objectType->objectType != 'com.woltlab.wcf.databaseConvertEncoding'}
+ {assign var=_allowRebuild value=false}
+ {/if}
+
<dl class="wide">
<dd>
- <a class="button small" id="rebuildData{@$objectType->objectTypeID}">{lang}wcf.acp.rebuildData.{@$objectType->objectType}{/lang}</a>
+ <a class="button small{if !$_allowRebuild} disabled{/if}" id="rebuildData{@$objectType->objectTypeID}">{lang}wcf.acp.rebuildData.{@$objectType->objectType}{/lang}</a>
<small>{lang}wcf.acp.rebuildData.{@$objectType->objectType}.description{/lang}</small>
- <script data-relocate="true">
- $(function() {
- $('#rebuildData{@$objectType->objectTypeID}').click(function () {
- new WCF.ACP.Worker('cache', '{@$objectType->className|encodeJS}', '{lang}wcf.acp.rebuildData.{@$objectType->objectType}{/lang}');
+ {if $_allowRebuild}
+ <script data-relocate="true">
+ $(function() {
+ $('#rebuildData{@$objectType->objectTypeID}').click(function () {
+ new WCF.ACP.Worker('cache', '{@$objectType->className|encodeJS}', '{lang}wcf.acp.rebuildData.{@$objectType->objectType}{/lang}');
+ });
});
- });
- </script>
+ </script>
+ {/if}
</dd>
</dl>
{/foreach}
*/
public $activeMenuItem = 'wcf.acp.menu.link.maintenance.rebuildData';
+ /**
+ * disallow any rebuild actions unless `wcfN_user_storage` uses `utf8mb4`
+ * @var boolean
+ */
+ public $convertEncoding = false;
+
/**
* @inheritDoc
*/
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;
+ }
+ }
+ }
}
/**
parent::assignVariables();
WCF::getTPL()->assign([
+ 'convertEncoding' => $this->convertEncoding,
'objectTypes' => $this->objectTypes,
'showInnoDBWarning' => $this->showInnoDBWarning
]);