_binary From 37d8a16bfeeb10e81ef049ea17634bf4213d748b Mon Sep 17 00:00:00 2001
From: Aditya <thesyn3rman@gmail.com>
Date: Tue, 5 Nov 2024 02:36:25 -0800
Subject: [PATCH] add editors list for wiki

Signed-off-by: Aditya <thesyn3rman@gmail.com>
---
 src/configs/Config.php                        |   2 +-
 src/configs/Createdb.php                      |   2 +-
 src/controllers/RegisterController.php        |   2 +-
 .../components/AccountaccessComponent.php     |   5 +-
 .../components/SocialComponent.php            |  65 +++++-
 src/library/VersionFunctions.php              |  21 +-
 src/locale/ar/configure.ini                   |   1 +
 src/locale/bn/configure.ini                   |   1 +
 src/locale/de/configure.ini                   |   1 +
 src/locale/el_GR/configure.ini                |   1 +
 src/locale/en_US/configure.ini                |   1 +
 src/locale/es/configure.ini                   |   1 +
 src/locale/fa/configure.ini                   |   1 +
 src/locale/fr_FR/configure.ini                |   3 +-
 src/locale/he/configure.ini                   |   4 +-
 src/locale/hi/configure.ini                   |   1 +
 src/locale/id/configure.ini                   |   1 +
 src/locale/it/configure.ini                   |   1 +
 src/locale/ja/configure.ini                   |   1 +
 src/locale/kn/configure.ini                   |   1 +
 src/locale/ko/configure.ini                   |   1 +
 src/locale/nl/configure.ini                   |   1 +
 src/locale/pl/configure.ini                   |   1 +
 src/locale/pt/configure.ini                   |   1 +
 src/locale/ru/configure.ini                   |   1 +
 src/locale/te/configure.ini                   |   1 +
 src/locale/th/configure.ini                   |   1 +
 src/locale/tl/configure.ini                   |   1 +
 src/locale/tr/configure.ini                   |   1 +
 src/locale/vi_VN/configure.ini                |   1 +
 src/locale/zh_CN/configure.ini                |   1 +
 src/models/GroupModel.php                     | 187 +++++++++++++++++-
 src/models/ProfileModel.php                   |   6 +
 src/views/elements/GroupbarElement.php        |   1 +
 src/views/elements/ManagegroupsElement.php    |  13 ++
 src/views/helpers/GrouplistHelper.php         |   1 +
 tests/ManyUserExperiment.php                  |   4 +-
 37 files changed, 311 insertions(+), 28 deletions(-)

diff --git a/src/configs/Config.php b/src/configs/Config.php
index c94792c02..ff823d47f 100755
--- a/src/configs/Config.php
+++ b/src/configs/Config.php
@@ -162,7 +162,7 @@ nsconddefine('GENERATOR_STRING', "Yioop");
  * Version number for upgrade database function
  * @var int
  */
