/** * Exports member-list for a Stud.IP-lecture. * * This function gets the data of the members of a lecture and writes it into $data_object. * It calls output_data afterwards. * * @access public * @param string $inst_id Stud.IP-inst_id for export * @param string $ex_sem_id allows to choose which lecture is to be exported */ function export_teilis($inst_id, $ex_sem_id = "no") { global $range_id, $xml_file, $o_mode, $xml_names_person, $xml_groupnames_person, $xml_names_studiengaenge, $xml_groupnames_studiengaenge, $object_counter, $filter, $SEM_CLASS, $SEM_TYPE, $SessSemName; if ($filter == 'status') { $query = "SELECT statusgruppe_id, name\n FROM statusgruppen\n WHERE range_id = ?\n ORDER BY position ASC"; $statement = DBManager::get()->prepare($query); $statement->execute(array($ex_sem_id)); $gruppe = $statement->fetchGrouped(PDO::FETCH_COLUMN); $gruppe['no'] = _('keiner Funktion oder Gruppe zugeordnet'); } else { if (!in_array($filter, words('awaiting claiming'))) { if (!$SEM_CLASS[$SEM_TYPE[$SessSemName['art_num']]['class']]['workgroup_mode']) { $gruppe = array('dozent' => _('Lehrende'), 'tutor' => _('Tutor/-innen'), 'autor' => _('Studierende'), 'user' => _('Leser/-innen'), 'accepted' => _('Vorläufig akzeptierte Personen')); } else { $gruppe = array('dozent' => _('Leitung'), 'tutor' => _('Mitglieder'), 'autor' => _('Autor/-innen'), 'user' => _('Leser/-innen'), 'accepted' => _('Vorläufig akzeptierte Personen')); } } else { $gruppe[$filter] = _('Anmeldeliste'); } } $data_object .= xml_open_tag($xml_groupnames_person['group']); while (list($key1, $val1) = each($gruppe)) { $parameters = array(); if ($filter == 'status') { // Gruppierung nach Statusgruppen / Funktionen if ($key1 == 'no') { $query = "SELECT ui.*, aum.*, su.*, FROM_UNIXTIME(su.mkdate) AS registration_date,\n GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge\n FROM seminar_user AS su\n LEFT JOIN auth_user_md5 AS aum USING (user_id)\n LEFT JOIN user_info AS ui USING (user_id)\n LEFT JOIN user_studiengang USING (user_id)\n LEFT JOIN studiengaenge AS sg USING(studiengang_id)\n LEFT JOIN abschluss AS a USING (abschluss_id)\n WHERE seminar_id = :seminar_id\n GROUP BY aum.user_id\n ORDER BY Nachname"; $parameters[':seminar_id'] = $ex_sem_id; } else { $query = "SELECT DISTINCT ui.*, aum.*, su.*, FROM_UNIXTIME(su.mkdate) AS registration_date,\n GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge\n FROM statusgruppe_user\n LEFT JOIN seminar_user AS su USING (user_id)\n LEFT JOIN auth_user_md5 AS aum USING (user_id)\n LEFT JOIN user_info AS ui USING (user_id)\n LEFT JOIN user_studiengang USING(user_id)\n LEFT JOIN studiengaenge AS sg USING(studiengang_id)\n LEFT JOIN abschluss AS a USING (abschluss_id)\n WHERE statusgruppe_id = :statusgruppe_id AND seminar_id = :seminar_id\n GROUP BY aum.user_id\n ORDER BY Nachname"; $parameters[':seminar_id'] = $ex_sem_id; $parameters[':statusgruppe_id'] = $key1; } } else { if ($key1 == 'accepted') { $query = "SELECT ui.*, aum.*, asu.comment,\n FROM_UNIXTIME(asu.mkdate) AS registration_date,\n GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge\n FROM admission_seminar_user AS asu\n LEFT JOIN user_info AS ui USING (user_id)\n LEFT JOIN auth_user_md5 AS aum USING (user_id)\n LEFT JOIN user_studiengang USING (user_id)\n LEFT JOIN studiengaenge AS sg ON (user_studiengang.studiengang_id = sg.studiengang_id)\n LEFT JOIN abschluss AS a USING (abschluss_id)\n WHERE seminar_id = :seminar_id AND asu.status = 'accepted'\n GROUP BY aum.user_id\n ORDER BY Nachname"; $parameters[':seminar_id'] = $ex_sem_id; } elseif ($key1 == 'awaiting') { $query = "SELECT ui.*, aum.*, asu.comment,\n asu.position AS admission_position,\n GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge\n FROM admission_seminar_user AS asu\n LEFT JOIN user_info AS ui USING(user_id)\n LEFT JOIN auth_user_md5 AS aum USING(user_id)\n LEFT JOIN user_studiengang USING(user_id)\n LEFT JOIN studiengaenge AS sg ON (user_studiengang.studiengang_id = sg.studiengang_id)\n LEFT JOIN abschluss AS a USING (abschluss_id)\n WHERE asu.seminar_id = :seminar_id AND asu.status != 'accepted'\n GROUP BY aum.user_id ORDER BY position"; $parameters[':seminar_id'] = $ex_sem_id; } elseif ($key1 == 'claiming') { $cs = CourseSet::getSetForCourse($ex_sem_id); if (is_object($cs) && !$cs->hasAlgorithmRun()) { $parameters[':users'] = array_keys(AdmissionPriority::getPrioritiesByCourse($cs->getId(), $ex_sem_id)); } else { $parameters[':users'] = array(); } $query = "SELECT ui.*, aum.*, '' as comment,\n 0 AS admission_position,\n GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge\n FROM auth_user_md5 AS aum\n INNER JOIN user_info AS ui USING(user_id)\n LEFT JOIN user_studiengang USING(user_id)\n LEFT JOIN studiengaenge AS sg ON (user_studiengang.studiengang_id = sg.studiengang_id)\n LEFT JOIN abschluss AS a USING (abschluss_id)\n WHERE aum.user_id IN (:users)\n GROUP BY aum.user_id ORDER BY Nachname"; } else { $query = "SELECT ui.*, aum.*, su.*, FROM_UNIXTIME(su.mkdate) AS registration_date,\n GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, us.semester) SEPARATOR '; ') AS nutzer_studiengaenge\n FROM seminar_user AS su\n LEFT JOIN auth_user_md5 AS aum USING ( user_id )\n LEFT JOIN user_info AS ui USING ( user_id )\n LEFT JOIN user_studiengang AS us USING(user_id)\n LEFT JOIN studiengaenge AS sg USING (studiengang_id)\n LEFT JOIN abschluss AS a USING (abschluss_id)\n WHERE seminar_id = :seminar_id AND su.status = :status\n GROUP BY aum.user_id\n ORDER BY " . ($key1 == 'dozent' ? 'position, ' : '') . "Nachname"; $parameters[':seminar_id'] = $ex_sem_id; $parameters[':status'] = $key1; } } $statement = DBManager::get()->prepare($query); $statement->execute($parameters); $data = $statement->fetchAll(PDO::FETCH_ASSOC); $data_object_tmp = ''; $object_counter_tmp = $object_counter; if (count($data) > 0) { $data_object_tmp .= xml_open_tag($xml_groupnames_person['subgroup1'], $val1); foreach ($data as $row) { // Nur Personen ausgeben, die entweder einer Gruppe angehoeren // oder zur Veranstaltung gehoeren und noch nicht ausgegeben wurden. if ($key1 != 'no' || $person_out[$row['user_id']] != true) { $object_counter += 1; $data_object_tmp .= xml_open_tag($xml_groupnames_person["object"], $row['username']); reset($xml_names_person); while (list($key, $val) = each($xml_names_person)) { if ($val == '') { $val = $key; } if ($row[$key] != '') { $data_object_tmp .= xml_tag($val, $row[$key]); } } // freie Datenfelder ausgeben $data_object_tmp .= export_datafields($row['user_id'], $xml_groupnames_person['childgroup1'], $xml_groupnames_person['childobject1'], 'user'); $data_object_tmp .= xml_close_tag($xml_groupnames_person['object']); $person_out[$row['user_id']] = true; } } $data_object_tmp .= xml_close_tag($xml_groupnames_person['subgroup1']); if ($object_counter_tmp != $object_counter) { $data_object .= $data_object_tmp; } } } $data_object .= xml_close_tag($xml_groupnames_person['group']); if (!in_array($filter, words('status awaiting accepted'))) { $query = "SELECT CONCAT_WS(',', studiengaenge.name, abschluss.name) AS name, COUNT(*) AS c\n FROM seminar_user\n INNER JOIN user_studiengang USING (user_id)\n LEFT JOIN studiengaenge USING (studiengang_id)\n LEFT JOIN abschluss USING (abschluss_id)\n WHERE seminar_id = ?\n GROUP BY name"; $statement = DBManager::get()->prepare($query); $statement->execute(array($ex_sem_id)); $studiengang_count = $statement->fetchGrouped(PDO::FETCH_COLUMN); if (count($studiengang_count) > 0) { $data_object .= xml_open_tag($xml_groupnames_studiengaenge["group"]); for ($i = 0; $i < count($studiengang_count); $i += 1) { // TODO: Is this really neccessary? while (list($key, $val) = each($studiengang_count)) { $data_object .= xml_open_tag($xml_groupnames_studiengaenge['object']); $data_object .= xml_tag($xml_names_studiengaenge['name'], $key); $data_object .= xml_tag($xml_names_studiengaenge['count'], $val); $data_object .= xml_close_tag($xml_groupnames_studiengaenge['object']); } } $data_object .= xml_close_tag($xml_groupnames_studiengaenge['group']); } } output_data($data_object, $o_mode); }
/** * Lock or unlock courses */ public function set_locked_action() { $admission_locked = Request::getArray('admission_locked'); $all_courses = Request::getArray('all_sem'); $course_set_id = CourseSet::getGlobalLockedAdmissionSetId(); foreach ($all_courses as $course_id) { $set = CourseSet::getSetForCourse($course_id); if (!is_null($set)) { if (!$set->hasAdmissionRule('LockedAdmission')) { continue; } if ($set->hasAdmissionRule('LockedAdmission') && !isset($admission_locked[$course_id])) { if (CourseSet::removeCourseFromSet($set->getId(), $course_id)) { $log_msg = _('Veranstaltung wurde entsperrt'); } } } if (is_null($set) && isset($admission_locked[$course_id])) { if (CourseSet::addCourseToSet($course_set_id, $course_id)) { $log_msg = sprintf(_('Veranstaltung wurde gesperrt, set_id: %s'), $course_set_id); } } if ($log_msg) { StudipLog::log('SEM_CHANGED_ACCESS', $course_id, NULL, $log_msg); } } PageLayout::postMessage(MessageBox::success(_('Die gewünschten Änderungen wurden ausgeführt!'))); $this->redirect('admin/courses/index'); }
function buildCourseset($course, $grouped) { $db = DBManager::get(); $cs = new CourseSet(); $rule = new ParticipantRestrictedAdmission(); // Loszeitpunkt übernehmen. $rule->setDistributionTime($course['admission_type'] == 1 ? $course['admission_endtime'] : 0); $cs->addAdmissionRule($rule); // Beschränkung 1 aus n, falls erforderlich if ($grouped) { $rule = new LimitedAdmission(); $rule->setMaxNumber(1); $cs->addAdmissionRule($rule); } // Falls Anmeldezeitraum eingestellt, diesen übernehmen. if ($course['admission_starttime'] != -1 || $course['admission_endtime_sem'] != -1) { $rule = new TimedAdmission(); if ($course['admission_starttime'] != -1) { $rule->setStartTime($course['admission_starttime']); } if ($course['admission_endtime_sem'] != -1) { $rule->setEndTime($course['admission_endtime_sem']); } $cs->addAdmissionRule($rule); } // Studiengänge eintragen $stmt = $db->prepare('SELECT studiengang_id FROM admission_seminar_studiengang WHERE seminar_id = ?'); $stmt->execute(array($course['seminar_id'])); $subjects = $stmt->fetchAll(PDO::FETCH_COLUMN); if (!in_array('all', $subjects) && $subjects) { $rule = new ConditionalAdmission(); foreach ($subjects as $subject) { $condition = new UserFilter(); $subject_field = new SubjectCondition(); $subject_field->setCompareOperator('='); $subject_field->setValue($subject); $condition->addField($subject_field); $rule->addCondition($condition); } $cs->addAdmissionRule($rule); } return $cs; }
/** * Distribute seats for several courses in a course set using the given * user priorities. * * @param CourseSet $courseSet The course set containing the courses * that seats shall be distributed for. * @see CourseSet */ private function distributeByPriorities($courseSet) { Log::DEBUG('start seat distribution for course set: ' . $courseSet->getId()); $limited_admission = $courseSet->getAdmissionRule('LimitedAdmission'); //all users with their priorities $claiming_users = AdmissionPriority::getPriorities($courseSet->getId()); //all users which have bonus/malus $factored_users = $courseSet->getUserFactorList(); //all users with their max number of courses $max_seats_users = array_combine(array_keys($claiming_users), array_map(function ($u) use($limited_admission) { return $limited_admission->getMaxNumberForUser($u); }, array_keys($claiming_users))); //unlucky users get a bonus for the next round $bonus_users = array(); //users / courses für later waitlist distribution $waiting_users = array(); //number of already distributed seats for users $distributed_users = array(); $prio_mapper = function ($users, $course_id) use($claiming_users) { $mapper = function ($u) use($course_id) { return isset($u[$course_id]) ? $u[$course_id] : null; }; return array_filter(array_map($mapper, array_intersect_key($claiming_users, array_flip($users)))); }; //sort courses by highest count of prio 1 applicants $stats = AdmissionPriority::getPrioritiesStats($courseSet->getId()); $courses = array_map(function ($a) { return $a['h']; }, $stats); arsort($courses, SORT_NUMERIC); $max_prio = AdmissionPriority::getPrioritiesMax($courseSet->getId()); //count already manually distributed places $distributed_users = $this->countParticipatingUsers(array_keys($courses), array_keys($claiming_users)); Log::DEBUG('already distributed users: ' . print_r($distributed_users, 1)); //walk through all prios with all courses foreach (range(1, $max_prio) as $current_prio) { foreach (array_keys($courses) as $course_id) { $current_claiming = array(); $course = Course::find($course_id); $free_seats = $course->getFreeSeats(); //find users with current prio for this course, if they still need a place foreach ($claiming_users as $user_id => $prio_courses) { if ($prio_courses[$course_id] == $current_prio && $distributed_users[$user_id] < $max_seats_users[$user_id]) { //exclude participants if (!$course->getParticipantStatus($user_id)) { $current_claiming[$user_id] = 1; if (isset($factored_users[$user_id])) { $current_claiming[$user_id] *= $factored_users[$user_id]; } } else { Log::DEBUG(sprintf('user %s is already %s in course %s, ignoring', $user_id, $course->getParticipantStatus($user_id), $course->id)); } } } //give maximum bonus to users which were unlucky before foreach (array_keys($current_claiming) as $user_id) { if ($bonus_users[$user_id] > 0) { $current_claiming[$user_id] = $bonus_users[$user_id] * count($current_claiming) + 1; $bonus_users[$user_id]--; } } Log::DEBUG(sprintf('distribute %s seats on %s claiming with prio %s in course %s', $free_seats, count($current_claiming), $current_prio, $course->id)); Log::DEBUG('users to distribute: ' . print_r($current_claiming, 1)); $current_claiming = $this->rollTheDice($current_claiming); Log::DEBUG('the die is cast: ' . print_r($current_claiming, 1)); $chosen_ones = array_slice(array_keys($current_claiming), 0, $free_seats); Log::DEBUG('chosen ones: ' . print_r($chosen_ones, 1)); $this->addUsersToCourse($chosen_ones, $course, $prio_mapper($chosen_ones, $course->id)); foreach ($chosen_ones as $one) { $distributed_users[$one]++; } if ($free_seats < count($current_claiming)) { $remaining_ones = array_slice(array_keys($current_claiming), $free_seats); foreach ($remaining_ones as $one) { $bonus_users[$one]++; $waiting_users[$current_prio][$course_id][] = $one; } } } } //distribute to waitlists if applicable Log::DEBUG('waiting list: ' . print_r($waiting_users, 1)); foreach ($waiting_users as $current_prio => $current_prio_waiting_courses) { foreach ($current_prio_waiting_courses as $course_id => $users) { $users = array_filter($users, function ($user_id) use($distributed_users, $max_seats_users) { return $distributed_users[$user_id] < $max_seats_users[$user_id]; }); $course = Course::find($course_id); Log::DEBUG(sprintf('distribute waitlist of %s with prio %s in course %s', count($users), $current_prio, $course->id)); if (!$course->admission_disable_waitlist) { if ($course->admission_waitlist_max) { $free_seats_waitlist = $course->admission_waitlist_max - $course->getNumWaiting(); $free_seats_waitlist = $free_seats_waitlist < 0 ? 0 : $free_seats_waitlist; } else { $free_seats_waitlist = count($users); } $waiting_list_ones = array_slice($users, 0, $free_seats_waitlist); Log::DEBUG('waiting list ones: ' . print_r($waiting_list_ones, 1)); $this->addUsersToWaitlist($waiting_list_ones, $course, $prio_mapper($waiting_list_ones, $course->id)); foreach ($waiting_list_ones as $one) { $distributed_users[$one]++; } } else { $free_seats_waitlist = 0; } if ($free_seats_waitlist < count($users)) { $remaining_ones = array_slice($users, $free_seats_waitlist); Log::DEBUG('remaining ones: ' . print_r($remaining_ones, 1)); $this->notifyRemainingUsers($remaining_ones, $course, $prio_mapper($remaining_ones, $course->id)); } } } }
/** * returns courseset object for this course * * @return CourseSet courseset object or null */ public function getCourseSet() { if ($this->course_set === null) { $this->course_set = CourseSet::getSetForCourse($this->id); if ($this->course_set === null) { $this->course_set = false; } } return $this->course_set ?: null; }
/** * Lets the user compose a message and send it. */ public function write_action() { PageLayout::setTitle(_("Neue Nachricht schreiben")); //collect possible default adressees $this->to = array(); $this->default_message = new Message(); if (Request::username("rec_uname")) { $user = new MessageUser(); $user->setData(array('user_id' => get_userid(Request::username("rec_uname")), 'snd_rec' => "rec")); $this->default_message->receivers[] = $user; } if (Request::getArray("rec_uname")) { foreach (Request::usernameArray("rec_uname") as $username) { $user = new MessageUser(); $user->setData(array('user_id' => get_userid($username), 'snd_rec' => "rec")); $this->default_message->receivers[] = $user; } } if (Request::option("group_id")) { $this->default_message->receivers = array(); $group = Statusgruppen::find(Request::option("group_id")); if ($group['range_id'] === $GLOBALS['user']->id || $GLOBALS['perm']->have_studip_perm("autor", $group['range_id'])) { foreach ($group->members as $member) { $user = new MessageUser(); $user->setData(array('user_id' => $member['user_id'], 'snd_rec' => "rec")); $this->default_message->receivers[] = $user; } } } if (Request::get('inst_id') && $GLOBALS['perm']->have_perm('admin')) { $query = "SELECT user_id FROM user_inst WHERE Institut_id = ? AND inst_perms != 'user'"; $this->default_message->receivers = DBManager::get()->fetchAll($query, array(Request::option('inst_id')), 'MessageUser::build'); } if (Request::get("filter") && Request::option("course_id")) { $course = new Course(Request::option('course_id')); if ($GLOBALS['perm']->have_studip_perm("tutor", Request::option('course_id')) || $course->getSemClass()['studygroup_mode']) { $this->default_message->receivers = array(); if (Request::get("filter") === 'claiming') { $cs = CourseSet::getSetForCourse(Request::option("course_id")); if (is_object($cs) && !$cs->hasAlgorithmRun()) { foreach (AdmissionPriority::getPrioritiesByCourse($cs->getId(), Request::option("course_id")) as $user_id => $p) { $this->default_message->receivers[] = MessageUser::build(array('user_id' => $user_id, 'snd_rec' => 'rec')); } } } else { $params = array(Request::option('course_id'), Request::option('who')); switch (Request::get("filter")) { case 'send_sms_to_all': $query = "SELECT b.user_id,'rec' as snd_rec FROM seminar_user a, auth_user_md5 b WHERE a.Seminar_id = ? AND a.user_id = b.user_id AND a.status = ? ORDER BY Nachname, Vorname"; break; case 'all': $query = "SELECT user_id,'rec' as snd_rec FROM seminar_user LEFT JOIN auth_user_md5 USING(user_id) WHERE Seminar_id = ? ORDER BY Nachname, Vorname"; break; case 'prelim': $query = "SELECT user_id,'rec' as snd_rec FROM admission_seminar_user LEFT JOIN auth_user_md5 USING(user_id) WHERE seminar_id = ? AND status='accepted' ORDER BY Nachname, Vorname"; break; case 'awaiting': $query = "SELECT user_id,'rec' as snd_rec FROM admission_seminar_user LEFT JOIN auth_user_md5 USING(user_id) WHERE seminar_id = ? AND status='awaiting' ORDER BY Nachname, Vorname"; break; case 'inst_status': $query = "SELECT b.user_id,'rec' as snd_rec FROM user_inst a, auth_user_md5 b WHERE a.Institut_id = ? AND a.user_id = b.user_id AND a.inst_perms = ? ORDER BY Nachname, Vorname"; break; } $this->default_message->receivers = DBManager::get()->fetchAll($query, $params, 'MessageUser::build'); } } } if (Request::option('prof_id') && Request::option('deg_id') && $GLOBALS['perm']->have_perm('root')) { $query = "SELECT DISTINCT user_id,'rec' as snd_rec\n FROM user_studiengang\n WHERE studiengang_id = ? AND abschluss_id = ?"; $this->default_message->receivers = DBManager::get()->fetchAll($query, array(Request::option('prof_id'), Request::option('deg_id')), 'MessageUser::build'); } if (Request::option('sd_id') && $GLOBALS['perm']->have_perm('root')) { $query = "SELECT DISTINCT user_id,'rec' as snd_rec\n FROM user_studiengang\n WHERE abschluss_id = ?"; $this->default_message->receivers = DBManager::get()->fetchAll($query, array(Request::option('sd_id')), 'MessageUser::build'); } if (Request::option('sp_id') && $GLOBALS['perm']->have_perm('root')) { $query = "SELECT DISTINCT user_id,'rec' as snd_rec\n FROM user_studiengang\n WHERE studiengang_id = ?"; $this->default_message->receivers = DBManager::get()->fetchAll($query, array(Request::option('sp_id')), 'MessageUser::build'); } if (!$this->default_message->receivers->count() && is_array($_SESSION['sms_data']['p_rec'])) { $this->default_message->receivers = DBManager::get()->fetchAll("SELECT user_id,'rec' as snd_rec FROM auth_user_md5 WHERE username IN(?) ORDER BY Nachname,Vorname", array($_SESSION['sms_data']['p_rec']), 'MessageUser::build'); unset($_SESSION['sms_data']); } if (Request::option("answer_to")) { $this->default_message->receivers = array(); $old_message = new Message(Request::option("answer_to")); if (!$old_message->permissionToRead()) { throw new AccessDeniedException("Message is not for you."); } if (!Request::get('forward')) { if (Request::option("quote") === $old_message->getId()) { if (Studip\Markup::isHtml($old_message['message'])) { $this->default_message['message'] = "<div>[quote]\n" . $old_message['message'] . "\n[/quote]</div>"; } else { $this->default_message['message'] = "[quote]\n" . $old_message['message'] . "\n[/quote]"; } } $this->default_message['subject'] = substr($old_message['subject'], 0, 4) === "RE: " ? $old_message['subject'] : "RE: " . $old_message['subject']; $user = new MessageUser(); $user->setData(array('user_id' => $old_message['autor_id'], 'snd_rec' => "rec")); $this->default_message->receivers[] = $user; $this->answer_to = $old_message->id; } else { $messagesubject = 'FWD: ' . $old_message['subject']; $message = _("-_-_ Weitergeleitete Nachricht _-_-"); $message .= "\n" . _("Betreff") . ": " . $old_message['subject']; $message .= "\n" . _("Datum") . ": " . strftime('%x %X', $old_message['mkdate']); $message .= "\n" . _("Von") . ": " . get_fullname($old_message['autor_id']); $num_recipients = $old_message->getNumRecipients(); if ($GLOBALS['user']->id == $old_message->autor_id) { $message .= "\n" . _("An") . ": " . ($num_recipients == 1 ? _('Eine Person') : sprintf(_('%s Personen'), $num_recipients)); } else { $message .= "\n" . _("An") . ": " . $GLOBALS['user']->getFullname() . ($num_recipients > 1 ? ' ' . sprintf(_('(und %d weitere)'), $num_recipients) : ''); } $message .= "\n\n"; if (Studip\Markup::isHtml($old_message['message'])) { $message = '<div>' . htmlReady($message, false, true) . '</div>' . $old_message['message']; } else { $message .= $old_message['message']; } if (count($old_message->attachments)) { Request::set('message_id', $old_message->getNewId()); foreach ($old_message->attachments as $attachment) { $attachment->range_id = 'provisional'; $attachment->seminar_id = $GLOBALS['user']->id; $attachment->autor_host = $_SERVER['REMOTE_ADDR']; $attachment->user_id = $GLOBALS['user']->id; $attachment->description = Request::option('message_id'); $new_attachment = $attachment->toArray(array('range_id', 'user_id', 'seminar_id', 'name', 'description', 'filename', 'filesize')); $new_attachment = StudipDocument::createWithFile(get_upload_file_path($attachment->getId()), $new_attachment); $this->default_attachments[] = array('icon' => GetFileIcon(getFileExtension($new_attachment['filename']))->asImg(['class' => "text-bottom"]), 'name' => $new_attachment['filename'], 'document_id' => $new_attachment->id, 'size' => relsize($new_attachment['filesize'], false)); } } $this->default_message['subject'] = $messagesubject; $this->default_message['message'] = $message; } } if (Request::get("default_body")) { $this->default_message['message'] = Request::get("default_body"); } if (Request::get("default_subject")) { $this->default_message['subject'] = Request::get("default_subject"); } $settings = UserConfig::get($GLOBALS['user']->id)->MESSAGING_SETTINGS; $this->mailforwarding = Request::get('emailrequest') ? true : $settings['request_mail_forward']; if (trim($settings['sms_sig'])) { if (Studip\Markup::isHtml($this->default_message['message']) || Studip\Markup::isHtml($settings['sms_sig'])) { if (!Studip\Markup::isHtml($this->default_message['message'])) { $this->default_message['message'] = '<div>' . nl2br($this->default_message['message']) . '</div>'; } $this->default_message['message'] .= '<br><br>--<br>'; if (Studip\Markup::isHtml($settings['sms_sig'])) { $this->default_message['message'] .= $settings['sms_sig']; } else { $this->default_message['message'] .= formatReady($settings['sms_sig']); } } else { $this->default_message['message'] .= "\n\n--\n" . $settings['sms_sig']; } } NotificationCenter::postNotification("DefaultMessageForComposerCreated", $this->default_message); }
/** * Imports a line of the table into the Stud.IP database if the check returns no errors. * @param array $line : array of fields * @return array : array('found' => true|false, 'errors' => "Error message", 'pk' => "primary key") */ public function importLine($line) { $plugin = $this->getPlugin(); $classname = $this['import_type']; if (!$classname) { return array(); } $data = $this->getMappedData($line); $pk = $this->getPrimaryKey($data); //Last chance to quit: $error = $this->checkLine($line, $data, $pk); $output = array(); $object = new $classname($pk); if (!$object->isNew()) { $output['found'] = true; $output['pk'] = $pk; foreach ((array) $this['tabledata']['ignoreonupdate'] as $fieldname) { unset($data[$fieldname]); } } else { $output['found'] = false; } foreach ($data as $fieldname => $value) { if ($value !== false && in_array($fieldname, $this->getTargetFields())) { $object[$fieldname] = $value; if ($classname === "User" && $fieldname === "password") { $object[$fieldname] = UserManagement::getPwdHasher()->HashPassword($value); } } } if (method_exists($object, "getFullName")) { $error['name'] = $output['name'] = $object->getFullName(); } elseif ($object->isField("name")) { $error['name'] = $output['name'] = $object['name']; } elseif ($object->isField("title")) { $error['name'] = $output['name'] = $object['title']; } if ($error && $error['errors']) { //exit here to have the name of the object in the log return $error; } if ($plugin) { $plugin->beforeUpdate($object, $line, $data); } $object->store(); $output['pk'] = (array) $object->getId(); //Dynamic special fields: switch ($classname) { case "Course": //fleximport_dozenten foreach ($data['fleximport_dozenten'] as $dozent_id) { $seminar = new Seminar($object->getId()); $seminar->addMember($dozent_id, 'dozent'); } //fleximport_related_institutes if (!$data['fleximport_related_institutes']) { $data['fleximport_related_institutes'] = array($object['institut_id']); } else { if (!in_array($object['institut_id'], $data['fleximport_related_institutes'])) { $data['fleximport_related_institutes'][] = $object['institut_id']; } } foreach ($data['fleximport_related_institutes'] as $institut_id) { $insert = DBManager::get()->prepare("\n INSERT IGNORE INTO seminar_inst\n SET seminar_id = :seminar_id,\n institut_id = :institut_id\n "); $insert->execute(array('seminar_id' => $object->getId(), 'institut_id' => $institut_id)); } if ($this['tabledata']['simplematching']["fleximport_course_userdomains"]['column'] || in_array("fleximport_course_userdomains", $this->fieldsToBeDynamicallyMapped())) { $statement = DBManager::get()->prepare("\n SELECT userdomain_id\n FROM seminar_userdomains\n WHERE seminar_id = ?\n "); $statement->execute(array($object->getId())); $olddomains = $statement->fetchAll(PDO::FETCH_COLUMN, 0); foreach (array_diff($data['fleximport_user_inst'], $olddomains) as $to_add) { $domain = new UserDomain($to_add); $domain->addSeminar($object->getId()); } foreach (array_diff($olddomains, $data['fleximport_user_inst']) as $to_remove) { $domain = new UserDomain($to_remove); $domain->removeSeminar($object->getId()); } } break; case "User": if ($this['tabledata']['simplematching']["fleximport_user_inst"]['column'] || in_array("fleximport_user_inst", $this->fieldsToBeDynamicallyMapped())) { if ($object['perms'] !== "root") { foreach ($data['fleximport_user_inst'] as $institut_id) { $member = new InstituteMember(array($object->getId(), $institut_id)); $member['inst_perms'] = $object['perms']; $member->store(); } } } if ($this['tabledata']['simplematching']["fleximport_userdomains"]['column'] || in_array("fleximport_userdomains", $this->fieldsToBeDynamicallyMapped())) { $olddomains = UserDomain::getUserDomainsForUser($object->getId()); foreach ($olddomains as $olddomain) { if (!in_array($olddomain->getID(), (array) $data['fleximport_userdomains'])) { $olddomain->removeUser($object->getId()); } } foreach ($data['fleximport_userdomains'] as $userdomain) { $domain = new UserDomain($userdomain); $domain->addUser($object->getId()); } AutoInsert::instance()->saveUser($object->getId()); foreach ($data['fleximport_userdomains'] as $domain_id) { if (!in_array($domain_id, $olddomains)) { $welcome = FleximportConfig::get("USERDOMAIN_WELCOME_" . $domain_id); if ($welcome) { foreach ($object->toArray() as $field => $value) { $welcome = str_replace("{{" . $field . "}}", $value, $welcome); } foreach ($line as $field => $value) { $welcome = str_replace("{{" . $field . "}}", $value, $welcome); } if (strpos($welcome, "\n") === false) { $subject = _("Willkommen!"); } else { $subject = strstr($welcome, "\n", true); $welcome = substr($welcome, strpos($welcome, "\n") + 1); } $messaging = new messaging(); $count = $messaging->insert_message($welcome, $object->username, '____%system%____', null, null, null, null, $subject, true, 'normal'); } } } } if ($this['tabledata']['simplematching']["fleximport_expiration_date"]['column'] || in_array("fleximport_expiration_date", $this->fieldsToBeDynamicallyMapped())) { if ($data['fleximport_expiration_date']) { UserConfig::get($object->getId())->store("EXPIRATION_DATE", $data['fleximport_expiration_date']); } else { UserConfig::get($object->getId())->delete("EXPIRATION_DATE"); } } if ($output['found'] === false && $data['fleximport_welcome_message'] !== "none") { $user_language = getUserLanguagePath($object->getId()); setTempLanguage(false, $user_language); if ($data['fleximport_welcome_message'] && FleximportConfig::get($data['fleximport_welcome_message'])) { $message = FleximportConfig::get($data['fleximport_welcome_message']); foreach ($data as $field => $value) { $message = str_replace("{{" . $field . "}}", $value, $message); } foreach ($line as $field => $value) { if (!in_array($field, $data)) { $message = str_replace("{{" . $field . "}}", $value, $message); } } if (strpos($message, "\n") === false) { $subject = dgettext($user_language, "Anmeldung Stud.IP-System"); } else { $subject = strstr($message, "\n", true); $message = substr($message, strpos($message, "\n") + 1); } } else { $Zeit = date("H:i:s, d.m.Y", time()); $this->user_data = array('auth_user_md5.username' => $object['username'], 'auth_user_md5.perms' => $object['perms'], 'auth_user_md5.Vorname' => $object['vorname'], 'auth_user_md5.Nachname' => $object['nachname'], 'auth_user_md5.Email' => $object['email']); $password = $data['password']; //this is the not hashed password in cleartext include "locale/{$user_language}/LC_MAILS/create_mail.inc.php"; $message = $mailbody; } if ($message) { $mail = new StudipMail(); $mail->addRecipient($object['email'], $object->getFullName()); $mail->setSubject($subject); $mail->setBodyText($message); $mail->setBodyHtml(formatReady($message)); if (Config::get()->MAILQUEUE_ENABLE) { MailQueueEntry::add($mail); } else { $mail->send(); } } restoreLanguage(); } break; } //Datafields: $datafields = array(); switch ($classname) { case "Course": $datafields = Datafield::findBySQL("object_type = 'sem'"); break; case "User": $datafields = Datafield::findBySQL("object_type = 'user'"); break; case "CourseMember": $datafields = Datafield::findBySQL("object_type = 'usersemdata'"); break; } foreach ($datafields as $datafield) { $fieldname = $datafield['name']; if (isset($data[$fieldname])) { $entry = new DatafieldEntryModel(array($datafield->getId(), $object->getId(), "")); $entry['content'] = $data[$fieldname]; $entry->store(); } } if ($classname === "Course") { if ($this['tabledata']['simplematching']["fleximport_studyarea"]['column'] || in_array("fleximport_studyarea", $this->fieldsToBeDynamicallyMapped())) { //Studienbereiche: $remove = DBManager::get()->prepare("\n DELETE FROM seminar_sem_tree\n WHERE seminar_id = :seminar_id\n "); $remove->execute(array('seminar_id' => $object->getId())); if ($GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$data['status']]['class']]['bereiche']) { foreach ($data['fleximport_studyarea'] as $sem_tree_id) { $insert = DBManager::get()->prepare("\n INSERT IGNORE INTO seminar_sem_tree\n SET sem_tree_id = :sem_tree_id,\n seminar_id = :seminar_id\n "); $insert->execute(array('sem_tree_id' => $sem_tree_id, 'seminar_id' => $object->getId())); } } } if ($this['tabledata']['simplematching']["fleximport_locked"]['column'] || in_array("fleximport_locked", $this->fieldsToBeDynamicallyMapped())) { //Lock or unlock course if ($data['fleximport_locked']) { CourseSet::addCourseToSet(CourseSet::getGlobalLockedAdmissionSetId(), $object->getId()); } elseif (in_array($data['fleximport_locked'], array("0", 0)) && $data['fleximport_locked'] !== "") { CourseSet::removeCourseFromSet(CourseSet::getGlobalLockedAdmissionSetId(), $object->getId()); } } $folder_exist = DBManager::get()->prepare("\n SELECT 1 FROM folder WHERE range_id = ?\n "); $folder_exist->execute(array($object->getId())); if (!$folder_exist->fetch()) { $insert_folder = DBManager::get()->prepare("\n INSERT IGNORE INTO folder\n SET folder_id = MD5(CONCAT(:seminar_id, 'allgemeine_dateien')),\n range_id = :seminar_id,\n user_id = :user_id,\n name = :name,\n description = :description,\n mkdate = UNIX_TIMESTAMP(),\n chdate = UNIX_TIMESTAMP()\n "); $insert_folder->execute(array('seminar_id' => $object->getId(), 'user_id' => $GLOBALS['user']->id, 'name' => _("Allgemeiner Dateiordner"), 'description' => _("Ablage für allgemeine Ordner und Dokumente der Veranstaltung"))); } } if ($plugin && !$object->isNew()) { $plugin->afterUpdate($object, $line); } return $output; }
/** * Gets courses fulfilling the given condition. * * @param String $seminare_condition SQL condition */ function get_courses($seminare_condition) { global $perm, $user; list($institut_id, $all) = explode('_', $this->current_institut_id); // Prepare count statements $query = "SELECT count(*)\n FROM seminar_user\n WHERE seminar_id = ? AND status IN ('user', 'autor')"; $count0_statement = DBManager::get()->prepare($query); $query = "SELECT SUM(status = 'accepted') AS count2,\n SUM(status = 'awaiting') AS count3\n FROM admission_seminar_user\n WHERE seminar_id = ?\n GROUP BY seminar_id"; $count1_statement = DBManager::get()->prepare($query); $parameters = array(); $sql = "SELECT seminare.seminar_id,seminare.Name as course_name,seminare.VeranstaltungsNummer as course_number,\n admission_prelim, admission_turnout,seminar_courseset.set_id\n FROM seminar_courseset\n INNER JOIN courseset_rule csr ON csr.set_id=seminar_courseset.set_id AND csr.type='ParticipantRestrictedAdmission'\n INNER JOIN seminare ON seminar_courseset.seminar_id=seminare.seminar_id\n "; if ($institut_id == 'all' && $perm->have_perm('root')) { $sql .= "WHERE 1 {$seminare_condition} "; } elseif ($all == 'all') { $sql .= "INNER JOIN Institute USING (Institut_id)\n WHERE Institute.fakultaets_id = ? {$seminare_condition}\n "; $parameters[] = $institut_id; } else { $sql .= "WHERE seminare.Institut_id = ? {$seminare_condition}\n "; $parameters[] = $institut_id; } $sql .= "GROUP BY seminare.Seminar_id ORDER BY seminar_courseset.set_id, seminare.Name"; $statement = DBManager::get()->prepare($sql); $statement->execute($parameters); while ($row = $statement->fetch(PDO::FETCH_ASSOC)) { $seminar_id = $row['seminar_id']; $ret[$seminar_id] = $row; $count0_statement->execute(array($seminar_id)); $count = $count0_statement->fetchColumn(); $ret[$seminar_id]['count_teilnehmer'] = $count; $count1_statement->execute(array($seminar_id)); $counts = $count1_statement->fetch(PDO::FETCH_ASSOC); $ret[$seminar_id]['count_prelim'] = (int) $counts['count2']; $ret[$seminar_id]['count_waiting'] = (int) $counts['count3']; $cs = new CourseSet($row['set_id']); $ret[$seminar_id]['cs_name'] = $cs->getName(); $ret[$seminar_id]['distribution_time'] = $cs->getSeatDistributionTime(); if ($ta = $cs->getAdmissionRule('TimedAdmission')) { $ret[$seminar_id]['start_time'] = $ta->getStartTime(); $ret[$seminar_id]['end_time'] = $ta->getEndTime(); } if (!$cs->hasAlgorithmRun()) { $ret[$seminar_id]['count_claiming'] = $cs->getNumApplicants(); } } return $ret; }
/** * Prioritize courses. */ function claim_action() { CSRFProtection::verifyUnsafeRequest(); $user_id = $GLOBALS['user']->id; $courseset = CourseSet::getSetForCourse($this->course_id); if ($courseset->isSeatDistributionEnabled() && !count($courseset->checkAdmission($user_id, $this->course_id))) { if ($limit = $courseset->getAdmissionRule('LimitedAdmission')) { $admission_user_limit = Request::int('admission_user_limit'); if ($admission_user_limit && $admission_user_limit <= $limit->getMaxNumber()) { $limit->setCustomMaxNumber($user_id, $admission_user_limit); } $admission_prio = Request::getArray('admission_prio'); $max_prio = max($admission_prio); $admission_prio = array_map(function ($a) use(&$max_prio) { return $a > 0 ? $a : ++$max_prio; }, $admission_prio); if (count(array_unique($admission_prio)) != count(Request::getArray('admission_prio'))) { PageLayout::postMessage(MessageBox::info(_("Sie dürfen jede Priorität nur einmal auswählen. Überprüfen Sie bitte Ihre Auswahl!"))); } $old_prio_count = AdmissionPriority::unsetAllPrioritiesForUser($courseset->getId(), $user_id); if ($order_up = key(Request::getArray('admission_prio_order_up'))) { $prio_to_move = $admission_prio[$order_up]; $change_with = array_search($prio_to_move - 1, $admission_prio); $admission_prio[$order_up] = $prio_to_move - 1; $admission_prio[$change_with] = $prio_to_move; } if ($order_down = key(Request::getArray('admission_prio_order_down'))) { $prio_to_move = $admission_prio[$order_down]; $change_with = array_search($prio_to_move + 1, $admission_prio); $admission_prio[$order_down] = $prio_to_move + 1; $admission_prio[$change_with] = $prio_to_move; } if ($delete = key(Request::getArray('admission_prio_delete'))) { unset($admission_prio[$delete]); $changed = 1; $admission_prio = array_map(function ($a) { static $c = 1; return $c++; }, $admission_prio); } foreach ($admission_prio as $course_id => $p) { $changed += AdmissionPriority::setPriority($courseset->getId(), $user_id, $course_id, $p); } if ($changed || $old_prio_count && !count($admission_prio)) { if (count(AdmissionPriority::getPrioritiesByUser($courseset->getId(), $user_id))) { PageLayout::postMessage(MessageBox::success(_("Ihre Priorisierung wurde gespeichert."))); } else { PageLayout::postMessage(MessageBox::success(_("Ihre Anmeldung zur Platzvergabe wurde zurückgezogen."))); } } } else { if (Request::int('courseset_claimed')) { if (AdmissionPriority::setPriority($courseset->getId(), $user_id, $this->course_id, 1)) { PageLayout::postMessage(MessageBox::success(_("Ihre Anmeldung zur Platzvergabe wurde gespeichert."))); } } else { if (AdmissionPriority::unsetPriority($courseset->getId(), $user_id, $this->course_id)) { PageLayout::postMessage(MessageBox::success(_("Ihre Anmeldung zur Platzvergabe wurde zurückgezogen."))); } } } } $this->redirect($this->url_for('/apply/' . $this->course_id)); }
function save_courseset_action($cs_id) { $cs = new CourseSet($cs_id); if ($cs->isUserAllowedToEdit($this->user_id)) { $this->instant_course_set_view = true; $response = $this->relay('admission/courseset/save/' . $cs->getId()); $this->body = $response->body; if ($response->headers['Location']) { $this->redirect($response->headers['Location']); } } else { throw new Trails_Exception(403); } }
/** * @param string $sort_status * @param string $order_by * @return SimpleCollection */ function getAdmissionMembers($sort_status = 'autor', $order_by = 'nachname asc') { $cs = CourseSet::getSetForCourse($this->course_id); $claiming = array(); if (is_object($cs) && !$cs->hasAlgorithmRun()) { foreach (AdmissionPriority::getPrioritiesByCourse($cs->getId(), $this->course_id) as $user_id => $p) { $user = User::find($user_id); $data = $user->toArray('user_id username vorname nachname email'); $data['fullname'] = $user->getFullname('full_rev'); $data['position'] = $p; $data['visible'] = 'unknown'; $data['status'] = 'claiming'; $claiming[] = $data; } } $query = "SELECT asu.user_id,username,vorname,nachname,email,status,position,asu.mkdate,asu.visible, asu.comment,\n " . $GLOBALS['_fullname_sql']['full_rev'] . " as fullname\n FROM admission_seminar_user asu INNER JOIN auth_user_md5 USING(user_id)\n INNER JOIN user_info USING(user_id)\n WHERE seminar_id = ? ORDER BY position, nachname ASC"; $st = DBManager::get()->prepare($query); $st->execute(array($this->course_id)); $application_members = SimpleCollection::createFromArray(array_merge($claiming, $st->fetchAll(PDO::FETCH_ASSOC))); $filtered_members = array(); foreach (words('awaiting accepted claiming') as $status) { $filtered_members[$status] = $application_members->findBy('status', $status); if ($status == $sort_status) { $filtered_members[$status]->orderBy($order_by, strpos($order_by, 'nachname') === false ? SORT_NUMERIC : SORT_LOCALE_STRING); } } return $filtered_members; }
public function execute($last_result, $parameters = array()) { $verbose = $parameters['verbose']; $sets = DbManager::get()->fetchFirst("SELECT DISTINCT cr.set_id FROM courseset_rule cr INNER JOIN coursesets USING(set_id)\n WHERE type = 'ParticipantRestrictedAdmission' AND algorithm_run = 0"); if (count($sets)) { if ($verbose) { echo date('r') . ' - Starting seat distribution ' . chr(10); $old_logger = Log::get()->getHandler(); $old_log_level = Log::get()->getLogLevel(); @mkdir($GLOBALS['TMP_PATH'] . '/seat_distribution_logs'); $logfile = $GLOBALS['TMP_PATH'] . '/seat_distribution_logs/' . date('Y-m-d-H-i') . '_seat_distribution.log'; if (is_dir($GLOBALS['TMP_PATH'] . '/seat_distribution_logs')) { Log::get()->setHandler($logfile); Log::get()->setLogLevel(Log::DEBUG); echo 'logging to ' . $logfile . chr(10); } else { echo 'could not create directory ' . $GLOBALS['TMP_PATH'] . '/seat_distribution_logs' . chr(10); } } foreach ($sets as $set_id) { $courseset = new CourseSet($set_id); if ($courseset->isSeatDistributionEnabled() && !$courseset->hasAlgorithmRun() && $courseset->getSeatDistributionTime() < time()) { if ($verbose) { echo ++$i . ' ' . $courseset->getId() . ' : ' . $courseset->getName() . chr(10); $applicants = AdmissionPriority::getPriorities($set_id); $courses = SimpleCollection::createFromArray(Course::findMany($courseset->getCourses()))->toGroupedArray('seminar_id', words('name veranstaltungsnummer')); $captions = array(_("Nachname"), _("Vorname"), _("Nutzername"), _('Nutzer-ID'), _('Veranstaltung-ID'), _("Veranstaltung"), _("Nummer"), _("Priorität")); $data = array(); $users = User::findEachMany(function ($user) use($courses, $applicants, &$data) { $app_courses = $applicants[$user->id]; asort($app_courses); foreach ($app_courses as $course_id => $prio) { $row = array(); $row[] = $user->nachname; $row[] = $user->vorname; $row[] = $user->username; $row[] = $user->id; $row[] = $course_id; $row[] = $courses[$course_id]['name']; $row[] = $courses[$course_id]['veranstaltungsnummer']; $row[] = $prio; $data[] = $row; } }, array_keys($applicants), 'ORDER BY Nachname'); $applicants_file = $GLOBALS['TMP_PATH'] . '/seat_distribution_logs/applicants_' . $set_id . '.csv'; if (array_to_csv($data, $applicants_file, $captions)) { echo 'applicants written to ' . $applicants_file . chr(10); } } $courseset->distributeSeats(); } } if ($verbose) { Log::get()->setHandler($old_logger); Log::get()->setLogLevel($old_log_level); } } else { if ($verbose) { echo date('r') . ' - Nothing to do' . chr(10); } } }