TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Upgrades;
|
||||
|
||||
use TYPO3\CMS\Core\Attribute\UpgradeWizard;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* @since 14.0
|
||||
* @internal This class is only meant to be used within EXT:install and is not part of the TYPO3 Core API.
|
||||
*/
|
||||
#[UpgradeWizard('userPermissionsForRenamedModulesMigration')]
|
||||
class UserPermissionsForRenamedModulesMigration implements UpgradeWizardInterface
|
||||
{
|
||||
protected array $tables = [
|
||||
'be_groups' => 'groupMods',
|
||||
'be_users' => 'userMods',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array <string, string> an array with the old module identifier as key and the new one as value
|
||||
*/
|
||||
protected array $moduleRenaming = [
|
||||
'web_list' => 'records',
|
||||
'web_info' => 'content_status',
|
||||
'workspaces_admin' => 'workspaces_publish',
|
||||
'site_redirects' => 'redirects',
|
||||
'web_linkvalidator' => 'linkvalidator_checklinks',
|
||||
];
|
||||
|
||||
/**
|
||||
* Modules that require a parent module to be accessible.
|
||||
*
|
||||
* @var array<string, string> Key: the new module identifier, Value: required parent module
|
||||
*/
|
||||
protected array $requiredParentModules = [
|
||||
'redirects' => 'link_management',
|
||||
'linkvalidator_checklinks' => 'link_management',
|
||||
];
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Migrate module permissions';
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Migrate permissions for renamed modules in user and group module permissions. '
|
||||
. 'Also adds required parent modules when a module has been moved to a new location in the module hierarchy.';
|
||||
}
|
||||
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
return $this->migrate(true);
|
||||
}
|
||||
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
return $this->migrate(false);
|
||||
}
|
||||
|
||||
private function migrate(bool $dryRun): bool
|
||||
{
|
||||
$migrated = false;
|
||||
foreach ($this->tables as $table => $field) {
|
||||
$queryBuilder = $this->getConnectionPool()->getQueryBuilderForTable($table);
|
||||
$connection = $this->getConnectionPool()->getConnectionForTable($table);
|
||||
$queryBuilder->select('uid', $field)
|
||||
->from($table)
|
||||
->executeQuery();
|
||||
|
||||
foreach ($queryBuilder->fetchAllAssociative() as $record) {
|
||||
$originalModules = (string)($record[$field] ?? '');
|
||||
$modules = explode(',', $originalModules);
|
||||
$parentModulesToAdd = [];
|
||||
$updatedModules = array_map(function ($module) use (&$parentModulesToAdd) {
|
||||
$trimmedModule = trim($module);
|
||||
if (isset($this->moduleRenaming[$trimmedModule])) {
|
||||
$newModule = $this->moduleRenaming[$trimmedModule];
|
||||
if (isset($this->requiredParentModules[$newModule])) {
|
||||
$parentModulesToAdd[] = $this->requiredParentModules[$newModule];
|
||||
}
|
||||
return $newModule;
|
||||
}
|
||||
return $module;
|
||||
}, $modules);
|
||||
|
||||
$trimmedModules = array_filter(array_map('trim', $updatedModules));
|
||||
$deduplicatedModules = array_unique($trimmedModules);
|
||||
|
||||
// Check if existing modules (already renamed in a previous migration) need parent modules
|
||||
// This handles the case where the wizard ran in v14.0 before $requiredParentModules existed
|
||||
foreach ($deduplicatedModules as $module) {
|
||||
if (isset($this->requiredParentModules[$module])) {
|
||||
$parentModulesToAdd[] = $this->requiredParentModules[$module];
|
||||
}
|
||||
}
|
||||
|
||||
// Add parent modules if not already present
|
||||
foreach (array_unique($parentModulesToAdd) as $parentModule) {
|
||||
if (!in_array($parentModule, $deduplicatedModules, true)) {
|
||||
$deduplicatedModules[] = $parentModule;
|
||||
}
|
||||
}
|
||||
|
||||
$newModules = implode(',', $deduplicatedModules);
|
||||
if ($originalModules !== $newModules) {
|
||||
if ($dryRun) {
|
||||
return true;
|
||||
}
|
||||
$migrated = $connection->update(
|
||||
$table,
|
||||
[
|
||||
$field => $newModules,
|
||||
],
|
||||
['uid' => (int)$record['uid']]
|
||||
) > 0 || $migrated;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $migrated;
|
||||
}
|
||||
|
||||
protected function getConnectionPool(): ConnectionPool
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user