-nsdefine('DATABASE_VERSION', 81);
+nsdefine('DATABASE_VERSION', 82);
 /**
  * Minimum Version fo Yioop for which keyword ad script
  * still works with this version
diff --git a/src/configs/Createdb.php b/src/configs/Createdb.php
index 799279349..e17adff03 100755
--- a/src/configs/Createdb.php
+++ b/src/configs/Createdb.php
@@ -150,7 +150,7 @@ $root_group_name = C\PERSONAL_GROUP_PREFIX . ROOT_ID;
 $group_model = new GroupModel(DB_NAME, false);
 $group_model->db = $db;
 $group_model->addGroup($root_group_name,
-    ROOT_ID, C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+    ROOT_ID, ["root"], C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
     C\NON_VOTING_GROUP, C\FOREVER, 0);
 /* public account is an inactive account for used for public permissions
    default account is root without a password
diff --git a/src/controllers/RegisterController.php b/src/controllers/RegisterController.php
index 5e7ece334..cb15cb982 100755
--- a/src/controllers/RegisterController.php
+++ b/src/controllers/RegisterController.php
@@ -322,7 +322,7 @@ class RegisterController extends Controller implements CrawlConstants
                 $user['USER_ID'];
             if ($group_model->getGroupId($personal_group_name) < 0) {
                 $group_model->addGroup($personal_group_name,
-                    $user['USER_ID'], C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+                    $user['USER_ID'], [$user['USER_NAME']], C\INVITE_ONLY_JOIN,
                     C\ACTIVE_STATUS, C\NON_VOTING_GROUP, C\FOREVER, 0);
             }
         }
diff --git a/src/controllers/components/AccountaccessComponent.php b/src/controllers/components/AccountaccessComponent.php
index 65cf33858..cebd44cee 100644
--- a/src/controllers/components/AccountaccessComponent.php
+++ b/src/controllers/components/AccountaccessComponent.php
@@ -166,7 +166,7 @@ class AccountaccessComponent extends Component
         if (($personal_group_id =
             $group_model->getGroupId($personal_group_name)) < 0) {
             $personal_group_id = $group_model->addGroup($personal_group_name,
-                $user_id, C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+                $user_id, [$username], C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+                 C\NON_VOTING_GROUP, C\FOREVER, 0);
         }
         $this->initSocialBadges($user_id, $data);
@@ -511,6 +511,7 @@ class AccountaccessComponent extends Component
                             substr($parent->clean($_REQUEST['password'],
                             "string"), 0, C\LONG_NAME_LEN);
                         $username = trim($username);
+
                         $user_id = $user_model->addUser($username,
                             $norm_password,
                             substr(trim($parent->clean($_REQUEST['first_name'],
@@ -526,7 +527,7 @@ class AccountaccessComponent extends Component
                             $user_id;
                         if ($group_model->getGroupId($personal_group_name) < 0){
                             $group_model->addGroup($personal_group_name,
-                                $user_id, C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+                                $user_id, [$username], C\INVITE_ONLY_JOIN,
+                                 C\ACTIVE_STATUS, C\NON_VOTING_GROUP,
+                                 C\FOREVER, 0);
                         }
                         return $parent->redirectWithMessage(
diff --git a/src/controllers/components/SocialComponent.php b/src/controllers/components/SocialComponent.php
index 572d6b3f0..0153fc140 100644
--- a/src/controllers/components/SocialComponent.php
+++ b/src/controllers/components/SocialComponent.php
@@ -136,6 +136,17 @@ class SocialComponent extends Component implements CrawlConstants
             1 => tl('social_component_encryption_enable'),
             0 => tl('social_component_encryption_disable'),
         ];
+
+        if (!empty($_REQUEST['group_id'])) {
+            $group_id = $parent->clean($_REQUEST['group_id'], "int");
+            $wiki_editors = $group_model->getWikiEditors($group_id);
+            $data['edit_wiki_users'] = $wiki_editors;
+            $data['edit_wiki_usernames'] =
+                 $group_model->getWikiEditorsUsernames($group_id);
+        }
+        else {
+            $data['edit_wiki_users'] = [$_SESSION['USER_ID']];
+            $data['edit_wiki_usernames'] = [
+                $this->parent->model("user")->getUserName($_SESSION['USER_ID'])
+            ];
+        }
         if (in_array(C\MONETIZATION_TYPE, ['group_fees','fees_and_keywords'])) {
             $data['can_monetise_group'] = true;
         } else {
@@ -344,8 +355,17 @@ class SocialComponent extends Component implements CrawlConstants
                             "vote_access" => ["VOTING_CODES",
                                 C\NON_VOTING_GROUP],
                             "post_lifetime" => ["POST_LIFETIMES", C\FOREVER],
-                            "encryption" => ["ENCRYPTION_CODES", 0]
+                            "encryption" => ["ENCRYPTION_CODES", 0],
                         ];
+
+                        $edit_wiki_users = [];
+                        if (isset($_REQUEST['edit_wiki_users'])) {
+                            $edit_wiki_users = array_map(
+                                'trim', explode(',', $_REQUEST['edit_wiki_users'])
+                            );
+                            $edit_wiki_users = $group_model->validateWikiEditors(
+                                $edit_wiki_users
+                            );
+                        }
+
+                        $_REQUEST['edit_wiki_users'] = $edit_wiki_users;
+
                         foreach ($group_fields as $field => $info) {
                             if (!isset($_REQUEST[$field]) ||
                                 !in_array($_REQUEST[$field],
@@ -354,7 +374,7 @@ class SocialComponent extends Component implements CrawlConstants
                             }
                         }
                         $group_model->addGroup($name,
-                            $_SESSION['USER_ID'], $_REQUEST['register'],
+                            $_SESSION['USER_ID'],
+                            $_REQUEST['edit_wiki_users'],
+                            $_REQUEST['register'],
                             $_REQUEST['member_access'],
                             $_REQUEST['vote_access'],
                             $_REQUEST['post_lifetime'],
@@ -445,10 +465,24 @@ class SocialComponent extends Component implements CrawlConstants
                         ['register', 'REGISTER_TYPE','REGISTER_CODES'],
                         ['vote_access', 'VOTE_ACCESS', 'VOTING_CODES'],
                         ['post_lifetime', 'POST_LIFETIME', 'POST_LIFETIMES'],
-                        ['encryption', 'ENCRYPTION', 'ENCRYPTION_CODES']
+                        ['encryption', 'ENCRYPTION', 'ENCRYPTION_CODES'],
                         ];
                     $message = $this->updateGroup($data, $group,
-                        $update_fields);
+                    $update_fields);
+                    $edit_wiki_users = [];
+                    $edit_wiki_users_cleaned = [];
+                    if (isset($_REQUEST['edit_wiki_users'])) {
+                        $edit_wiki_users = array_map(
+                            'trim', explode(',', $_REQUEST['edit_wiki_users'])
+                        );
+                        foreach ($edit_wiki_users as $user) {
+                            $clean_user = $parent->clean(
+                                trim($user), "string"
+                            );
+                            $edit_wiki_users_cleaned[] = $clean_user;
+                        }
+                        $edit_wiki_users_cleaned[] = $this->parent->model("user")
+                            ->getUserName($_SESSION['USER_ID']);
+                        $edit_wiki_users = $group_model->validateWikiEditors(
+                            $edit_wiki_users_cleaned
+                        );
+                        $data['edit_wiki_usernames'] = $edit_wiki_users_cleaned;
+                        $data['edit_wiki_users'] = $group_model->wikiEditorIdLookup(
+                            $edit_wiki_users_cleaned
+                        );
+                        $message = $group_model->updateWikiEditors(
+                            $group_id, $edit_wiki_users_cleaned
+                        );
+                    }
                     if (!empty($message)) {
                         $preserve_fields = ['arg', 'browse', 'context',
                             'start_row','end_row', 'group_limit', 'num_show',
@@ -2061,10 +2095,12 @@ class SocialComponent extends Component implements CrawlConstants
                 $page_info = $group_model->getPageInfoByThread($just_thread);
                 if (isset($page_info["PAGE_NAME"])) {
                     $group_id = $page_info['GROUP_ID'];
+                    $wiki_editors = $group_model->getWikiEditors($group_id);
+                    $is_user_editor = in_array($user_id, $wiki_editors);
                     $data["WIKI_PAGE_NAME"] = $page_info["PAGE_NAME"];
                     $group = $group_model->getGroupById($group_id, $user_id,
                         true);
-                    if (!empty($group) && ($group["OWNER_ID"] == $user_id ||
+                    if (!empty($group) &&
+                        ($group["OWNER_ID"] == $user_id || $is_user_editor ||
                         ($group["STATUS"] == C\ACTIVE_STATUS &&
                         $group["MEMBER_ACCESS"] == C\GROUP_READ_WIKI &&
                         $user_id != C\PUBLIC_USER_ID))) {
@@ -3001,7 +3037,7 @@ class SocialComponent extends Component implements CrawlConstants
             $page['USER_ICON'] = $user_model->getUserIconUrl($page['USER_ID']);
             $page[self::TITLE] = $page['TITLE'];
             //functionality for moderation group
-            if($page['GROUP_ID'] == C\MODERATION_GROUP_ID
+            if ($page['GROUP_ID'] == C\MODERATION_GROUP_ID
                 && $page['FLAG'] != C\MODERATION_GENERAL) {
                 $parent_group_id = $group_model->getParentGroupId($page['ID']);
                 $page['PARENT_ITEM_ID'] =
@@ -3313,6 +3349,7 @@ class SocialComponent extends Component implements CrawlConstants
             $strings_array) = $this->initCommonWikiArrays(
                 $controller_name, $base_url);
         $group_model = $parent->model("group");
+
         if (isset($_SESSION['USER_ID'])) {
             $user_id = $_SESSION['USER_ID'];
             $data['ADMIN'] = 1;
@@ -3399,6 +3436,10 @@ class SocialComponent extends Component implements CrawlConstants
         } else {
             $group_id = C\PUBLIC_GROUP_ID;
         }
+        $wiki_editors = $group_model->getWikiEditors($group_id);
+        if (in_array($user_id, $wiki_editors)) {
+            $data['CAN_EDIT'] = true;
+        }
         $group = $group_model->getGroupById($group_id, $user_id, true);
         if (!$group) {
             $group = $group_model->getGroupById($group_id, $user_id);
@@ -4528,11 +4569,17 @@ EOD;
         $page_name, $page, $sub_path, $edit_reason,
         $missing_fields, $read_address, $additional_substitutions)
     {
+        $parent = $this->parent;
+        $group_model = $parent->model("group");
+        $wiki_editors = $group_model->getWikiEditors($group_id);
+
+        if (in_array($user_id, $wiki_editors)) {
+            $data['CAN_EDIT'] = true;
+        }
         if (empty($data["CAN_EDIT"])) {
             return;
         }
-        $parent = $this->parent;
-        $group_model = $parent->model("group");
+
         if (isset($_REQUEST['caret']) &&
            isset($_REQUEST['scroll_top'])
                 && !isset($page)) {
@@ -5560,4 +5607,4 @@ EOD;
             }
 EOD;
     }
-}
+}
\ No newline at end of file
diff --git a/src/library/VersionFunctions.php b/src/library/VersionFunctions.php
index 59102e9c6..3148eac17 100644
--- a/src/library/VersionFunctions.php
+++ b/src/library/VersionFunctions.php
@@ -1870,7 +1870,7 @@ function upgradeDatabaseVersion65(&$db)
     $group_model->db = $db;
     $group_id = $group_model->getGroupId('Search');
     if ($group_id <= 0) {
-        $group_model->addGroup('Search', C\ROOT_ID,
+        $group_model->addGroup('Search', C\ROOT_ID, ["root"],
             C\PUBLIC_BROWSE_REQUEST_JOIN, C\GROUP_READ_WIKI,
             C\UP_DOWN_VOTING_GROUP, C\FOREVER, 0);
         $group_id = $group_model->getGroupId('Search');
@@ -2193,3 +2193,22 @@ function upgradeDatabaseVersion81(&$db)
     $profile_model->updateProfile(C\WORK_DIRECTORY, $new_profile,
         $profile);
 }
+/**
+ * Upgrades a Version 81 version of the Yioop database to a Version 82 version
+ * @param object $db datasource to use to upgrade
+ */
+function upgradeDatabaseVersion82(&$db)
+{
+    $dbinfo = [
+        "DBMS" => C\DBMS,
+        "DB_HOST" => C\DB_HOST,
+        "DB_NAME" => C\DB_NAME,
+        "DB_PASSWORD" => C\DB_PASSWORD
+    ];
+    $integer = $db->integerType($dbinfo);
+    // Drop the table if it exists to prevent errors on re-running upgrade
+    $db->execute("DROP TABLE IF EXISTS GROUP_EDITORS");
+    $db->execute(
+        "CREATE TABLE GROUP_EDITORS (" +
+        "id $integer AUTO_INCREMENT PRIMARY KEY, " +
+        "group_id $integer NOT NULL, " +
+        "user_id $integer NOT NULL, " +
+        "FOREIGN KEY (group_id) REFERENCES SOCIAL_GROUPS(GROUP_ID) " +
+        "ON DELETE CASCADE ON UPDATE CASCADE, " +
+        "FOREIGN KEY (user_id) REFERENCES USERS(USER_ID) " +
+        "ON DELETE CASCADE ON UPDATE CASCADE)"
+    );
+}

