diff options
| author | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2025-01-30 10:14:19 +0000 |
|---|---|---|
| committer | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2025-01-31 11:51:51 +0100 |
| commit | f78e85e8ddf6b254c95514548b1367b4981aff9e (patch) | |
| tree | fbbe0f2af0419f1688623427e86a2f8f05e5856b | |
| parent | 3ec0cdb446e6b11bac52cddc96c2a27d2069b696 (diff) | |
introduce StudygroupInvitation model and use it as relation for course and user and cleanup the orphaned studygroup invitations, fixes #5195
Closes #5195
Merge request studip/studip!3879
| -rw-r--r-- | app/controllers/course/studygroup.php | 2 | ||||
| -rw-r--r-- | app/views/course/studygroup/members.php | 28 | ||||
| -rw-r--r-- | db/migrations/5.3.28_cleanup_studygroup_invitations.php | 18 | ||||
| -rw-r--r-- | lib/classes/StudygroupModel.php | 51 | ||||
| -rw-r--r-- | lib/models/Course.class.php | 6 | ||||
| -rw-r--r-- | lib/models/StudygroupInvitation.php | 29 | ||||
| -rw-r--r-- | lib/models/User.class.php | 6 |
7 files changed, 107 insertions, 33 deletions
diff --git a/app/controllers/course/studygroup.php b/app/controllers/course/studygroup.php index 5527179..a311991 100644 --- a/app/controllers/course/studygroup.php +++ b/app/controllers/course/studygroup.php @@ -331,7 +331,7 @@ class Course_StudygroupController extends AuthenticatedController $this->autors = $sem->getMembersWithStatus('autor'); $this->accepted = $sem->admission_applicants->findBy('status', 'accepted'); $this->sem_class = $sem->getSemClass(); - $this->invitedMembers = StudygroupModel::getInvitations($id); + $this->invitedMembers = StudygroupInvitation::findBySQL('sem_id = ? ORDER BY mkdate', $id); $this->rechte = $GLOBALS['perm']->have_studip_perm('tutor', $id); $this->page = null; $this->setupMembersSidebar($sem); diff --git a/app/views/course/studygroup/members.php b/app/views/course/studygroup/members.php index 58a3b07..68dae66 100644 --- a/app/views/course/studygroup/members.php +++ b/app/views/course/studygroup/members.php @@ -1,3 +1,19 @@ +<?php +/** + * @var Course_StudygroupController $controller + * @var int $anzahl + * @var int $page + * @var string $sem_id + * @var array $moderators + * @var array $tutors + * @var array $autors + * @var array $accepted + * @var bool $rechte + * @var string $view + * @var array $sem_class + * @var StudygroupInvitation[] $invitedMembers + */ +?> <?= $this->render_partial('course/studygroup/_feedback', compact('anzahl', 'page', 'sem_id')) ?> <? if (count($moderators) > 0): ?> @@ -126,20 +142,20 @@ <? foreach ($invitedMembers as $p): ?> <tr> <td> - <input type="checkbox" name="members[]" value="<?= htmlReady($p['username']) ?>"> + <input type="checkbox" name="members[]" value="<?= htmlReady($p->user->username) ?>"> </td> <td> - <a href="<?= URLHelper::getLink('dispatch.php/profile' , ['username' => $p['username']]) ?>"> - <?= Avatar::getAvatar($p['user_id'])->getImageTag(Avatar::SMALL) ?> + <a href="<?= URLHelper::getLink('dispatch.php/profile' , ['username' => $p->user->username]) ?>"> + <?= Avatar::getAvatar($p->user_id)->getImageTag(Avatar::SMALL) ?> </a> </td> <td> - <a href="<?= URLHelper::getLink('dispatch.php/profile' , ['username' => $p['username']]) ?>"> - <?= htmlReady($p['fullname']) ?> + <a href="<?= URLHelper::getLink('dispatch.php/profile' , ['username' => $p->user->username]) ?>"> + <?= htmlReady($p->user->getFullName()) ?> </a> </td> <td class="actions"> - <a href="<?= $controller->edit_members('cancelInvitation', ['user' => $p['username']]) ?>" data-confirm="<?= _('Wollen Sie die Einladung wirklich löschen?') ?>"> + <a href="<?= $controller->edit_members('cancelInvitation', ['user' => $p->user->username]) ?>" data-confirm="<?= _('Wollen Sie die Einladung wirklich löschen?') ?>"> <?= Icon::create('trash')->asImg(['title' => _('Einladung löschen')]) ?> </a> </td> diff --git a/db/migrations/5.3.28_cleanup_studygroup_invitations.php b/db/migrations/5.3.28_cleanup_studygroup_invitations.php new file mode 100644 index 0000000..9c67224 --- /dev/null +++ b/db/migrations/5.3.28_cleanup_studygroup_invitations.php @@ -0,0 +1,18 @@ +<?php +return new class extends Migration { + public function description() + { + return 'Removes orphaned entries in table "studygroup_invitations"'; + } + + protected function up() + { + $query = "DELETE FROM `studygroup_invitations` + WHERE `user_id` NOT IN ( + SELECT `user_id` FROM `auth_user_md5` + ) OR `sem_id` NOT IN ( + SELECT `Seminar_id` FROM `seminare` + )"; + DBManager::get()->exec($query); + } +}; diff --git a/lib/classes/StudygroupModel.php b/lib/classes/StudygroupModel.php index 051ada7..eea8a7f 100644 --- a/lib/classes/StudygroupModel.php +++ b/lib/classes/StudygroupModel.php @@ -413,32 +413,33 @@ class StudygroupModel /** * invites a member to a given studygroup. * - * @param string user id - * @param string id of a studygroup + * @param string $user_id + * @param string $sem_id id of a studygroup */ public static function inviteMember($user_id, $sem_id) { - $query = "REPLACE INTO studygroup_invitations (sem_id, user_id, mkdate) - VALUES (?, ?, UNIX_TIMESTAMP())"; - $stmt = DBManager::get()->prepare($query); - $stmt->execute([$sem_id, $user_id]); + $invitation = new StudygroupInvitation([$sem_id, $user_id]); + $invitation->mkdate = time(); + $invitation->store(); } /** * cancels invitation. * - * @param string username - * @param string id of a studygroup + * @param string $username + * @param string $sem_id id of a studygroup */ public static function cancelInvitation($username, $sem_id) { - $query = "DELETE FROM studygroup_invitations - WHERE sem_id = ? AND user_id = ?"; - $statement = DBManager::get()->prepare($query); - $statement->execute([ - $sem_id, - get_userid($username) - ]); + $user = User::findOneByUsername($username); + if (!$user) { + return; + } + + StudygroupInvitation::deleteBySQL( + 'sem_id = ? AND user_id = ?', + [$sem_id, $user->id] + ); } /** @@ -446,6 +447,7 @@ class StudygroupModel * * @param string id of a studygroup * @return array invited members + * @deprecated Will be removed in Stud.IP 6.2 */ public static function getInvitations($sem_id) { @@ -456,7 +458,7 @@ class StudygroupModel LEFT JOIN auth_user_md5 USING (user_id) LEFT JOIN user_info USING (user_id) WHERE studygroup_invitations.sem_id = ? - ORDER BY studygroup_invitations.mkdate ASC"; + ORDER BY studygroup_invitations.mkdate"; $stmt = DBManager::get()->prepare($query); $stmt->execute([$sem_id]); @@ -467,19 +469,16 @@ class StudygroupModel /** * checks if a user is already invited. * - * @param string user id - * @param string id of a studygroup - * @return array invited members + * @param string $user_id + * @param string $sem_id id of a studygroup + * @return bool */ public static function isInvited($user_id, $sem_id) { - $query = "SELECT 1 - FROM studygroup_invitations - WHERE user_id = ? AND sem_id = ?"; - $stmt = DBManager::get()->prepare($query); - $stmt->execute([$user_id, $sem_id]); - - return (bool) $stmt->fetchColumn(); + return (bool) StudygroupInvitation::countBySql( + 'sem_id = ? AND user_id = ?', + [$sem_id, $user_id] + ); } /** diff --git a/lib/models/Course.class.php b/lib/models/Course.class.php index e4510c4..e36af55 100644 --- a/lib/models/Course.class.php +++ b/lib/models/Course.class.php @@ -227,6 +227,12 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe 'on_delete' => 'delete', ]; + $config['has_many']['studygroup_invitations'] = [ + 'class_name' => StudygroupInvitation::class, + 'assoc_foreign_key' => 'sem_id', + 'on_delete' => 'delete', + ]; + $config['default_values']['lesezugriff'] = 1; $config['default_values']['schreibzugriff'] = 1; $config['default_values']['duration_time'] = 0; diff --git a/lib/models/StudygroupInvitation.php b/lib/models/StudygroupInvitation.php new file mode 100644 index 0000000..c7d09dc --- /dev/null +++ b/lib/models/StudygroupInvitation.php @@ -0,0 +1,29 @@ +<?php + +/** + * @property array $id + * @property string $sem_id + * @property string $user_id + * @property int $mkdate + * + * @property User $user + * @property Course $course + */ +final class StudygroupInvitation extends SimpleORMap +{ + protected static function configure($config = []) + { + $config['db_table'] = 'studygroup_invitations'; + + $config['belongs_to']['course'] = [ + 'class_name' => Course::class, + 'foreign_key' => 'sem_id', + ]; + $config['belongs_to']['user'] = [ + 'class_name' => User::class, + 'foreign_key' => 'user_id', + ]; + + parent::configure($config); + } +} diff --git a/lib/models/User.class.php b/lib/models/User.class.php index eb0793f..a4475c7 100644 --- a/lib/models/User.class.php +++ b/lib/models/User.class.php @@ -224,6 +224,12 @@ class User extends AuthUserMd5 implements Range, PrivacyObject, Studip\Calendar\ 'on_delete' => 'delete', ]; + $config['has_many']['studygroup_invitations'] = [ + 'class_name' => StudygroupInvitation::class, + 'assoc_foreign_key' => 'user_id', + 'on_delete' => 'delete', + ]; + $config['additional_fields']['config']['get'] = function ($user) { return UserConfig::get($user->id); }; |
