diff --git a/application/_installation/04-create-table-user-groups.sql b/application/_installation/04-create-table-user-groups.sql new file mode 100644 index 0000000..a312cdd --- /dev/null +++ b/application/_installation/04-create-table-user-groups.sql @@ -0,0 +1,15 @@ +CREATE TABLE IF NOT EXISTS `huge`.`user_groups` ( + `group_id` TINYINT(1) NOT NULL COMMENT 'numeric user group id, matches users.user_account_type', + `group_name` VARCHAR(64) COLLATE utf8_unicode_ci NOT NULL COMMENT 'human readable group name', + PRIMARY KEY (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='user groups lookup'; + +INSERT INTO `huge`.`user_groups` (`group_id`, `group_name`) VALUES + (1, 'Gast'), + (2, 'Benutzer'), + (3, 'Gruppe 3'), + (4, 'Gruppe 4'), + (5, 'Gruppe 5'), + (6, 'Gruppe 6'), + (7, 'Admin') +ON DUPLICATE KEY UPDATE `group_name` = VALUES(`group_name`); diff --git a/application/controller/AdminController.php b/application/controller/AdminController.php index 6cd7614..ecb3a9c 100644 --- a/application/controller/AdminController.php +++ b/application/controller/AdminController.php @@ -20,7 +20,9 @@ class AdminController extends Controller public function index() { $this->View->render('admin/index', array( - 'users' => UserModel::getPublicProfilesOfAllUsers()) + 'users' => UserModel::getPublicProfilesOfAllUsers(), + 'groups' => GroupModel::getAllGroups() + ) ); } @@ -32,4 +34,10 @@ class AdminController extends Controller Redirect::to("admin"); } + + public function changeUserGroup() + { + GroupModel::setUserGroup(Request::post('user_id'), Request::post('group_id')); + Redirect::to("admin"); + } } diff --git a/application/controller/DirectoryController.php b/application/controller/DirectoryController.php new file mode 100644 index 0000000..476b462 --- /dev/null +++ b/application/controller/DirectoryController.php @@ -0,0 +1,16 @@ +View->render('directory/index', [ + 'users' => UserModel::getUsersWithGroups() + ]); + } +} diff --git a/application/model/GroupModel.php b/application/model/GroupModel.php new file mode 100644 index 0000000..5d7622e --- /dev/null +++ b/application/model/GroupModel.php @@ -0,0 +1,54 @@ +getConnection(); + $sql = "SELECT group_id, group_name FROM user_groups ORDER BY group_id"; + $query = $database->prepare($sql); + $query->execute(); + return $query->fetchAll(); + } + + public static function getGroupNameById($group_id) + { + $database = DatabaseFactory::getFactory()->getConnection(); + $sql = "SELECT group_name FROM user_groups WHERE group_id = :gid LIMIT 1"; + $query = $database->prepare($sql); + $query->execute(array(':gid' => $group_id)); + $row = $query->fetch(); + return $row ? $row->group_name : null; + } + + public static function setUserGroup($userId, $groupId) + { + if (!is_numeric($userId) || !is_numeric($groupId)) { + return false; + } + + // Do not allow changing own group via admin UI to prevent lockout + if ((int)$userId === (int)Session::get('user_id')) { + Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_CANT_DELETE_SUSPEND_OWN')); + return false; + } + + // Only allow groups that exist in lookup + $database = DatabaseFactory::getFactory()->getConnection(); + $check = $database->prepare("SELECT 1 FROM user_groups WHERE group_id = :gid LIMIT 1"); + $check->execute([':gid' => $groupId]); + if ($check->rowCount() !== 1) { + return false; + } + + $query = $database->prepare("UPDATE users SET user_account_type = :gid WHERE user_id = :uid LIMIT 1"); + $query->execute([':gid' => $groupId, ':uid' => $userId]); + + if ($query->rowCount() === 1) { + Session::add('feedback_positive', 'Benutzergruppe aktualisiert.'); + return true; + } + + return false; + } +} diff --git a/application/model/UserModel.php b/application/model/UserModel.php index 1321eb3..98f4b70 100644 --- a/application/model/UserModel.php +++ b/application/model/UserModel.php @@ -19,7 +19,7 @@ class UserModel { $database = DatabaseFactory::getFactory()->getConnection(); - $sql = "SELECT user_id, user_name, user_email, user_active, user_has_avatar, user_deleted FROM users"; + $sql = "SELECT user_id, user_name, user_email, user_active, user_has_avatar, user_deleted, user_account_type FROM users"; $query = $database->prepare($sql); $query->execute(); @@ -39,11 +39,46 @@ class UserModel $all_users_profiles[$user->user_id]->user_active = $user->user_active; $all_users_profiles[$user->user_id]->user_deleted = $user->user_deleted; $all_users_profiles[$user->user_id]->user_avatar_link = (Config::get('USE_GRAVATAR') ? AvatarModel::getGravatarLinkByEmail($user->user_email) : AvatarModel::getPublicAvatarFilePathOfUser($user->user_has_avatar, $user->user_id)); + $all_users_profiles[$user->user_id]->user_account_type = $user->user_account_type; } return $all_users_profiles; } + /** + * Gets list of users including their group name via user_groups lookup. + * @return array + */ + public static function getUsersWithGroups() + { + $database = DatabaseFactory::getFactory()->getConnection(); + + $sql = "SELECT u.user_id, u.user_name, u.user_email, u.user_active, u.user_has_avatar, u.user_deleted, u.user_account_type, + g.group_name + FROM users u + LEFT JOIN user_groups g ON g.group_id = u.user_account_type"; + $query = $database->prepare($sql); + $query->execute(); + + $result = []; + foreach ($query->fetchAll() as $user) { + array_walk_recursive($user, 'Filter::XSSFilter'); + + $obj = new stdClass(); + $obj->user_id = $user->user_id; + $obj->user_name = $user->user_name; + $obj->user_email = $user->user_email; + $obj->user_active = $user->user_active; + $obj->user_deleted = $user->user_deleted; + $obj->user_account_type = $user->user_account_type; + $obj->group_name = $user->group_name; + $obj->user_avatar_link = (Config::get('USE_GRAVATAR') ? AvatarModel::getGravatarLinkByEmail($user->user_email) : AvatarModel::getPublicAvatarFilePathOfUser($user->user_has_avatar, $user->user_id)); + + $result[] = $obj; + } + return $result; + } + /** * Gets a user's profile data, according to the given $user_id * @param int $user_id The user's id diff --git a/application/view/_templates/header.php b/application/view/_templates/header.php index 5d91151..4a1992a 100644 --- a/application/view/_templates/header.php +++ b/application/view/_templates/header.php @@ -24,6 +24,9 @@