diff --git a/src/locale/ar/configure.ini b/src/locale/ar/configure.ini
index 7b6c08bed..f738343f2 100755
--- a/src/locale/ar/configure.ini
+++ b/src/locale/ar/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "إ 注册"
 managegroups_element_memberaccess = "دخول"
 managegroups_element_voting = "التصويت"
 managegroups_element_post_lifetime = "عمر المنشور"
+managegroups_element_wikieditors = "محررو الويكي"
 managegroups_element_encryption = "تشفير"
 managegroups_element_feed = "رصد"
 managegroups_element_import_discussions = "إستيراد المحادثات"
diff --git a/src/locale/bn/configure.ini b/src/locale/bn/configure.ini
index 0190e50ea..bcbc3002c 100755
--- a/src/locale/bn/configure.ini
+++ b/src/locale/bn/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "রেজিস্টার"
 managegroups_element_memberaccess = "অ্যাক্সেস"
 managegroups_element_voting = "ভোটিং"
 managegroups_element_post_lifetime = "পোস্ট জীবনকাল"
+managegroups_element_wikieditors = "উইকি সম্পাদক"
 managegroups_element_encryption = "এনক্রিপশন"
 managegroups_element_feed = "ফিড"
 managegroups_element_import_discussions = "আমদানি আলোচনা"
diff --git a/src/locale/de/configure.ini b/src/locale/de/configure.ini
index ce7449441..1cdd32231 100755
--- a/src/locale/de/configure.ini
+++ b/src/locale/de/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Inscribirse"
 managegroups_element_memberaccess = "Zugriff"
 managegroups_element_voting = "Stimmen"
 managegroups_element_post_lifetime = "Dauer des Beitrags"
+managegroups_element_wikieditors = "Wiki-Editoren"
 managegroups_element_encryption = "Verschlüsselung"
 managegroups_element_feed = "Nachrichten"
 managegroups_element_import_discussions = "Importate Discusiones"
diff --git a/src/locale/el_GR/configure.ini b/src/locale/el_GR/configure.ini
index 0f3675a21..3e7c4d3b0 100644
--- a/src/locale/el_GR/configure.ini
+++ b/src/locale/el_GR/configure.ini
@@ -1180,6 +1180,7 @@ managegroups_element_register = "Εγγραφή"
 managegroups_element_memberaccess = "Πρόσβαση"
 managegroups_element_voting = "Εψήφηση"
 managegroups_element_post_lifetime = "Πόστι Ζωή"
+managegroups_element_wikieditors = "Επεξεργαστές Wiki"
 managegroups_element_encryption = "Κρυπτογράφηση"
 managegroups_element_feed = "Παρακοινοποίηση"
 managegroups_element_import_discussions = "Εισαγωγή Συζητήσεων"
