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 */
1919final 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