diff --git a/typo3/sysext/install/Classes/Updates/BackendUserConfigurationUpdate.php b/typo3/sysext/install/Classes/Updates/BackendUserConfigurationUpdate.php new file mode 100644 index 000000000000..4a368cd4c324 --- /dev/null +++ b/typo3/sysext/install/Classes/Updates/BackendUserConfigurationUpdate.php @@ -0,0 +1,141 @@ +getAffectedBackendUsers() as $backendUser) { + $userConfig = $this->unserializeUserConfig($backendUser['uc']); + + array_walk_recursive($userConfig, function (&$item) use (&$needsExecution) { + if ($item instanceof \stdClass) { + $needsExecution = true; + } + }); + + if ($needsExecution) { + break; + } + } + + return $needsExecution; + } + + /** + * @return string[] All new fields and tables must exist + */ + public function getPrerequisites(): array + { + return [ + DatabaseUpdatedPrerequisite::class + ]; + } + + /** + * Performs the database update for be_users + * + * @return bool + */ + public function executeUpdate(): bool + { + foreach ($this->getAffectedBackendUsers() as $backendUser) { + $userConfig = $this->unserializeUserConfig($backendUser['uc']); + array_walk_recursive($userConfig, function (&$item) { + if ($item instanceof \stdClass) { + $item = json_decode(json_encode($item), true); + } + }); + + $this->updateBackendUser($backendUser['uid'], $userConfig); + } + + return true; + } + + private function unserializeUserConfig(string $userConfig) + { + return unserialize($userConfig, ['allowed_classes' => ['stdClass']]); + } + + private function getAffectedBackendUsers(): iterable + { + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) + ->getQueryBuilderForTable('be_users'); + $queryBuilder->getRestrictions()->removeAll(); + $statement = $queryBuilder + ->select('uid', 'uc') + ->from('be_users') + ->where( + $queryBuilder->expr()->like( + 'uc', + $queryBuilder->createNamedParameter( + '%"stdClass"%' + ) + ) + ); + + return $statement->execute(); + } + + private function updateBackendUser(int $userId, array $userConfig): void + { + $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users'); + $connection->update('be_users', ['uc' => serialize($userConfig)], ['uid' => $userId]); + } +} diff --git a/typo3/sysext/install/ext_localconf.php b/typo3/sysext/install/ext_localconf.php index 90162edfb660..f0afb737bb0a 100644 --- a/typo3/sysext/install/ext_localconf.php +++ b/typo3/sysext/install/ext_localconf.php @@ -68,6 +68,8 @@ = \TYPO3\CMS\Install\Updates\PopulatePageSlugs::class; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['argon2iPasswordHashes'] = \TYPO3\CMS\Install\Updates\Argon2iPasswordHashes::class; +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['backendUsersConfiguration'] + = \TYPO3\CMS\Install\Updates\BackendUserConfigurationUpdate::class; $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class); $icons = [