diff --git a/src/locale/en_US/configure.ini b/src/locale/en_US/configure.ini
index 4322ff375..e1edef9dc 100644
--- a/src/locale/en_US/configure.ini
+++ b/src/locale/en_US/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Register"
 managegroups_element_memberaccess = "Access"
 managegroups_element_voting = "Voting"
 managegroups_element_post_lifetime = "Post Lifetime"
+managegroups_element_wikieditors = "Wiki Editors"
 managegroups_element_encryption = "Encryption"
 managegroups_element_feed = "Feed"
 managegroups_element_import_discussions = "Import Discussions"
diff --git a/src/locale/es/configure.ini b/src/locale/es/configure.ini
index 1c0aacee0..97f14ffa1 100755
--- a/src/locale/es/configure.ini
+++ b/src/locale/es/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Registro"
 managegroups_element_memberaccess = "Acceso"
 managegroups_element_voting = "Votación"
 managegroups_element_post_lifetime = "Vida después de la publicación"
+managegroups_element_wikieditors = "Editores de Wiki"
 managegroups_element_encryption = "Criptografía"
 managegroups_element_feed = "Ruta de alimentación"
 managegroups_element_import_discussions = "Importar discusiones"
diff --git a/src/locale/fa/configure.ini b/src/locale/fa/configure.ini
index 52d34cccd..c4ceccf9e 100755
--- a/src/locale/fa/configure.ini
+++ b/src/locale/fa/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "ثبت نام"
 managegroups_element_memberaccess = "دسترسی"
 managegroups_element_voting = "رأی"
 managegroups_element_post_lifetime = "پس از عمر"
+managegroups_element_wikieditors = "ویراستاران ویکی"
 managegroups_element_encryption = "شیفه"
 managegroups_element_feed = "رشته"
 managegroups_element_import_discussions = "دخیل بحث‌ها را وارد کنید"
diff --git a/src/locale/fr_FR/configure.ini b/src/locale/fr_FR/configure.ini
index 68ba49a08..133bf2a98 100755
--- a/src/locale/fr_FR/configure.ini
+++ b/src/locale/fr_FR/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Inscrire"
 managegroups_element_memberaccess = "Accès"
 managegroups_element_voting = "Votation"
 managegroups_element_post_lifetime = "Gestion de vie du groupe"
+managegroups_element_wikieditors = "Éditeurs Wiki"
 managegroups_element_encryption = "Chiffrement"
 managegroups_element_feed = "Rubrique"
 managegroups_element_import_discussions = "Importer les discussions"
@@ -5686,4 +5687,4 @@ wordfilter_plugin_settings_saved = "Les paramètres de filtration des mots ont
 wordfilter_plugin_defaults_restored = "Les paramètres par défaut ont été restaurés !"
 wordfilter_plugin_preferences = "Filtrage des mots : préférences"
 wordfilter_plugin_factory_settings = "Paramètres d\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'usine"
-wordfilter_plugin_save = "Enregistrer"
+wordfilter_plugin_save = "Enregistrer"
\ No newline at end of file
diff --git a/src/locale/he/configure.ini b/src/locale/he/configure.ini
index 52d281452..f18fa9801 100755
--- a/src/locale/he/configure.ini
+++ b/src/locale/he/configure.ini
@@ -1160,6 +1160,8 @@ managegroups_element_register = "Registro"
 managegroups_element_memberaccess = "Acceso"
 managegroups_element_voting = "Votación"
 managegroups_element_post_lifetime = "Kündigungszeitraum"
+managegroups_element_wikieditors = "עורכי ויקי"
+managegroups_element_wikieditors = "עורכי ויקי"
 managegroups_element_encryption = "Verschlüsselung"
 managegroups_element_feed = "Feed"
 managegroups_element_import_discussions = "Diskussionsimportieren"
@@ -5686,4 +5688,4 @@ wordfilter_plugin_settings_saved = "המילה הגדרות סינון הציל!
 wordfilter_plugin_defaults_restored = "ברירות מחדל משוחזר!"
 wordfilter_plugin_preferences = "המילה העדפות סינון"
 wordfilter_plugin_factory_settings = "הגדרות יצרן"
-wordfilter_plugin_save = "להציל"
+wordfilter_plugin_save = "להציל"
\ No newline at end of file
diff --git a/src/locale/hi/configure.ini b/src/locale/hi/configure.ini
index 759d32371..312318929 100755
--- a/src/locale/hi/configure.ini
+++ b/src/locale/hi/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "रजिस्टर"
 managegroups_element_memberaccess = "पहुँच"
 managegroups_element_voting = "मतदान"
 managegroups_element_post_lifetime = "पोस्ट जीवन भर"
+managegroups_element_wikieditors = "विकी संपादक"
 managegroups_element_encryption = "एन्क्रिप्शन"
 managegroups_element_feed = "फ़ीड"
 managegroups_element_import_discussions = "आयात चर्चा"
diff --git a/src/locale/id/configure.ini b/src/locale/id/configure.ini
index cf4cf0fd8..14c92a21e 100755
--- a/src/locale/id/configure.ini
+++ b/src/locale/id/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Daftar"
 managegroups_element_memberaccess = "Akses"
 managegroups_element_voting = "Pemegang"
 managegroups_element_post_lifetime = "Posting Seumur Hidup"
+managegroups_element_wikieditors = "Editor Wiki"
 managegroups_element_encryption = "Enkripsi"
 managegroups_element_feed = "Pakan"
 managegroups_element_import_discussions = "Impor Diskusi"
diff --git a/src/locale/it/configure.ini b/src/locale/it/configure.ini
index 48a6ad662..8ce4d10b4 100755
--- a/src/locale/it/configure.ini
+++ b/src/locale/it/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Registro"
 managegroups_element_memberaccess = "Accesso"
 managegroups_element_voting = "Voto"
 managegroups_element_post_lifetime = "Post Vita"
+managegroups_element_wikieditors = "Editor Wiki"
 managegroups_element_encryption = "La crittografia"
 managegroups_element_feed = "Feed"
 managegroups_element_import_discussions = "Importazione Discussioni"
diff --git a/src/locale/ja/configure.ini b/src/locale/ja/configure.ini
index 72a790540..114ceac56 100755
--- a/src/locale/ja/configure.ini
+++ b/src/locale/ja/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "登録"
 managegroups_element_memberaccess = "アクセス"
 managegroups_element_voting = "議決権"
 managegroups_element_post_lifetime = "ポストの生涯"
+managegroups_element_wikieditors = "ウィキ編集者"
 managegroups_element_encryption = "暗号化"
 managegroups_element_feed = "飼料"
 managegroups_element_import_discussions = "輸入の議論"
