hasRecordsToMigrate(); } public function executeUpdate(): bool { $connection = $this->connectionPool->getConnectionForTable('be_users'); $hasFailures = false; foreach ($this->getRecordsToMigrate() as $record) { try { $uc = @unserialize($record['uc'], ['allowed_classes' => false]); if (!is_array($uc)) { continue; } $userSettings = $this->userSettingsFactory->createFromUc($uc); $connection->update( 'be_users', [ // The array must be passed directly to prevent double JSON encoding. // See: https://review.typo3.org/c/Packages/TYPO3.CMS/+/89293 'user_settings' => $userSettings->toArray(), ], ['uid' => (int)$record['uid']], [ // @todo This behavior cannot be modified yet; the array value must be passed directly // until https://review.typo3.org/c/Packages/TYPO3.CMS/+/89293 is merged, // otherwise the value will be JSON-encoded twice. 'user_settings' => Type::getType(Types::JSON), ], ); } catch (\Throwable) { $hasFailures = true; } } return !$hasFailures; } private function hasRecordsToMigrate(): bool { $queryBuilder = $this->connectionPool->getQueryBuilderForTable('be_users'); return (bool)$queryBuilder ->count('uid') ->from('be_users') ->where( $queryBuilder->expr()->isNotNull('uc'), $queryBuilder->expr()->neq('uc', $queryBuilder->createNamedParameter('')), $queryBuilder->expr()->isNull('user_settings') ) ->executeQuery() ->fetchOne(); } private function getRecordsToMigrate(): array { $queryBuilder = $this->connectionPool->getQueryBuilderForTable('be_users'); return $queryBuilder ->select('uid', 'uc') ->from('be_users') ->where( $queryBuilder->expr()->isNotNull('uc'), $queryBuilder->expr()->neq('uc', $queryBuilder->createNamedParameter('')), $queryBuilder->expr()->isNull('user_settings') ) ->executeQuery() ->fetchAllAssociative(); } }