aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/StudygroupModel.php
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:07:19 +0200
committerJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:19:12 +0200
commita3da1483a9e689846179159355badfec8073dbec (patch)
tree770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /lib/classes/StudygroupModel.php
current code from svn, revision 62608
Diffstat (limited to 'lib/classes/StudygroupModel.php')
-rw-r--r--lib/classes/StudygroupModel.php592
1 files changed, 592 insertions, 0 deletions
diff --git a/lib/classes/StudygroupModel.php b/lib/classes/StudygroupModel.php
new file mode 100644
index 0000000..23930c0
--- /dev/null
+++ b/lib/classes/StudygroupModel.php
@@ -0,0 +1,592 @@
+<?php
+# Lifter010: TODO
+/*
+ * studygroup.php - Contains the StudygroupModel class
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author André Klaßen <andre.klassen@elan-ev.de>
+ * @copyright 2009 ELAN e.V.
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category Stud.IP
+ *
+ */
+
+require_once 'lib/messaging.inc.php';
+
+class StudygroupModel
+{
+ /**
+ * retrieves all institues suitbable for an admin wrt global studygroup settings
+ *
+ * @return array institutes
+ */
+ public static function getInstitutes()
+ {
+ $institutes = [];
+
+ // Prepare institutes statement
+ $query = "SELECT Institut_id, Name
+ FROM Institute
+ WHERE fakultaets_id = ? AND fakultaets_id != Institut_id
+ ORDER BY Name";
+ $institute_statement = DBManager::get()->prepare($query);
+
+ // get faculties
+ $query = "SELECT Name, Institut_id, 1 AS is_fak, 'admin' AS inst_perms
+ FROM Institute
+ WHERE Institut_id = fakultaets_id
+ ORDER BY Name";
+ $stmt = DBManager::get()->query($query);
+ while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ $institutes[$data['Institut_id']] = [
+ 'name' => $data['Name'],
+ 'childs' => [],
+ ];
+
+ // institutes for faculties
+ $institute_statement->execute([$data['Institut_id']]);
+ while ($data2 = $institute_statement->fetch(PDO::FETCH_ASSOC)) {
+ $institutes[$data['Institut_id']]['childs'][$data2['Institut_id']] = $data2['Name'];
+ }
+ $institute_statement->closeCursor();
+ }
+
+ return $institutes;
+ }
+
+ /**
+ * allows an user to access a "closed" studygroup
+ *
+ * @param string username
+ * @param string id of a studygroup
+ */
+ public static function accept_user($username, $sem_id)
+ {
+ $query = "SELECT user_id
+ FROM admission_seminar_user AS asu
+ JOIN auth_user_md5 AS au USING (user_id)
+ WHERE au.username = ? AND asu.seminar_id = ?";
+ $statement = DBManager::get()->prepare($query);
+ $statement->execute([$username, $sem_id]);
+ if ($accept_user_id = $statement->fetchColumn()) {
+ CourseMember::create([
+ 'seminar_id' => $sem_id,
+ 'user_id' => $accept_user_id,
+ 'status' => 'autor',
+ 'gruppe' => 8,
+ 'visible' => 'yes',
+ ]);
+
+ AdmissionApplication::deleteBySQL(
+ 'user_id = ? AND seminar_id = ?',
+ [$accept_user_id, $sem_id]
+ );
+
+ // Post equivalent notifications to a regular course
+ $seminar = Seminar::getInstance($sem_id);
+ NotificationCenter::postNotification(
+ 'CourseDidGetMember', $seminar, $accept_user_id
+ );
+ NotificationCenter::postNotification(
+ 'CourseDidChangeMember', $seminar, $accept_user_id
+ );
+ NotificationCenter::postNotification(
+ 'UserDidEnterCourse', $sem_id, $accept_user_id
+ );
+ }
+ }
+
+ /**
+ * denies access to a "closed" studygroup for an user
+ *
+ * @param string username
+ * @param string id of a studygroup
+ *
+ * @return void
+ */
+ public static function deny_user($username, $sem_id)
+ {
+ $user = User::findByUsername($username);
+
+ AdmissionApplication::deleteBySQL(
+ 'user_id = ? AND seminar_id = ?',
+ [$user->id, $sem_id]
+ );
+ }
+
+ /**
+ * promotes an user in a studygroup wrt to a given perm
+ *
+ * @param string username
+ * @param string id of a studygroup
+ * @param string perm
+ *
+ * @return void
+ */
+ public static function promote_user($username, $sem_id, $perm)
+ {
+ $user = User::findByUsername($username);
+
+ $member = CourseMember::find([$sem_id, $user->id]);
+ $member->status = $perm;
+ $member->store();
+ }
+
+ /**
+ * removes a user of a studygroup
+ *
+ * @param string username
+ * @param string id of a studygroup
+ *
+ * @return void
+ */
+ public static function remove_user($username, $sem_id)
+ {
+ $user = User::findByUsername($username);
+
+ CourseMember::deleteBySQL(
+ 'Seminar_id = ? AND user_id = ?',
+ [$sem_id, $user->id]
+ );
+
+ // Post equivalent notifications to a regular course
+ $seminar = Seminar::getInstance($sem_id);
+ NotificationCenter::postNotification('CourseDidChangeMember', $seminar, $user->id);
+ NotificationCenter::postNotification('UserDidLeaveCourse', $sem_id, $user->id);
+ }
+
+ /**
+ * retrieves the count of all studygroups
+ *
+ * @param string $search Search term
+ * @param mixed $closed_groups Display closed groups
+ * @return int count
+ */
+ public static function countGroups($search = null, $closed_groups = null)
+ {
+ $conditions = ['status IN (?)'];
+ $parameters = [studygroup_sem_types()];
+
+ // Only root may see hidden studygroups
+ if (!$GLOBALS['perm']->have_perm('root')) {
+ $conditions[] = 'visible = 1';
+ }
+
+ // Search by name?
+ if (isset($search)) {
+ $conditions[] = "Name LIKE CONCAT('%', ?, '%')";
+ $parameters[] = $search;
+ }
+
+ // Show closed groups
+ if (isset($closed_groups) && !$closed_groups) {
+ $conditions[] = 'admission_prelim = 0';
+ }
+
+ return Course::countBySQL(
+ implode(' AND ', $conditions),
+ $parameters
+ );
+ }
+
+ /**
+ * get all studygroups in a paged manner wrt a stort criteria and a search term
+ *
+ * @param string $sort Sort criteria
+ * @param int $lower_bound Lower bound of the resultset
+ * @param int $elements_per_page Elements per page, if null get the global configuration value
+ * @param string $search Search term
+ * @param mixed $closed_groups Display closed groups
+ * @return array studygroups
+ */
+ public static function getAllGroups($sort = '', $lower_bound = 1, $elements_per_page = null, $search = null, $closed_groups = null)
+ {
+ if (!$elements_per_page) {
+ $elements_per_page = Config::get()->ENTRIES_PER_PAGE;
+ }
+
+ $sql = "SELECT *
+ FROM seminare AS s";
+ $sql_additional = '';
+ $conditions = [];
+ $parameters = [];
+
+ $conditions[] = 's.status IN (?)';
+ $parameters[] = studygroup_sem_types();
+
+ if (!$GLOBALS['perm']->have_perm('root')) {
+ $conditions[] = 's.visible = 1';
+ }
+
+ if (isset($search)) {
+ $conditions[] = "Name LIKE CONCAT('%', ?, '%')";
+ $parameters[] = $search;
+ }
+ if (isset($closed_groups) && !$closed_groups) {
+ $conditions[] = 'admission_prelim = 0';
+ }
+
+ list($sort_by, $sort_order) = explode('_', $sort);
+ $sort_order = $sort_order === 'asc' ? 'ASC' : 'DESC';
+
+ // add here the sortings
+ if ($sort_by === 'name') {
+ $sort_by = 'Name';
+ } elseif ($sort_by === 'founded') {
+ $sort_by = 'mkdate';
+ } elseif ($sort_by === 'member') {
+ $sort_by = 'members';
+
+ $sql = "SELECT s.*, COUNT(su.user_id) AS members
+ FROM seminare AS s
+ LEFT JOIN seminar_user AS su USING (Seminar_id)";
+
+ $sql_additional = 'GROUP BY s.Seminar_id';
+ } elseif ($sort_by === 'founder') {
+ $sort_by = "GROUP_CONCAT(aum.Nachname ORDER BY su.status, su.position, aum.Nachname, aum.Vorname SEPARATOR ',')";
+
+ $sql = "SELECT s.*
+ FROM seminare AS s
+ LEFT JOIN seminar_user AS su ON (s.Seminar_id = su.Seminar_id AND su.status = 'dozent')
+ LEFT JOIN auth_user_md5 AS aum ON (su.user_id = aum.user_id)";
+
+ $sql_additional = 'GROUP BY s.Seminar_id';
+ } elseif ($sort_by === 'ismember') {
+ $sort_by = 'is_member';
+
+ $sql = "SELECT s.*, COUNT(su.user_id) AS is_member
+ FROM seminare AS s
+ LEFT JOIN seminar_user AS su ON s.Seminar_id = su.Seminar_id AND su.user_id = ?";
+ array_unshift($parameters, $GLOBALS['user']->id);
+
+ $sql_additional = 'GROUP BY s.Seminar_id';
+ } elseif ($sort_by == 'access') {
+ $sort_by = 'admission_prelim';
+ } else {
+ throw new Exception('Invalid sort parameter');
+ }
+
+ if (!empty($conditions)) {
+ $sql .= ' WHERE ' . implode(' AND ', $conditions);
+ }
+ $sql .= ' ' . $sql_additional;
+ $sql .= " ORDER BY {$sort_by} {$sort_order}";
+ $sql .= ", name {$sort_order} LIMIT " . (int) $lower_bound . ',' . (int) $elements_per_page;
+
+ $statement = DBManager::get()->prepare($sql);
+ $statement->execute($parameters);
+ $groups = $statement->fetchAll();
+
+ return $groups;
+ }
+
+ /**
+ * returns the count of members for a given studygroup
+ *
+ * @param string id of a studygroup
+ * @return int count
+ */
+ public static function countMembers($semid)
+ {
+ return (int) CourseMember::countBySeminar_id($semid);
+ }
+
+ /**
+ * get founder for a given studgroup
+ *
+ * @param string id of a studygroup
+ * @return array founder
+ */
+ public static function getFounder($semid)
+ {
+ $founder = [];
+ foreach (CourseMember::findByCourseAndStatus($semid, 'dozent') as $user) {
+ $founder[] = [
+ 'user_id' => $user->user_id,
+ 'fullname' => $user->getUserFullname(),
+ 'uname' => $user->username,
+ ];
+ }
+ return $founder;
+ }
+
+ /**
+ * checks whether a user is a member of a studygroup
+ *
+ * @param string id of a user
+ * @param string id of a studygroup
+ * @return boolean membership
+ */
+ public static function isMember($userid, $semid)
+ {
+ return CourseMember::exists([$semid, $userid]);
+ }
+
+ /**
+ * adds a founder to a given studygroup
+ *
+ * @param string username
+ * @param string id of a studygroup
+ */
+ public static function addFounder($username, $sem_id)
+ {
+ $user = User::findByUsername($username);
+
+ $member = new CourseMember([$sem_id, $user->id]);
+ if ($member->isNew()) {
+ $member->status = 'dozent';
+ $member->store();
+ }
+ }
+
+ /**
+ * removes a founder from a given studygroup
+ *
+ * @param string username
+ * @param string id of a studygroup
+ */
+ public static function removeFounder($username, $sem_id)
+ {
+ $user = User::findByUsername($username);
+
+ CourseMember::deleteBySQL(
+ 'Seminar_id = ? AND user_id = ?',
+ [$sem_id, $user->id]
+ );
+ }
+
+ /**
+ * get founders of a given studygroup
+ *
+ * @param string id of a studygroup
+ * @return array founders
+ */
+ public static function getFounders($sem_id)
+ {
+ $query = "SELECT username, perms, {$GLOBALS['_fullname_sql']['full_rev']} AS fullname
+ FROM seminar_user
+ LEFT JOIN auth_user_md5 USING (user_id)
+ LEFT JOIN user_info USING (user_id)
+ WHERE Seminar_id = ? AND status = 'dozent'";
+
+ $stmt = DBManager::get()->prepare($query);
+ $stmt->execute([$sem_id]);
+
+ return $stmt->fetchAll();
+ }
+
+ /**
+ * retrieves all members of a given studygroup in a paged manner
+ *
+ * @param string id of a studygroup
+ * @param int lower bound of the resultset
+ * @param int elements per page, if null get the global configuration value
+ *
+ * @return array members
+ */
+ public static function getMembers($sem_id, $lower_bound = 1, $elements_per_page = null)
+ {
+ if (!$elements_per_page) {
+ $elements_per_page = Config::get()->ENTRIES_PER_PAGE;
+ }
+
+ $query = "SELECT user_id ,username ,perms, seminar_user.status,
+ {$GLOBALS['_fullname_sql']['full_rev']} AS fullname,
+ seminar_user.mkdate
+ FROM seminar_user
+ LEFT JOIN auth_user_md5 USING (user_id)
+ LEFT JOIN user_info USING (user_id)
+ WHERE Seminar_id = ?
+ ORDER BY seminar_user.mkdate ASC, seminar_user.status ASC";
+
+ if ($elements_per_page !== 'all') {
+ $query .= " LIMIT {$lower_bound}, {$elements_per_page}";
+ }
+
+ return DBManager::get()->fetchGrouped($query, [$sem_id]);
+ }
+
+ /**
+ * invites a member to a given studygroup.
+ *
+ * @param string user id
+ * @param string 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]);
+ }
+
+ /**
+ * cancels invitation.
+ *
+ * @param string username
+ * @param string 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)
+ ]);
+ }
+
+ /**
+ * returns invited member of a given studygroup.
+ *
+ * @param string id of a studygroup
+ * @return array invited members
+ */
+ public static function getInvitations($sem_id)
+ {
+ $query = "SELECT username, user_id,
+ {$GLOBALS['_fullname_sql']['full_rev']} AS fullname,
+ studygroup_invitations.mkdate
+ FROM studygroup_invitations
+ 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";
+
+ $stmt = DBManager::get()->prepare($query);
+ $stmt->execute([$sem_id]);
+
+ return $stmt->fetchAll();
+ }
+
+ /**
+ * checks if a user is already invited.
+ *
+ * @param string user id
+ * @param string id of a studygroup
+ * @return array invited members
+ */
+ 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();
+ }
+
+ /**
+ * callback function - used to compare sequences of studygroup statuses
+ *
+ * @param array status a
+ * @param array status b
+ * @return int ordering
+ */
+ public static function compare_status($a, $b)
+ {
+ if ($a['status'] === $b['status']) {
+ return strnatcmp($a['fullname'], $b['fullname']);
+ }
+
+ if ($a['status'] === 'dozent') {
+ if ($b['status'] === 'tutor') {
+ return -1;
+ } elseif ($b['status'] === 'autor') {
+ return -1;
+ }
+ } elseif ($a['status'] === 'tutor') {
+ if ($b['status'] === 'dozent') {
+ return 1;
+ } elseif ($b['status'] === 'autor') {
+ return -1;
+ }
+ } elseif ($a['status'] === 'autor') {
+ if ($b['status'] === 'tutor') {
+ return 1;
+ } elseif ($b['status'] === 'dozent') {
+ return 1;
+ }
+ }
+ }
+
+ /**
+ * Checks for a given seminar_id whether a course is a studygroup
+ *
+ * @param string id of a seminar
+ *
+ * @return array studygroup
+ */
+ public static function isStudygroup($sem_id)
+ {
+ $sql = "SELECT *
+ FROM seminare
+ WHERE Seminar_id = ? AND status IN (?)";
+ $stmt = DBManager::get()->prepare($sql);
+ $stmt->execute([
+ $sem_id,
+ studygroup_sem_types()
+ ]);
+
+ return $stmt->fetch();
+ }
+
+ /**
+ * If a new user applies, an application note to all moderators and founders
+ * of a studygroup will be automatically sent while calling this function.
+ * The note contains the user's name and a direct link to the member page of the studygroup.
+ *
+ * @param string $sem_id id of a seminar / studygroup
+ * @param string $user_id id of the applicant
+ * @return int number of recipients
+ */
+ public static function applicationNotice($sem_id, $user_id)
+ {
+ $sem = new Seminar($sem_id);
+ $dozenten = $sem->getMembers();
+ $tutors = $sem->getMembers('tutor');
+ $recipients = [];
+ $msging = new Messaging();
+
+ foreach (array_merge($dozenten, $tutors) as $uid => $user) {
+ $recipients[] = $user['username'];
+ }
+
+ if (mb_strlen($sem->getName()) > 32) //cut subject if to long
+ $subject = sprintf(_('[Studiengruppe: %s...]'), mb_substr($sem->getName(), 0, 30));
+ else
+ $subject = sprintf(_('[Studiengruppe: %s]'), $sem->getName());
+
+ if (StudygroupModel::isInvited($user_id, $sem_id)) {
+ $subject .= ' ' . _('Einladung akzeptiert');
+ $message = sprintf(
+ _("%s hat die Einladung zur Studiengruppe %s akzeptiert. Klicken Sie auf den untenstehenden Link, um direkt zur Studiengruppe zu gelangen.\n\n [Direkt zur Studiengruppe]%s"),
+ get_fullname($user_id),
+ $sem->getName(),
+ URLHelper::getlink(
+ "{$GLOBALS['ABSOLUTE_URI_STUDIP']}dispatch.php/course/studygroup/members/?cid={$sem->id}",
+ ['cid' => $sem->id]
+ )
+ );
+ } else {
+ $subject .= ' ' . _('Neuer Mitgliedsantrag');
+ $message = sprintf(
+ _("%s möchte der Studiengruppe %s beitreten. Klicken Sie auf den untenstehenden Link, um direkt zur Studiengruppe zu gelangen.\n\n [Direkt zur Studiengruppe]%s"),
+ get_fullname($user_id),
+ $sem->getName(),
+ URLHelper::getlink(
+ "{$GLOBALS['ABSOLUTE_URI_STUDIP']}dispatch.php/course/studygroup/members/?cid={$sem->id}",
+ ['cid' => $sem->id]
+ )
+ );
+ }
+
+ return $msging->insert_message($message, $recipients, '', '', '', '1', '', $subject);
+ }
+}