diff --git a/src/locale/kn/configure.ini b/src/locale/kn/configure.ini
index fc6f6317c..23ae9af5d 100755
--- a/src/locale/kn/configure.ini
+++ b/src/locale/kn/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "ನೋಂದಣಿ"
 managegroups_element_memberaccess = "ಪ್ರವೇಶ"
 managegroups_element_voting = "ಮತದಾನ"
 managegroups_element_post_lifetime = "ಪೋಸ್ಟ್ ಜೀವಮಾನ"
+managegroups_element_wikieditors = "ವಿಕಿ ಸಂಪಾದಕರು"
 managegroups_element_encryption = "ಗೂಢಲಿಪೀಕರಣ"
 managegroups_element_feed = "ಫೀಡ್"
 managegroups_element_import_discussions = "ಆಮದು ಚರ್ಚೆಗಳು"
diff --git a/src/locale/ko/configure.ini b/src/locale/ko/configure.ini
index 81d88227d..306d238ef 100755
--- a/src/locale/ko/configure.ini
+++ b/src/locale/ko/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "등록"
 managegroups_element_memberaccess = "스"
 managegroups_element_voting = "투표"
 managegroups_element_post_lifetime = "게시 일생"
+managegroups_element_wikieditors = "위키 편집자"
 managegroups_element_encryption = "암호화"
 managegroups_element_feed = "피드"
 managegroups_element_import_discussions = "Import 토론"
diff --git a/src/locale/nl/configure.ini b/src/locale/nl/configure.ini
index 6b152b782..a03f23e2a 100644
--- a/src/locale/nl/configure.ini
+++ b/src/locale/nl/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Registreer"
 managegroups_element_memberaccess = "toegang"
 managegroups_element_voting = "stemming"
 managegroups_element_post_lifetime = "bericht Lifetime"
+managegroups_element_wikieditors = "Wiki-bewerkers"
 managegroups_element_encryption = "Encryptie"
 managegroups_element_feed = "Feed"
 managegroups_element_import_discussions = "Importeren Discussies"
diff --git a/src/locale/pl/configure.ini b/src/locale/pl/configure.ini
index e325473fb..053da6b78 100755
--- a/src/locale/pl/configure.ini
+++ b/src/locale/pl/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Zarejestruj się"
 managegroups_element_memberaccess = "Dostęp do"
 managegroups_element_voting = "Głosowanie"
 managegroups_element_post_lifetime = "Po Życiu"
+managegroups_element_wikieditors = "Edytory Wiki"
 managegroups_element_encryption = "Szyfrowanie"
 managegroups_element_feed = "Karmić"
 managegroups_element_import_discussions = "Dyskusja Import "
diff --git a/src/locale/pt/configure.ini b/src/locale/pt/configure.ini
index 54409d7a4..f43d8eeec 100755
--- a/src/locale/pt/configure.ini
+++ b/src/locale/pt/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Registar"
 managegroups_element_memberaccess = "Acesso"
 managegroups_element_voting = "Vota&ccedil;&atilde;o"
 managegroups_element_post_lifetime = "P&oacute;s Vida"
+managegroups_element_wikieditors = "Editores Wiki"
 managegroups_element_encryption = "Criptografia"
 managegroups_element_feed = "Alimenta&ccedil;&atilde;o"
 managegroups_element_import_discussions = "Importa&ccedil;&atilde;o De Discuss&otilde;es"
diff --git a/src/locale/ru/configure.ini b/src/locale/ru/configure.ini
index a14dfc136..1ee4023fa 100755
--- a/src/locale/ru/configure.ini
+++ b/src/locale/ru/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Зарегистрироваться"
 managegroups_element_memberaccess = "Доступ к"
 managegroups_element_voting = "Голосование"
 managegroups_element_post_lifetime = "После Жизни"
+managegroups_element_wikieditors = "Редакторы Wiki"
 managegroups_element_encryption = "Шифрование"
 managegroups_element_feed = "Кормить"
 managegroups_element_import_discussions = "Обсуждение Импорт "
diff --git a/src/locale/te/configure.ini b/src/locale/te/configure.ini
index 40057c497..34b47f8d7 100644
--- a/src/locale/te/configure.ini
+++ b/src/locale/te/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "నమోదు చేయి"
 managegroups_element_memberaccess = "ప్రాప్యత"
 managegroups_element_voting = "ఓటింగ్"
 managegroups_element_post_lifetime = "పోస్ట్ జీవితకాలం"
+managegroups_element_wikieditors = "వికీ ఎడిటర్లు"
 managegroups_element_encryption = "ఎన్క్రిప్షన్"
 managegroups_element_feed = "ఫీడ్"
 managegroups_element_import_discussions = "దిగుమతి చర్చలు"
diff --git a/src/locale/th/configure.ini b/src/locale/th/configure.ini
index 53ff5a335..ad28eb9bf 100755
--- a/src/locale/th/configure.ini
+++ b/src/locale/th/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "ลงทะเบียน"
 managegroups_element_memberaccess = "การเข้าถึง"
 managegroups_element_voting = "โหวต"
 managegroups_element_post_lifetime = "โพสในชีวิต"
+managegroups_element_wikieditors = "บรรณาธิการ Wiki"
 managegroups_element_encryption = "การเข้ารหัส"
 managegroups_element_feed = "แหล่งป้อน"
 managegroups_element_import_discussions = "นำเข้า Discussions"
diff --git a/src/locale/tl/configure.ini b/src/locale/tl/configure.ini
index 13f6994de..794920a92 100644
--- a/src/locale/tl/configure.ini
+++ b/src/locale/tl/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Magrehistro"
 managegroups_element_memberaccess = "Access"
 managegroups_element_voting = "Pagboto"
 managegroups_element_post_lifetime = "Mag-Post Ng Panghabang Buhay"
+managegroups_element_wikieditors = "Mga Editor ng Wiki"
 managegroups_element_encryption = "Pag-encrypt"
 managegroups_element_feed = "Feed"
 managegroups_element_import_discussions = "I-Import Ang Mga Talakayan"
diff --git a/src/locale/tr/configure.ini b/src/locale/tr/configure.ini
index 755fad172..57ba2cbef 100755
--- a/src/locale/tr/configure.ini
+++ b/src/locale/tr/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Kayıt"
 managegroups_element_memberaccess = "Erişim"
 managegroups_element_voting = "Oylama"
 managegroups_element_post_lifetime = "Sonrası &Ouml;m&uuml;r Boyu"
