Skip to content

Commit 45d74b9

Browse files
committed
Refactor command for copying user groups
1 parent 1630c1b commit 45d74b9

File tree

1 file changed

+121
-77
lines changed

1 file changed

+121
-77
lines changed

wcfsetup/install/files/lib/system/user/group/command/CopyUserGroup.class.php

Lines changed: 121 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Copies a user group.
1414
*
1515
* @author Olaf Braun
16-
* @copyright 2001-2024 WoltLab GmbH
16+
* @copyright 2001-2025 WoltLab GmbH
1717
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
1818
*/
1919
final class CopyUserGroup
@@ -22,53 +22,39 @@ public function __construct(
2222
public readonly UserGroup $userGroup,
2323
public readonly bool $copyUserGroupOptions,
2424
public readonly bool $copyMembers,
25-
public readonly bool $copyACLOptions
26-
) {
27-
}
25+
public readonly bool $copyACLOptions,
26+
) {}
2827

2928
public function __invoke(): UserGroup
3029
{
31-
// fetch user group option values
3230
if ($this->copyUserGroupOptions) {
33-
$sql = "SELECT optionID, optionValue
34-
FROM wcf1_user_group_option_value
35-
WHERE groupID = ?";
36-
$statement = WCF::getDB()->prepare($sql);
37-
$statement->execute([$this->userGroup->groupID]);
31+
$optionValues = $this->getOptionValues($this->userGroup);
3832
} else {
39-
$sql = "SELECT optionID, defaultValue AS optionValue
40-
FROM wcf1_user_group_option";
41-
$statement = WCF::getDB()->prepare($sql);
42-
$statement->execute();
33+
$optionValues = $this->getDefaultOptionValues();
4334
}
4435

45-
$optionValues = $statement->fetchMap('optionID', 'optionValue');
36+
$group = $this->copyUserGroup($this->userGroup, $optionValues);
37+
$groupEditor = new UserGroupEditor($group);
38+
$groupName = $this->updateGroupName($this->userGroup, $group);
39+
$groupDescription = $this->updateGroupDescription($this->userGroup, $group);
40+
$groupEditor->update([
41+
'groupDescription' => $groupDescription,
42+
'groupName' => $groupName,
43+
]);
4644

47-
$groupType = $this->userGroup->groupType;
48-
// When copying special user groups of which only one may exist,
49-
// change the group type to 'other'.
50-
if (\in_array($groupType, [UserGroup::EVERYONE, UserGroup::GUESTS, UserGroup::USERS, UserGroup::OWNER])) {
51-
$groupType = UserGroup::OTHER;
52-
}
45+
$this->copyMembers($this->userGroup, $group);
46+
$this->copyACLOptions($this->userGroup, $group);
5347

54-
/** @var UserGroup $group */
55-
$group = (new UserGroupAction([], 'create', [
56-
'data' => [
57-
'groupName' => $this->userGroup->groupName,
58-
'groupDescription' => $this->userGroup->groupDescription,
59-
'priority' => $this->userGroup->priority,
60-
'userOnlineMarking' => $this->userGroup->userOnlineMarking,
61-
'showOnTeamPage' => $this->userGroup->showOnTeamPage,
62-
'groupType' => $groupType,
63-
],
64-
'options' => $optionValues,
65-
]))->executeAction()['returnValues'];
66-
$groupEditor = new UserGroupEditor($group);
48+
LanguageFactory::getInstance()->deleteLanguageCache();
49+
UserGroupEditor::resetCache();
50+
51+
return $group;
52+
}
6753