+managegroups_element_wikieditors = "Wiki Editörleri"
 managegroups_element_encryption = "Şifreleme"
 managegroups_element_feed = "Besleme"
 managegroups_element_import_discussions = "İthalat Tartışmalar"
diff --git a/src/locale/vi_VN/configure.ini b/src/locale/vi_VN/configure.ini
index 20a4202ff..d3c010600 100755
--- a/src/locale/vi_VN/configure.ini
+++ b/src/locale/vi_VN/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "Đăng k&yacute;"
 managegroups_element_memberaccess = "Truy cập"
 managegroups_element_voting = "Bỏ phiếu"
 managegroups_element_post_lifetime = "B&agrave;i Đời"
+managegroups_element_wikieditors = "Biên tập viên Wiki"
 managegroups_element_encryption = "M&atilde; h&oacute;a"
 managegroups_element_feed = "Thức ăn"
 managegroups_element_import_discussions = "Nhập Cuộc Thảo Luận"
diff --git a/src/locale/zh_CN/configure.ini b/src/locale/zh_CN/configure.ini
index c3ac8cd45..92ec44e96 100755
--- a/src/locale/zh_CN/configure.ini
+++ b/src/locale/zh_CN/configure.ini
@@ -1160,6 +1160,7 @@ managegroups_element_register = "注册"
 managegroups_element_memberaccess = "访问"
 managegroups_element_voting = "投票"
 managegroups_element_post_lifetime = "后辈子"
+managegroups_element_wikieditors = "维基编辑器"
 managegroups_element_encryption = "加密的"
 managegroups_element_feed = "喂"
 managegroups_element_import_discussions = "导入讨论"
diff --git a/src/models/GroupModel.php b/src/models/GroupModel.php
index caa772f1c..4d904698a 100644
--- a/src/models/GroupModel.php
+++ b/src/models/GroupModel.php
@@ -265,7 +265,7 @@ class GroupModel extends Model implements MediaConstants
      *      group
      * @return int id of group added
      */
-    public function addGroup($group_name, $user_id,
+    public function addGroup($group_name, $user_id, $wiki_editors,
         $register = C\REQUEST_JOIN, $member = C\GROUP_READ,
         $voting = C\NON_VOTING_GROUP, $post_lifetime = C\FOREVER,
         $encryption = 0)
@@ -300,6 +300,18 @@ class GroupModel extends Model implements MediaConstants
             $encrypt_key = base64_encode(openssl_random_pseudo_bytes(32));
             $private_db->execute($sql, [$last_id, $encrypt_key]);
         }
+        if (is_string($wiki_editors)) {
+            $wiki_editors = array_map('trim', explode(',', $wiki_editors));
+        }
+        $insert_sql = "INSERT INTO GROUP_EDITORS (group_id, user_id) VALUES (?, ?)";
+        foreach ($wiki_editors as $editor) {
+            $get_user_sql = "SELECT USER_ID FROM USERS WHERE USER_NAME = ?";
+            $result = $this->db->execute($get_user_sql, [$editor]);
+            if ($result && $editor_row = $this->db->fetchArray($result)) {
+                $editor_id = $editor_row['USER_ID'];
+                $this->db->execute($insert_sql, [$last_id, $editor_id]);
+            }
+        }
         return $last_id;
     }
     /**
@@ -470,6 +482,8 @@ class GroupModel extends Model implements MediaConstants
         $db->execute($sql, $params);
         $sql = "DELETE FROM TYPE_KEYS WHERE TYPE_ID=?";
         $private_db->execute($sql, $params);
+        $sql = "DELETE FROM GROUP_EDITORS WHERE group_id=?";
+        $db->execute($sql, $params);
     }
     /**
      * Deletes a wiki page from a group from the database
@@ -502,6 +516,161 @@ class GroupModel extends Model implements MediaConstants
         $db->execute($sql, $params);
         return true;
     }
+    /**
+     * Validates an array of usernames against the USERS table to ensure they
+     * are registered users.
+     *
+     * @param array $edit_wiki_users Array of usernames to validate.
+     * @return array Returns an array of valid usernames from the USERS table.
+     */
+    public function validateWikiEditors($edit_wiki_users)
+    {
+        if (empty($edit_wiki_users) || !is_array($edit_wiki_users)) {
+            return [];
+        }
+        $placeholders = implode(',', array_fill(0, count($edit_wiki_users), '?'));
+        $sql = "SELECT USER_NAME FROM USERS WHERE USER_NAME IN ($placeholders)";
+        $result = $this->db->execute($sql, $edit_wiki_users);
+        $valid_users = [];
+        while ($row = $this->db->fetchArray($result)) {
+            if (isset($row['USER_NAME'])) {
+                $valid_users[] = $row['USER_NAME'];
+            }
+        }
+        return $valid_users;
+    }
+    /**
+     * Retrieves a list of editor user IDs associated with a specific group.
+     *
+     * @param string $group_id The group ID for which to retrieve editor IDs.
+     * @return array Returns an array of user IDs who are editors of the group.
+     */
+    public function getWikiEditors($group_id)
+    {
+        $sql = "SELECT USER_ID FROM GROUP_EDITORS WHERE group_id = ?";
+        $result = $this->db->execute($sql, [$group_id]);
+
+        $editors = [];
+        while ($row = $this->db->fetchArray($result)) {
+            if (isset($row['USER_ID'])) {
+                $editors[] = $row['USER_ID'];
+            }
+        }
+        return $editors;
+    }
+    /**
+     * Retrieves a list of usernames for the editors of a group using user IDs.
+     *
+     * @param string $group_id The group ID to retrieve editor usernames for.
+     * @return array Returns an array of usernames of the group's editors.
+     */
+    public function getWikiEditorsUserNames($group_id)
+    {
+        $sql = "SELECT USER_ID FROM GROUP_EDITORS WHERE group_id = ?";
+        $result = $this->db->execute($sql, [$group_id]);
+
+        $user_ids = [];
+        while ($row = $this->db->fetchArray($result)) {
+            if (isset($row['USER_ID'])) {
+                $user_ids[] = $row['USER_ID'];
+            }
+        }
+        if (empty($user_ids)) {
+            return [];
+        }
+        $placeholders = implode(',', array_fill(0, count($user_ids), '?'));
+        $user_sql = "SELECT USER_NAME FROM USERS WHERE USER_ID IN ($placeholders)";
+        $user_result = $this->db->execute($user_sql, $user_ids);
+        $usernames = [];
+        while ($user_row = $this->db->fetchArray($user_result)) {
+            if (isset($user_row['USER_NAME'])) {
+                $usernames[] = $user_row['USER_NAME'];
+            }
+        }
+        return $usernames;
+    }
+    /**
+     * Looks up the user IDs of editors based on their usernames.
+     *
+     * @param array $editor_list Array of editor usernames to look up.
+     * @return array Returns an array of user IDs for provided editor names.
+     */
+    public function wikiEditorIdLookup($editor_list)
+    {
+        $editors = [];
+        foreach ($editor_list as $editor_name) {
+            $sql = "SELECT USER_ID FROM USERS WHERE USER_NAME = ?";
+            $result = $this->db->execute($sql, [$editor_name]);
+            if ($result && $row = $this->db->fetchArray($result)) {
+                $editor_id = $row['USER_ID'];
+                if ($editor_id) {
+                    $editors[] = $editor_id;
+                }
+            }
+        }
+        return $editors;
+    }
+    /**
+     * Looks up the usernames of editors based on their user IDs.
+     *
+     * @param array $editors Array of editor user IDs to look up.
+     * @return array Returns an array of usernames for the provided user IDs.
+     */
+    public function wikiEditorUsernameLookup($editors)
+    {
+        $editor_names = [];
+        foreach ($editors as $editor_id) {
+            $sql = "SELECT USER_NAME FROM USERS WHERE USER_ID = ?";
+            $result = $this->db->execute($sql, [$editor_id]);
+            if ($result && $row = $this->db->fetchArray($result)) {
+                $editor_name = $row['USER_NAME'];
+                if ($editor_name) {
+                    $editor_names[] = $editor_name;
+                }
+            }
+        }
+        return $editor_names;
+    }
+    /**
+     * Updates the group editor list for a specified group by adding new editors.
+     * Old editors are removed before the update.
+     *
+     * @param string $group_id The group ID to update editor list.
+     * @param array $editors Array of editor usernames to update in the group.
+     * @return string Returns the status message for the update operation.
+     */
+    public function updateWikiEditors($group_id, $editors)
+    {
+        $sql = "DELETE FROM GROUP_EDITORS WHERE group_id = ?";
+        $result = $this->db->execute($sql, [$group_id]);
+        if (!$result) {
+            return L\tl('social_component_upload_error');
+        }
+        if (empty($editors)) {
+            return L\tl('social_component_group_updated');
+        }
+        $placeholders = str_repeat('?,', count($editors) - 1) . '?';
+        $get_user_sql = "SELECT USER_ID, USER_NAME FROM USERS " +
+                        "WHERE USER_NAME IN ($placeholders)";
+        $result = $this->db->execute($get_user_sql, $editors);
+        if (!$result) {
+            return L\tl('social_component_upload_error');
+        }
+        $userMap = [];
+        while ($row = $this->db->fetchArray($result)) {
+            $userMap[$row['USER_NAME']] = $row['USER_ID'];
+        }
+        foreach ($editors as $editor) {
+            if (!isset($userMap[$editor])) {
+                return L\tl('social_component_upload_error');
+            }
+        }
+        $insert_sql = "INSERT INTO GROUP_EDITORS (group_id, user_id) VALUES (?, ?)";
+        foreach ($editors as $editor) {
+            $insert_result = $this->db->execute(
+                $insert_sql,
+                [$group_id, $userMap[$editor]]
+            );
+            if (!$insert_result) {
+                return L\tl('social_component_upload_error');
+            }
+        }
+        return L\tl('social_component_group_updated');
+    }
     /**
      * Return the type of the registration for a group given by $group_id
      * This says who is allowed to register for the group (i.e., is it
@@ -1019,7 +1188,7 @@ class GroupModel extends Model implements MediaConstants
         if ($post_time == 0) {
             $post_time = time();
         }
-        if($this->isGroupEncrypted($parent_group_id)) {
+        if ($this->isGroupEncrypted($parent_group_id)) {
             $key = $this->getGroupKey($parent_group_id);
             $title = $this->decrypt($title, $key);
             $description = $this->decrypt($description, $key);
@@ -1203,10 +1372,10 @@ class GroupModel extends Model implements MediaConstants
             $flag_count = $this->encryptFlag(strval($flag_count), $key);
         } else {
             $flag_count++;
-            if($flag_count > C\MODERATION_FLAG_THRESHOLD) {
+            if ($flag_count > C\MODERATION_FLAG_THRESHOLD) {
                 return false;
             }
-            if($flag_count === $threshold) {
+            if ($flag_count === $threshold) {
                 $this->addGroupItemModeration(0, C\MODERATION_GROUP_ID,
                     $result['USER_ID'], $result['TITLE'],$result['DESCRIPTION'],
                     C\MODERATION_FLAGGED, $post_id, $group_id,
@@ -1364,7 +1533,7 @@ class GroupModel extends Model implements MediaConstants
     public function deleteFlaggedPost($post_id, $message)
     {
          $parent_group_id = $this->getParentGroupId($post_id);
-         if($this->isGroupEncrypted($parent_group_id)) {
+         if ($this->isGroupEncrypted($parent_group_id)) {
             $key = $this->getGroupKey($parent_group_id);
             $description = $this->encrypt($description, $key);
          }
@@ -3921,7 +4090,7 @@ EOD;
             $file_size = strlen($data);
             $vcs->headPutContents("$folder/$file_name", $data, $timestamp);
         }
-        $this->makeThumbStripExif($file_name, $folder, $thumb_folder,
+        $this->makeThumbStripExif ($file_name, $folder, $thumb_folder,
             $mime_type);
         if (C\nsdefined('FFMPEG') && in_array($mime_type, [
             'video/mp4', 'video/webm', 'video/ogg', 'video/avi',
@@ -4051,7 +4220,7 @@ EOD;
      * @param string $mime_type the mime type of the file
      * @return bool whether a thumb was made or not
      */