68-
// update group name
69-
$groupName = $this->userGroup->groupName;
70-
if (\preg_match('~^wcf\.acp\.group\.group\d+$~', $this->userGroup->groupName)) {
71-
$groupName = 'wcf.acp.group.group' . $group->groupID;
54+
private function updateGroupName(UserGroup $oldGroup, UserGroup $newGroup): string
55+
{
56+
if (\preg_match('~^wcf\.acp\.group\.group\d+$~', $oldGroup->groupName)) {
57+
$groupName = 'wcf.acp.group.group' . $newGroup->groupID;
7258

7359
// create group name language item
7460
$sql = "INSERT INTO wcf1_language_item
@@ -77,15 +63,18 @@ public function __invoke(): UserGroup
7763
FROM wcf1_language_item
7864
WHERE languageItem = ?";
7965
$statement = WCF::getDB()->prepare($sql);
80-
$statement->execute([$this->userGroup->groupName]);
66+
$statement->execute([$oldGroup->groupName]);
8167
} else {
82-
$groupName .= ' (2)';
68+
$groupName = $oldGroup->groupName . ' (2)';
8369
}
8470

85-
// update group name
86-
$groupDescription = $this->userGroup->groupName;
87-
if (\preg_match('~^wcf\.acp\.group\.groupDescription\d+$~', $this->userGroup->groupDescription)) {
88-
$groupDescription = 'wcf.acp.group.groupDescription' . $group->groupID;
71+
return $groupName;
72+
}
73+
74+
private function updateGroupDescription(UserGroup $oldGroup, UserGroup $newGroup): string
75+
{
76+
if (\preg_match('~^wcf\.acp\.group\.groupDescription\d+$~', $oldGroup->groupDescription)) {
77+
$groupDescription = 'wcf.acp.group.groupDescription' . $newGroup->groupID;
8978

9079
// create group name language item
9180
$sql = "INSERT INTO wcf1_language_item
@@ -94,48 +83,103 @@ public function __invoke(): UserGroup
9483
FROM wcf1_language_item
9584
WHERE languageItem = ?";
9685
$statement = WCF::getDB()->prepare($sql);
97-
$statement->execute([$this->userGroup->groupDescription]);
86+
$statement->execute([$oldGroup->groupDescription]);
87+
} else {
88+
$groupDescription = $oldGroup->groupDescription;
9889
}
9990

100-
$groupEditor->update([
101-
'groupDescription' => $groupDescription,
102-
'groupName' => $groupName,
103-
]);
91+
return $groupDescription;
92+
}
10493

105-
// copy members
106-
if ($this->copyMembers) {
107-
$sql = "INSERT INTO wcf1_user_to_group
108-
(userID, groupID)
109-
SELECT userID, " . $group->groupID . "
110-
FROM wcf1_user_to_group
111-
WHERE groupID = ?";
112-
$statement = WCF::getDB()->prepare($sql);
113-
$statement->execute([$this->userGroup->groupID]);
94+
private function copyMembers(UserGroup $oldGroup, UserGroup $newGroup): void
95+
{
96+
if (!$this->copyMembers) {
97+
return;
11498
}
11599

116-
// copy acl options
117-
if ($this->copyACLOptions) {
118-
$sql = "INSERT INTO wcf1_acl_option_to_group
119-
(optionID, objectID, groupID, optionValue)
120-
SELECT optionID, objectID, " . $group->groupID . ", optionValue
121-
FROM wcf1_acl_option_to_group
122-
WHERE groupID = ?";
123-
$statement = WCF::getDB()->prepare($sql);
124-
$statement->execute([$this->userGroup->groupID]);
125-
126-
// it is likely that applications or plugins use caches
127-
// for acl option values like for the labels which have
128-
// to be renewed after copying the acl options; because
129-
// there is no other way to delete these caches, we simply
130-
// delete all caches
131-
CacheHandler::getInstance()->flushAll();
100+
$sql = "INSERT INTO wcf1_user_to_group
101+
(userID, groupID)
102+
SELECT userID, " . $newGroup->groupID . "
103+
FROM wcf1_user_to_group
104+
WHERE groupID = ?";
105+
$statement = WCF::getDB()->prepare($sql);
106+
$statement->execute([$oldGroup->groupID]);
107+
}
108+
109+
private function copyACLOptions(UserGroup $oldGroup, UserGroup $newGroup): void
110+
{
111+
if (!$this->copyACLOptions) {
112+
return;
132113
}
133114

134-
// reset language cache
135-
LanguageFactory::getInstance()->deleteLanguageCache();
115+
$sql = "INSERT INTO wcf1_acl_option_to_group
116+
(optionID, objectID, groupID, optionValue)
117+
SELECT optionID, objectID, " . $newGroup->groupID . ", optionValue
118+
FROM wcf1_acl_option_to_group
119+
WHERE groupID = ?";
120+
$statement = WCF::getDB()->prepare($sql);
121+
$statement->execute([$oldGroup->groupID]);
122+
123+
// it is likely that applications or plugins use caches
124+
// for acl option values like for the labels which have
125+
// to be renewed after copying the acl options; because
126+
// there is no other way to delete these caches, we simply
127+
// delete all caches
128+
CacheHandler::getInstance()->flushAll();
129+
}
136130

137-
UserGroupEditor::resetCache();
131+
/**
132+
* @param array<int, mixed> $optionValues
133+
*/
134+
private function copyUserGroup(UserGroup $group, array $optionValues): UserGroup
135+
{
136+
$groupType = $group->groupType;
137+
// When copying special user groups of which only one may exist,
138+
// change the group type to 'other'.
139+
if (\in_array($groupType, [UserGroup::EVERYONE, UserGroup::GUESTS, UserGroup::USERS, UserGroup::OWNER])) {
140+
$groupType = UserGroup::OTHER;
141+
}
142+
143+
$group = (new UserGroupAction([], 'create', [
144+
'data' => [
145+
'groupName' => $group->groupName,
146+
'groupDescription' => $group->groupDescription,
147+
'priority' => $group->priority,
148+
'userOnlineMarking' => $group->userOnlineMarking,
149+
'showOnTeamPage' => $group->showOnTeamPage,
150+
'groupType' => $groupType,
151+
],
152+
'options' => $optionValues,
153+
]))->executeAction()['returnValues'];
154+
\assert($group instanceof UserGroup);
138155

139156
return $group;
140157
}
158+
159+
/**
160+
* @return array<int, mixed>
161+
*/
162+
private function getOptionValues(UserGroup $group): array
163+
{
164+
$sql = "SELECT optionID, optionValue
165+
FROM wcf1_user_group_option_value
166+
WHERE groupID = ?";
167+
$statement = WCF::getDB()->prepare($sql);
168+
$statement->execute([$group->groupID]);
169+
170+
return $statement->fetchMap('optionID', 'optionValue');
171+
}
172+
173+
/**
174+
* @return array<int, mixed>
175+
*/
176+
private function getDefaultOptionValues(): array
177+
{
178+
$sql = "SELECT optionID, defaultValue AS optionValue
179+
FROM wcf1_user_group_option";
180+
$statement = WCF::getDB()->prepare($sql);
181+
$statement->execute();
182+
183+
return $statement->fetchMap('optionID', 'optionValue');
184+
}
141185
}

0 commit comments

Comments
 (0)