-    function makeThumbStripExif($file_name, $folder, $thumb_folder,
+    function makeThumbStripExif ($file_name, $folder, $thumb_folder,
         $mime_type = "")
     {
         if ($mime_type == "") {
@@ -4584,7 +4753,7 @@ EOD;
             } else if ($thumb_folder && !$resource['is_dir'] &&
                 time() < $time + C\PAGE_TIMEOUT/2) {
                 $resource['has_thumb'] =
-                    $this->makeThumbStripExif($name, $folder, $thumb_folder);
+                    $this->makeThumbStripExif ($name, $folder, $thumb_folder);
             }
             if ($resource['is_writable'] && ($might_have_animated_thumb &&
                 !$resource['has_animated_thumb'])
@@ -4818,4 +4987,4 @@ EOD;
         }
         return $bots;
     }
-}
+}
\ No newline at end of file
diff --git a/src/models/ProfileModel.php b/src/models/ProfileModel.php
index 29dcd141c..de642d4eb 100755
--- a/src/models/ProfileModel.php
+++ b/src/models/ProfileModel.php
@@ -262,6 +262,12 @@ class ProfileModel extends Model
                 MEMBER_ACCESS $integer, VOTE_ACCESS $integer DEFAULT ".
                 C\NON_VOTING_GROUP . ", POST_LIFETIME $integer DEFAULT ".
                 C\FOREVER . ", ENCRYPTION $integer DEFAULT 0)",
+            "GROUP_EDITORS" => "CREATE TABLE GROUP_EDITORS (
+                id $integer AUTO_INCREMENT PRIMARY KEY,
+                group_id $integer NOT NULL,
+                user_id $integer NOT NULL,
+                FOREIGN KEY (group_id) REFERENCES SOCIAL_GROUPS(GROUP_ID),
+                FOREIGN KEY (user_id) REFERENCES USERS(USER_ID))",
             /* NOTE: We are not using singular name GROUP for SOCIAL_GROUPS as
                GROUP is a reserved SQL keyword and the table used to be
                called GROUPS until Mysql reserved that word too
diff --git a/src/views/elements/GroupbarElement.php b/src/views/elements/GroupbarElement.php
index f3db87797..fa9557c8e 100644
--- a/src/views/elements/GroupbarElement.php
+++ b/src/views/elements/GroupbarElement.php
@@ -238,6 +238,7 @@ class GroupbarElement extends Element
         $token_string = ($logged_in) ? C\CSRF_TOKEN . "=" . $data[C\CSRF_TOKEN]
             : "";
         $can_edit = $logged_in && !empty($data["CAN_EDIT"]);
+
         $wiki_base_url = htmlentities(B\wikiUrl(
             $data['PAGE_NAME'], true, $data['CONTROLLER'],
             $data["GROUP"]["GROUP_ID"])) . $token_string;
diff --git a/src/views/elements/ManagegroupsElement.php b/src/views/elements/ManagegroupsElement.php
index 254d81423..be91cdec6 100755
--- a/src/views/elements/ManagegroupsElement.php
+++ b/src/views/elements/ManagegroupsElement.php
@@ -265,6 +265,16 @@ class ManagegroupsElement extends Element
                     $data["POST_LIFETIMES"],
                     $data['CURRENT_GROUP']['post_lifetime']);
                 ?></td></tr>
+        <tr>
+            <th class="table-label">
+                <label for="wiki-editors">
+                    <?= tl('managegroups_element_wikieditors') ?>
+                </label>:
+            </th>
+            <td>
+                <input type="text" id="wiki-editors" name="edit_wiki_users"
+                       maxlength="<?= C\SHORT_TITLE_LEN ?>"
+                       value="<?= isset($data['edit_wiki_usernames']) &&
+                                is_array($data['edit_wiki_usernames']) ?
+                                implode(', ', $data['edit_wiki_usernames']) :
+                                htmlspecialchars($data['edit_wiki_usernames']) ?>"
+                       class="narrow-field">
+            </td>
+        </tr>
         <tr><th class="table-label"><label for="encryption"><?=
             tl('managegroups_element_encryption')?></label>:</th>
             <?php
@@ -608,6 +618,9 @@ class ManagegroupsElement extends Element
         <tr><th class="table-label"><?=
             tl('managegroups_element_post_lifetime')?>:</th>
             <td><?=$data["POST_LIFETIMES"][$group['post_lifetime']] ?></td></tr>
+        <tr><th class="table-label"><?=
+            tl('managegroups_element_wikieditors') ?>:</th>
+            <td><?= $group['name'] ?></td></tr>
         <tr><th class="table-label"><label for="encryption"><?=
             tl('managegroups_element_encryption')?>:</th>
             <td><?= ($group['encryption'] == 1) ?
diff --git a/src/views/helpers/GrouplistHelper.php b/src/views/helpers/GrouplistHelper.php
index 170d0ec87..ddc3157db 100644
--- a/src/views/helpers/GrouplistHelper.php
+++ b/src/views/helpers/GrouplistHelper.php
@@ -113,6 +113,7 @@ class GrouplistHelper extends Helper
                 ($group['REGISTER_TYPE'] >= C\LOW_JOIN_FEE ||
                 in_array($group['REGISTER_TYPE'],
                 [C\INVITE_ONLY_JOIN, C\REQUEST_JOIN]));
+
             if ($is_owner && !in_array("cannot_delete_groups", $modifiers)) {
                 $icon_helper->renderLink(
                     $delete_url . "group_id={$group['GROUP_ID']}", "delete",
diff --git a/tests/ManyUserExperiment.php b/tests/ManyUserExperiment.php
index 27f017337..22237b8dc 100644
--- a/tests/ManyUserExperiment.php
+++ b/tests/ManyUserExperiment.php
@@ -80,7 +80,7 @@ for ($i = 0; $i < C\ME_NUM_USERS; $i++) {
     $personal_group_name = C\PERSONAL_GROUP_PREFIX . $id;
     if ($group_model->getGroupId($personal_group_name) < 0) {
         $group_model->addGroup($personal_group_name,
-            $id, C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+            $id, ["User$i"], C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
             C\NON_VOTING_GROUP, C\FOREVER, 0);
     }
     $user_ids[$i] = $id;
@@ -89,7 +89,7 @@ for ($i = 0; $i < C\ME_NUM_USERS; $i++) {
 $group_ids = [];
 for ($i = 0; $i < C\ME_NUM_GROUPS; $i++) {
     echo "Creating Group $i\n";
-    $group_ids[$i] = $group_model->addGroup("Group$i", $user_ids[$i],
+    $group_ids[$i] = $group_model->addGroup("Group$i", $user_ids[$i], ["User$i"],
         C\PUBLIC_JOIN, C\GROUP_READ_WIKI);
 }
 // add lots of users to groups (everyone belongs to at least group 1)
--
2.39.2 (Apple Git-143)

