aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/SemBrowse.php
diff options
context:
space:
mode:
authorPhilipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de>2024-09-24 10:53:31 +0200
committerPhilipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de>2024-09-24 10:53:31 +0200
commit4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch)
tree5c07151ae61276d334e88f6309c30d439a85c12e /lib/classes/SemBrowse.php
parentda0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff)
parent97a188592c679890a25c37ab78463add76a52ff7 (diff)
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/classes/SemBrowse.php')
-rw-r--r--lib/classes/SemBrowse.php1264
1 files changed, 1264 insertions, 0 deletions
diff --git a/lib/classes/SemBrowse.php b/lib/classes/SemBrowse.php
new file mode 100644
index 0000000..536b7e3
--- /dev/null
+++ b/lib/classes/SemBrowse.php
@@ -0,0 +1,1264 @@
+<?php
+# Lifter002: TODO
+# Lifter005: TODO
+# Lifter007: TODO
+# Lifter003: TODO
+# Lifter010: TODO
+
+require_once 'lib/dates.inc.php';
+
+class SemBrowse {
+
+ public $sem_browse_data;
+ public $persistent_fields = [
+ 'level', 'cmd', 'start_item_id', 'show_class', 'group_by',
+ 'search_result', 'default_sem', 'sem_status', 'show_entries', 'sset'
+ ];
+ public $search_obj;
+ public $sem_tree;
+ public $range_tree;
+ public $show_result;
+ public $sem_number;
+ public $group_by_fields = [];
+ public $target_url;
+ public $target_id;
+ public $classes_show_module;
+ public $classes_show_class;
+
+ public function __construct($sem_browse_data_init = [])
+ {
+
+ $this->group_by_fields =
+ [
+ [
+ 'name' => _('Semester'),
+ 'group_field' => 'sem_number'
+ ],
+ [
+ 'name' => _('Bereich'),
+ 'group_field' => 'bereich'
+ ],
+ [
+ 'name' => _('Lehrende'),
+ 'group_field' => 'fullname',
+ 'unique_field' => 'username'
+ ],
+ [
+ 'name' => _('Typ'),
+ 'group_field' => 'status'
+ ],
+ [
+ 'name' => _('Einrichtung'),
+ 'group_field' => 'Institut',
+ 'unique_field' => 'Institut_id'
+ ]
+ ];
+
+ if (empty($_SESSION['sem_browse_data'])) {
+ $_SESSION['sem_browse_data'] = $sem_browse_data_init;
+ }
+ $this->sem_browse_data =& $_SESSION['sem_browse_data'];
+
+ $level_change = Request::option('start_item_id') || Request::submitted('search_sem_sem_change');
+
+ for ($i = 0; $i < count($this->persistent_fields); ++$i){
+ $persistend_field = $this->persistent_fields[$i];
+ if (Request::get($persistend_field) != null) {
+ $this->sem_browse_data[$persistend_field] = Request::option($persistend_field);
+ }
+ }
+ $this->search_obj = new StudipSemSearch(
+ 'search_sem',
+ false,
+ !(is_object($GLOBALS['perm']) && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)),
+ $this->sem_browse_data['show_class'] ?? null
+ );
+
+
+ if (Request::get($this->search_obj->form_name . '_scope_choose')) {
+ $this->sem_browse_data['start_item_id'] =
+ Request::option($this->search_obj->form_name . '_scope_choose');
+ }
+ if (Request::get($this->search_obj->form_name . '_range_choose')) {
+ $this->sem_browse_data['start_item_id'] =
+ Request::option($this->search_obj->form_name . '_range_choose');
+ }
+ if (Request::get($this->search_obj->form_name . '_sem')) {
+ $this->sem_browse_data['default_sem'] =
+ Request::option($this->search_obj->form_name . '_sem');
+ }
+
+ if (
+ Request::get('keep_result_set')
+ || !empty($this->sem_browse_data['sset'])
+ || (!empty($this->sem_browse_data['search_result']) && !empty($this->sem_browse_data['show_entries']))
+ ) {
+ $this->show_result = true;
+ }
+
+ if (isset($this->sem_browse_data['cmd']) && $this->sem_browse_data['cmd'] === 'xts') {
+ if ($this->search_obj->new_search_button_clicked) {
+ $this->show_result = false;
+ $this->sem_browse_data['sset'] = false;
+ $this->sem_browse_data['search_result'] = [];
+ }
+ }
+
+ if (!isset($this->sem_browse_data['default_sem'])) {
+ $this->sem_number[0] = 0;
+ } elseif ($this->sem_browse_data['default_sem'] != 'all') {
+ $this->sem_number[0] = intval($this->sem_browse_data['default_sem']);
+ } else {
+ $this->sem_number = false;
+ }
+
+ $sem_status = (!empty($this->sem_browse_data['sem_status']) && is_array($this->sem_browse_data['sem_status'])) ? $this->sem_browse_data['sem_status'] : false;
+
+ if ($this->sem_browse_data['level'] == 'vv') {
+ if (empty($this->sem_browse_data['start_item_id'])) {
+ $this->sem_browse_data['start_item_id'] = 'root';
+ }
+ $this->sem_tree = new StudipSemTreeViewSimple(
+ $this->sem_browse_data['start_item_id'],
+ $this->sem_number, $sem_status,
+ !(is_object($GLOBALS['perm'])
+ && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)));
+ if (Request::option('cmd') != 'show_sem_range'
+ && $level_change
+ && !$this->search_obj->search_button_clicked ) {
+ $this->get_sem_range($this->sem_browse_data['start_item_id'], false);
+ $this->show_result = true;
+ $this->sem_browse_data['show_entries'] = 'level';
+ $this->sem_browse_data['sset'] = false;
+ }
+ if ($this->search_obj->sem_change_button_clicked) {
+ $this->get_sem_range($this->sem_browse_data['start_item_id'],
+ ($this->sem_browse_data['show_entries'] == 'sublevels'));
+ $this->show_result = true;
+ }
+ }
+
+ if ($this->sem_browse_data['level'] == 'ev'){
+ if (!$this->sem_browse_data['start_item_id']) {
+ $this->sem_browse_data['start_item_id'] = 'root';
+ }
+ $this->range_tree = new StudipSemRangeTreeViewSimple(
+ $this->sem_browse_data['start_item_id'],
+ $this->sem_number,
+ $sem_status,
+ !(is_object($GLOBALS['perm'])
+ && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)));
+ if (Request::option('cmd') != 'show_sem_range_tree'
+ && $level_change
+ && !$this->search_obj->search_button_clicked ) {
+ $this->get_sem_range_tree($this->sem_browse_data['start_item_id'], false);
+ $this->show_result = true;
+ $this->sem_browse_data['show_entries'] = 'level';
+ $this->sem_browse_data['sset'] = false;
+ }
+ if ($this->search_obj->sem_change_button_clicked) {
+ $this->get_sem_range_tree($this->sem_browse_data['start_item_id'],
+ ($this->sem_browse_data['show_entries'] == 'sublevels'));
+ $this->show_result = true;
+ }
+ }
+
+ if ($this->search_obj->search_button_clicked
+ && !$this->search_obj->new_search_button_clicked) {
+ $this->search_obj->override_sem = $this->sem_number;
+ $this->search_obj->doSearch();
+ if ($this->search_obj->found_rows) {
+ $this->sem_browse_data['search_result'] = array_flip($this->search_obj->search_result->getRows('seminar_id'));
+ } else {
+ $this->sem_browse_data['search_result'] = [];
+ }
+ $this->show_result = true;
+ $this->sem_browse_data['show_entries'] = false;
+ $this->sem_browse_data['sset'] = Request::get($this->search_obj->form_name . "_quick_search_parameter");
+ }
+
+
+ if (Request::option('cmd') == 'show_sem_range') {
+ $tmp = explode('_', Request::option('item_id'));
+ $this->get_sem_range($tmp[0], isset($tmp[1]));
+ $this->show_result = true;
+ $this->sem_browse_data['show_entries'] = (isset($tmp[1])) ? 'sublevels' : 'level';
+ $this->sem_browse_data['sset'] = false;
+ }
+
+ if (Request::option('cmd') == 'show_sem_range_tree') {
+ $tmp = explode('_', Request::option('item_id'));
+ $this->get_sem_range_tree($tmp[0],isset($tmp[1]));
+ $this->show_result = true;
+ $this->sem_browse_data['show_entries'] = (isset($tmp[1])) ? 'sublevels' : 'level';
+ $this->sem_browse_data['sset'] = false;
+ }
+
+ if (Request::option('do_show_class')
+ && count($this->sem_browse_data['sem_status'])) {
+ $this->get_sem_class();
+ }
+
+ }
+
+ /**
+ * Returns whether the search for modules has to be displayed.
+ *
+ * @return boolean True if search for modules has to be displayed.
+ */
+ private function showModules()
+ {
+ if ($this->sem_browse_data['show_class'] == 'all') {
+ return true;
+ }
+ if (!is_array($this->classes_show_module)) {
+ $this->classes_show_class = [];
+ foreach ($GLOBALS['SEM_CLASS'] as $sem_class_key => $sem_class){
+ if ($sem_class['module']) {
+ $this->classes_show_module[] = $sem_class_key;
+ }
+ }
+ }
+ return in_array($this->sem_browse_data['show_class'], $this->classes_show_class);
+ }
+
+ public function show_class()
+ {
+ if ($this->sem_browse_data['show_class'] == 'all') {
+ return true;
+ }
+ if (!is_array($this->classes_show_class)) {
+ $this->classes_show_class = [];
+ foreach ($GLOBALS['SEM_CLASS'] as $sem_class_key => $sem_class) {
+ if ($sem_class['bereiche']) {
+ $this->classes_show_class[] = $sem_class_key;
+ }
+ }
+ }
+ return in_array($this->sem_browse_data['show_class'], $this->classes_show_class);
+ }
+
+ public function get_sem_class()
+ {
+ $query = "SELECT `Seminar_id`
+ FROM `seminare`
+ WHERE `status` IN (?)";
+
+ $show_all = is_object($GLOBALS['perm'])
+ && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM);
+ if (!$show_all) {
+ $query .= ' AND visible = 1';
+ }
+
+ $sem_ids = DBManager::get()->fetchFirst($query);
+ if (is_array($sem_ids)) {
+ $this->sem_browse_data['search_result'] = array_flip($sem_ids);
+ }
+ $this->sem_browse_data['sset'] = true;
+ $this->show_result = true;
+ }
+
+ public function get_sem_range($item_id, $with_kids)
+ {
+ if (!is_object($this->sem_tree)) {
+ $sem_status = (is_array($this->sem_browse_data['sem_status'])) ? $this->sem_browse_data['sem_status'] : false;
+ $this->sem_tree = new StudipSemTreeViewSimple(
+ $this->sem_browse_data['start_item_id'],
+ $this->sem_number,
+ $sem_status,
+ !(is_object($GLOBALS['perm'])
+ && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)));
+ }
+ $sem_ids = $this->sem_tree->tree->getSemIds($item_id,$with_kids);
+ if (is_array($sem_ids)) {
+ $this->sem_browse_data['search_result'] = array_flip($sem_ids);
+ } else {
+ $this->sem_browse_data['search_result'] = [];
+ }
+ }
+
+ public function get_sem_range_tree($item_id, $with_kids)
+ {
+ $range_object = RangeTreeObject::GetInstance($item_id);
+ if ($with_kids) {
+ $inst_ids = $range_object->getAllObjectKids();
+ }
+ $inst_ids[] = $range_object->item_data['studip_object_id'];
+ $db_view = DbView::getView('sem_tree');
+ $db_view->params[0] = $inst_ids;
+ $db_view->params[1] = (is_object($GLOBALS['perm']) && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) ? '' : ' AND c.visible=1';
+ $db_view->params[1] .= !empty($this->sem_browse_data['sem_status']) && is_array($this->sem_browse_data['sem_status'])
+ ? " AND c.status IN('" . join("','", $this->sem_browse_data['sem_status']) ."')"
+ : '';
+ $db_view->params[2] = is_array($this->sem_number)
+ ? ' HAVING sem_number IN ('
+ . join(',', $this->sem_number)
+ . ') OR (sem_number <= '
+ . $this->sem_number[count($this->sem_number) - 1]
+ . ' AND (sem_number_end >= '
+ . $this->sem_number[count($this->sem_number) - 1]
+ . ' OR sem_number_end = -1)) '
+ : '';
+ $db_snap = new DbSnapshot($db_view->get_query('view:SEM_INST_GET_SEM'));
+ if ($db_snap->numRows) {
+ $sem_ids = $db_snap->getRows('Seminar_id');
+ $this->sem_browse_data['search_result'] = array_flip($sem_ids);
+ } else {
+ $this->sem_browse_data['search_result'] = [];
+ }
+ }
+
+ /**
+ * Prints the quicksearch form.
+ */
+ private function printQuickSearch()
+ {
+ if ($this->sem_browse_data['level'] === 'vv') {
+ $this->search_obj->sem_tree =& $this->sem_tree->tree;
+ if ($this->sem_tree->start_item_id !== 'root') {
+ $this->search_obj->search_scopes[] = $this->sem_tree->start_item_id;
+ }
+ } elseif ($this->sem_browse_data['level'] === 'ev') {
+ $this->search_obj->range_tree =& $this->range_tree->tree;
+ if ($this->range_tree->start_item_id !== 'root'){
+ $this->search_obj->search_ranges[] = $this->range_tree->start_item_id;
+ }
+ }
+
+ $template = $GLOBALS['template_factory']->open('sembrowse/quick-search.php');
+ $template->search_obj = $this->search_obj;
+ $template->sem_browse_data = $this->sem_browse_data;
+ $template->sem_tree = $this->sem_tree;
+ $template->range_tree = $this->range_tree;
+ $template->quicksearch = $this->getQuicksearch();
+
+ echo $template->render();
+ }
+
+ private function getQuicksearch()
+ {
+ $quicksearch = QuickSearch::get(
+ $this->search_obj->form_name . '_quick_search',
+ new SeminarSearch()
+ );
+
+ $quicksearch->setAttributes([
+ 'aria-label' => _('Suchbegriff'),
+ 'autofocus' => '',
+ ]);
+ $quicksearch->fireJSFunctionOnSelect('selectSem');
+ $quicksearch->noSelectbox();
+ $quicksearch->defaultValue(
+ $this->sem_browse_data['sset'] ?: '',
+ $this->sem_browse_data['sset'] ?: ''
+ );
+
+ return $quicksearch;
+ }
+
+ private function printExtendedSearch()
+ {
+ $template = $GLOBALS['template_factory']->open('sembrowse/extended-search.php');
+ $template->search_obj = $this->search_obj;
+ $template->sem_browse_data = $this->sem_browse_data;
+ $template->show_class = $this->show_class();
+ echo $template->render();
+ }
+
+ public function do_output()
+ {
+ if ($this->sem_browse_data['cmd'] == 'xts') {
+ $this->printExtendedSearch();
+ }
+ $path_id = Request::option('path_id');
+ URLHelper::addLinkParam('path_id', $path_id);
+ $this->print_level($path_id);
+ }
+
+ public function print_level($start_id = null)
+ {
+ ob_start();
+
+ echo "\n" . '<table id="sem_search_level" class="course-search" style="width: 100%">' . "\n";
+ if ($this->sem_browse_data['level'] == 'vv') {
+ echo "\n" . '<caption class="legend">'._('Studienbereiche').'<caption>';
+ echo "\n" . '<tr><td style="text-align: center">';
+ $this->sem_tree->show_entries = $this->sem_browse_data['show_entries'] ?? false;
+ $this->sem_tree->showSemTree($start_id);
+ }
+ if ($this->sem_browse_data['level'] == 'ev') {
+ echo "\n" . '<caption class="legend">'._('Einrichtungen').'<caption>';
+ echo "\n" . '<tr><td style="text-align: center">';
+ $this->range_tree->show_entries = $this->sem_browse_data['show_entries'] ?? false;
+ $this->range_tree->showSemRangeTree($start_id);
+ }
+
+ if ($this->show_result) {
+ $this->print_result();
+ }
+
+ echo '</td></tr></table>';
+ ob_end_flush();
+ }
+
+ public function print_result()
+ {
+ ob_start();
+ global $SEM_TYPE, $SEM_CLASS;
+
+ if (is_array($this->sem_browse_data['search_result'])
+ && count($this->sem_browse_data['search_result'])) {
+ if (!is_object($this->sem_tree)) {
+ $this->sem_tree = new StudipSemTreeViewSimple(
+ $this->sem_browse_data['start_item_id'] ?? null,
+ $this->sem_number,
+ !empty($this->sem_browse_data['sem_status']) && is_array($this->sem_browse_data['sem_status'])
+ ? $this->sem_browse_data['sem_status'] : false,
+ !(is_object($GLOBALS['perm']) && $GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM))
+ );
+ }
+ $the_tree = $this->sem_tree->tree;
+
+ list($group_by_data, $sem_data) = $this->get_result();
+
+ $visibles = $sem_data;
+ if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
+ $visibles = array_filter($visibles, function ($c) {
+ return key($c['visible']) == 1;
+ });
+ }
+
+ echo '<table class="default" id="sem_search_result" style="width: calc(100% - 21px);" >';
+ foreach ($group_by_data as $group_field => $sem_ids) {
+ if (Config::get()->COURSE_SEARCH_SHOW_ADMISSION_STATE) {
+ echo '<tr><th colspan="6">';
+ } else {
+ echo '<tr><th colspan="5">';
+ }
+ switch ($this->sem_browse_data['group_by'] ?? null) {
+ case 0:
+ echo htmlReady($this->search_obj->sem_dates[$group_field]['name'] ?? '');
+ break;
+ case 1:
+ if ($the_tree->tree_data[$group_field]) {
+ echo htmlReady($the_tree->getShortPath($group_field));
+ if (is_object($this->sem_tree)){
+ echo $this->sem_tree->getInfoIcon($group_field);
+ }
+ } else {
+ echo _('keine Studienbereiche eingetragen');
+ }
+ break;
+ case 3:
+ echo htmlReady($SEM_TYPE[$group_field]['name']
+ . ' ('
+ . $SEM_CLASS[$SEM_TYPE[$group_field]['class']]['name']
+ . ')');
+ break;
+ default:
+ echo htmlReady($group_field);
+ }
+ echo '</th></tr>';
+ ob_end_flush();
+ ob_start();
+ if (is_array($sem_ids['Seminar_id'])) {
+ foreach(array_keys($sem_ids['Seminar_id']) as $seminar_id){
+ echo $this->printCourseRow($seminar_id, $sem_data);
+ }
+ }
+ }
+ echo '</table>';
+ } elseif ($this->search_obj->search_button_clicked
+ && !$this->search_obj->new_search_button_clicked) {
+ $details = [];
+ if ($this->search_obj->found_rows === false) {
+ $details = [_('Der Suchbegriff fehlt oder ist zu kurz')];
+ }
+ if ($details) {
+ PageLayout::postError(_('Ihre Suche ergab keine Treffer'), $details);
+ } else {
+ PageLayout::postInfo(_('Ihre Suche ergab keine Treffer'));
+ }
+ $this->sem_browse_data['sset'] = 0;
+ }
+ ob_end_flush();
+ }
+
+ public function get_result()
+ {
+ global $_fullname_sql, $user;
+ if ($this->sem_browse_data['group_by'] == 1) {
+ if (!is_object($this->sem_tree)) {
+ $the_tree = TreeAbstract::GetInstance('StudipSemTree', false);
+ } else {
+ $the_tree = $this->sem_tree->tree;
+ }
+ $sem_tree_query = '';
+ if ($this->sem_browse_data['start_item_id'] != 'root'
+ && ($this->sem_browse_data['level'] == 'vv'
+ || $this->sem_browse_data['level'] == 'sbb')) {
+ $allowed_ranges = $the_tree->getKidsKids($this->sem_browse_data['start_item_id']);
+ $allowed_ranges[] = $this->sem_browse_data['start_item_id'];
+ $sem_tree_query = " AND sem_tree_id IN('" . join("','", $allowed_ranges) . "') ";
+ }
+ $add_fields = 'seminar_sem_tree.sem_tree_id AS bereich,';
+ $add_query = "LEFT JOIN seminar_sem_tree ON (seminare.Seminar_id = seminar_sem_tree.seminar_id $sem_tree_query)";
+ } else if ($this->sem_browse_data['group_by'] == 4){
+ $add_fields = 'Institute.Name AS Institut,Institute.Institut_id,';
+ $add_query = 'LEFT JOIN seminar_inst
+ ON (seminare.Seminar_id = seminar_inst.Seminar_id)
+ LEFT JOIN Institute
+ ON (Institute.Institut_id = seminar_inst.institut_id)';
+ } else {
+ $add_fields = '';
+ $add_query = '';
+ }
+
+ $dbv = DbView::getView('sem_tree');
+
+ $query = "
+ SELECT seminare.Seminar_id, VeranstaltungsNummer, seminare.status,
+ IF(seminare.visible = 0, CONCAT(seminare.Name, ' " . _('(versteckt)')
+ . "'), seminare.Name) AS Name,"
+ . $add_fields
+ . $_fullname_sql['full'] . " AS fullname,
+ auth_user_md5.username,"
+ . $dbv->sem_number_sql . ' AS sem_number, '
+ . $dbv->sem_number_end_sql . ' AS sem_number_end,
+ seminar_user.position AS position, seminare.parent_course, seminare.visible
+ FROM seminare
+ LEFT JOIN seminar_user
+ ON (seminare.Seminar_id=seminar_user.Seminar_id AND seminar_user.status = ' . "'dozent'" . ')
+ LEFT JOIN auth_user_md5
+ USING (user_id)
+ LEFT JOIN user_info
+ USING (user_id) '
+ . $add_query . "
+ WHERE (seminare.Seminar_id IN('" . join("','", array_keys($this->sem_browse_data['search_result'])) . "')
+ OR seminare.parent_course IN ('" . join("','", array_keys($this->sem_browse_data['search_result'])) . "'))";
+
+ // don't show Studiengruppen if user not logged in
+ if (!$GLOBALS['user'] || $GLOBALS['user']->id == 'nobody') {
+ $studygroup_types = DBManager::get()->quote(studygroup_sem_types());
+ $query .= " AND seminare.status NOT IN ({$studygroup_types})";
+ }
+
+ $db = new DB_Seminar($query);
+ $snap = new DbSnapshot($db);
+ $group_field = $this->group_by_fields[$this->sem_browse_data['group_by']]['group_field'];
+ $data_fields[0] = 'Seminar_id';
+ if (!empty($this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field'])) {
+ $data_fields[1] = $this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field'];
+ }
+ if($user->id == 'nobody' && $snap->numRows == 0){
+ $group_by_data = $sem_data = [];
+ }else{
+ $group_by_data = $snap->getGroupedResult($group_field, $data_fields);
+ $sem_data = $snap->getGroupedResult('Seminar_id');
+ }
+
+ if ($this->sem_browse_data['group_by'] == 0) {
+ if($user->id == 'nobody' && $snap->numRows == 0){
+ $group_by_duration = [];
+ }else{
+ $group_by_duration = $snap->getGroupedResult('sem_number_end', ['sem_number', 'Seminar_id']);
+ }
+ foreach ($group_by_duration as $sem_number_end => $detail) {
+ if ($sem_number_end != -1
+ && ($detail['sem_number'][$sem_number_end]
+ && count($detail['sem_number']) == 1)) {
+ continue;
+ }
+
+ $current_semester_index = Semester::getIndexById(Semester::findCurrent()->semester_id, true, true);
+ foreach (array_keys($detail['Seminar_id']) as $seminar_id) {
+ $start_sem = key($sem_data[$seminar_id]['sem_number']);
+ if ($sem_number_end == -1) {
+ if ($this->sem_number === false) {
+ $sem_number_end = $current_semester_index && isset($this->search_obj->sem_dates[$current_semester_index + 1]) ? $current_semester_index + 1 : count($this->search_obj->sem_dates) -1;
+ } else {
+ $sem_number_end = $this->sem_number[0];
+ }
+ }
+ for ($i = $start_sem; $i <= $sem_number_end; ++$i) {
+ if ($this->sem_number === false
+ || is_array($this->sem_number)
+ && in_array($i, $this->sem_number)) {
+ if (!empty($group_by_data[$i]) && empty($tmp_group_by_data[$i])) {
+ foreach (array_keys($group_by_data[$i]['Seminar_id']) as $id) {
+ $tmp_group_by_data[$i]['Seminar_id'][$id] = true;
+ }
+ }
+ $tmp_group_by_data[$i]['Seminar_id'][$seminar_id] = true;
+ }
+ }
+ }
+ }
+ if (!empty($tmp_group_by_data) && is_array($tmp_group_by_data)) {
+ if ($this->sem_number !== false) {
+ unset($group_by_data);
+ }
+ foreach ($tmp_group_by_data as $start_sem => $detail) {
+ $group_by_data[$start_sem] = $detail;
+ }
+ }
+ }
+
+ //release memory
+ unset($snap);
+ unset($tmp_group_by_data);
+
+ foreach ($group_by_data as $group_field => $sem_ids) {
+ foreach ($sem_ids['Seminar_id'] as $seminar_id => $foo) {
+ $name = mb_strtolower(key($sem_data[$seminar_id]['Name']));
+ $name = str_replace(['ä', 'ö', 'ü'], ['ae', 'oe', 'ue'], $name);
+ if (Config::get()->IMPORTANT_SEMNUMBER && key($sem_data[$seminar_id]['VeranstaltungsNummer'])) {
+ $name = key($sem_data[$seminar_id]['VeranstaltungsNummer']) . ' ' . $name;
+ }
+ $group_by_data[$group_field]['Seminar_id'][$seminar_id] = $name;
+ }
+ uasort($group_by_data[$group_field]['Seminar_id'], 'strnatcmp');
+ }
+
+ switch ($this->sem_browse_data['group_by']) {
+ case 0:
+ krsort($group_by_data, SORT_NUMERIC);
+ break;
+ case 1:
+ uksort($group_by_data, function($a,$b) {
+ $the_tree = TreeAbstract::GetInstance('StudipSemTree', false);
+ $the_tree->buildIndex();
+ return $the_tree->tree_data[$a]['index'] - $the_tree->tree_data[$b]['index'];
+ });
+ break;
+ case 3:
+ uksort($group_by_data, function ($a,$b) {
+ global $SEM_CLASS,$SEM_TYPE;
+ return strnatcasecmp($SEM_TYPE[$a]['name'], $SEM_TYPE[$b]['name'])
+ ?: strnatcasecmp(
+ $SEM_CLASS[$SEM_TYPE[$a]['class']]['name'],
+ $SEM_CLASS[$SEM_TYPE[$b]["class"]]['name']
+ );
+ });
+ break;
+ default:
+ uksort($group_by_data, 'strnatcasecmp');
+ }
+
+ return [$group_by_data, $sem_data];
+ }
+
+ /**
+ * Creates HTML code for a single course row. This has been extracted
+ * into a separate function as that makes handling and outputting
+ * course children easier.
+ *
+ * @param string $seminar_id a single course id to output
+ * @param mixed $sem_data collected data for all found courses
+ * @param bool $child call in "child mode" -> force output because here children are listed
+ * @return string A HTML table row.
+ */
+ private function printCourseRow($seminar_id, &$sem_data, $child = false)
+ {
+ global $SEM_TYPE;
+
+ $row = '';
+
+ /*
+ * As we include child courses now, we need an extra check for visibility.
+ * Child courses are not shown extra, but summarized under their parent if
+ * the parent is part of the search result.
+ */
+ if (($GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)
+ || key($sem_data[$seminar_id]['visible']) == 1)
+ && (empty($sem_data[key($sem_data[$seminar_id]['parent_course'])])
+ || $child)) {
+ // create instance of seminar-object
+ $seminar_obj = new Seminar($seminar_id);
+ // is this sem a studygroup?
+ $studygroup_mode = SeminarCategories::GetByTypeId($seminar_obj->getStatus())->studygroup_mode;
+
+ $sem_name = $seminar_obj->getFullName('type-name');
+ $seminar_number = key($sem_data[$seminar_id]['VeranstaltungsNummer']);
+
+ $visibleChildren = [];
+
+ $row .= '<tr';
+ // Set necessary classes if we are displaying subcourses.
+ if ($child) {
+ $row .= ' class="hidden-js subcourses subcourses-' . key($sem_data[$seminar_id]['parent_course']) . '"' ;
+ }
+ $row .= '>';
+
+ if ($studygroup_mode) {
+ $sem_name .= ' (' . _('Studiengruppe');
+ if ($seminar_obj->admission_prelim) $sem_name .= ', ' . _('Zutritt auf Anfrage');
+ $sem_name .= ')';
+ $row .= '<td width="1%" class="hidden-tiny-down">';
+ $row .= StudygroupAvatar::getAvatar($seminar_id)->getImageTag(Avatar::SMALL, ['title' => $seminar_obj->getName()]);
+ $row .= '</td>';
+ } else {
+ $sem_number_start = key($sem_data[$seminar_id]['sem_number']);
+ $sem_number_end = key($sem_data[$seminar_id]['sem_number_end']);
+ if ($sem_number_start != $sem_number_end) {
+ $sem_name .= ' (' . $this->search_obj->sem_dates[$sem_number_start]['name'] . ' - ';
+ $sem_name .= (($sem_number_end == -1)
+ ? _('unbegrenzt')
+ : $this->search_obj->sem_dates[$sem_number_end]['name']) . ')';
+ } elseif ($this->sem_browse_data['group_by']) {
+ $sem_name .= " (" . $this->search_obj->sem_dates[$sem_number_start]['name'] . ')';
+ }
+ $row .= '<td width="1%" class="hidden-tiny-down">';
+ $row .= CourseAvatar::getAvatar($seminar_id)->getImageTag(Avatar::SMALL, ['title' => $seminar_obj->getName()]);
+ $row .= '</td>';
+
+ }
+ $send_from_search = URLHelper::getUrl(basename($_SERVER['PHP_SELF']), ['keep_result_set' => 1, 'cid' => null]);
+ $send_from_search_link = URLHelper::getLink($this->target_url,
+ [
+ $this->target_id => $seminar_id,
+ 'cid' => null,
+ 'send_from_search' => 1,
+ 'send_from_search_page' => $send_from_search
+ ]);
+ $row .= '<td style="width: 66%" colspan="2">';
+
+ // Show the "more" icon only if there are visible children.
+ if (count($seminar_obj->children) > 0) {
+
+ // If you are not root, perhaps not all available subcourses are visible.
+ $visibleChildren = $seminar_obj->children;
+ if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
+ $visibleChildren = $visibleChildren->filter(function($c) {
+ return $c->visible;
+ });
+ }
+ if (count($visibleChildren) > 0) {
+ $row .= Icon::create('add', Icon::ROLE_CLICKABLE ,[
+ 'id' => 'show-subcourses-' . $seminar_id,
+ 'title' => sprintf(_('%u Unterveranstaltungen anzeigen'), count($visibleChildren)),
+ 'onclick' => "jQuery('tr.subcourses-" . $seminar_id . "').removeClass('hidden-js');jQuery(this).closest('tr').addClass('has-subcourses');jQuery(this).hide();jQuery('#hide-subcourses-" . $seminar_id . "').show();"
+ ])->asImg(12) . ' ';
+ $row .= Icon::create('remove', Icon::ROLE_CLICKABLE ,[
+ 'id' => 'hide-subcourses-' . $seminar_id,
+ 'style' => 'display:none',
+ 'title' => sprintf(_('%u Unterveranstaltungen ausblenden'), count($visibleChildren)),
+ 'onclick' => "jQuery('tr.subcourses-" . $seminar_id . "').addClass('hidden-js'); jQuery(this).closest('tr').removeClass('has-subcourses');jQuery(this).hide();jQuery('#show-subcourses-" . $seminar_id . "').show();"
+ ])->asImg(12) . ' ';
+ }
+ }
+
+ $row .= '<a href="' . $send_from_search_link . '">';
+ if (Config::get()->IMPORTANT_SEMNUMBER && $seminar_number) {
+ $row .= htmlReady($seminar_number) . " ";
+ }
+ $row .= htmlReady($sem_name) . '</a><br>';
+ //create Turnus field
+ if ($studygroup_mode) {
+ $row .= '<div style="font-size:smaller">'
+ . htmlReady(mb_substr($seminar_obj->description, 0, 100))
+ . '</div>';
+ } else {
+ $temp_turnus_string = $seminar_obj->getDatesExport(
+ [
+ 'short' => true,
+ 'shrink' => true,
+ 'semester_id' => ''
+ ]
+ );
+ //Shorten, if string too long (add link for details.php)
+ if (mb_strlen($temp_turnus_string) > 70) {
+ $temp_turnus_string = htmlReady(mb_substr($temp_turnus_string, 0, mb_strpos(mb_substr($temp_turnus_string, 70, mb_strlen($temp_turnus_string)), ',') + 71));
+ $temp_turnus_string .= ' ... <a href="' . $send_from_search_link . '">(' . _('mehr') . ')</a>';
+ } else {
+ $temp_turnus_string = htmlReady($temp_turnus_string);
+ }
+ if (!Config::get()->IMPORTANT_SEMNUMBER) {
+ $row .= '<div style="margin-left:5px;font-size:smaller">' . htmlReady($seminar_number) . '</div>';
+ }
+ $row .= '<div style="margin-left:5px;font-size:smaller">' . $temp_turnus_string . '</div>';
+ if (count($seminar_obj->children) > 0 && count($visibleChildren) > 0) {
+ $row .= '<div style="margin-left:5px;font-size:smaller">';
+ $row .= sprintf(_('%u Unterveranstaltungen'), count($visibleChildren));
+ $row .= '</div>';
+ }
+ }
+ $row .= '</td>';
+ $row .= '<td style="text-align: right">(';
+ $doz_name = [];
+ $c = 0;
+ reset($sem_data[$seminar_id]['fullname']);
+ foreach ($sem_data[$seminar_id]['username'] as $anzahl1) {
+ if ($c == 0) {
+ $d_name = key($sem_data[$seminar_id]['fullname']);
+ $anzahl2 = current($sem_data[$seminar_id]['fullname']);
+ next($sem_data[$seminar_id]['fullname']);
+ $c = $anzahl2 / $anzahl1;
+ $doz_name = array_merge($doz_name, array_fill(0, $c, $d_name));
+ }
+ --$c;
+ }
+ $doz_uname = array_keys($sem_data[$seminar_id]['username']);
+ $doz_position = array_keys($sem_data[$seminar_id]['position']);
+ if (count($doz_name)) {
+ if (count($doz_position) != count($doz_uname)) {
+ $doz_position = range(1, count($doz_uname));
+ }
+ array_multisort($doz_position, $doz_name, $doz_uname);
+ $i = 0;
+ foreach ($doz_name as $index => $value) {
+ if ($value) { // hide dozenten with empty username
+ if ($i == 4) {
+ $row .= '... <a href="' . $send_from_search_link . '">(' . _('mehr') . ')</a>';
+ break;
+ }
+ $row .= '<a href="' . URLHelper::getLink('dispatch.php/profile', ['username' => $doz_uname[$index]]) . '">' . htmlReady($value) . '</a>';
+ if ($i != count($doz_name) - 1) {
+ $row .= ', ';
+ }
+ }
+ ++$i;
+ }
+ $row .= ')</td>';
+ if (Config::get()->COURSE_SEARCH_SHOW_ADMISSION_STATE) {
+ $row .= '<td>';
+ switch (self::getStatusCourseAdmission($seminar_id,
+ $seminar_obj->admission_prelim)) {
+ case 1:
+ $row .= Icon::create(
+ 'info-circle',
+ Icon::ROLE_STATUS_YELLOW,
+ tooltip2(_('Eingeschränkter Zugang'))
+ );
+ break;
+ case 2:
+ $row .= Icon::create(
+ 'decline-circle',
+ Icon::ROLE_STATUS_RED,
+ tooltip2(_('Kein Zugang'))
+ );
+ break;
+ default:
+ $row .= Icon::create(
+ 'check-circle',
+ Icon::ROLE_STATUS_GREEN,
+ tooltip2(_('Uneingeschränkter Zugang'))
+ );
+ }
+ $row .= '</td>';
+ }
+ $row .= '</tr>';
+ }
+
+ // Process children.
+ foreach ($seminar_obj->children as $child) {
+ $row .= $this->printCourseRow($child->id, $sem_data, true);
+ }
+
+ }
+
+ return $row;
+ }
+
+
+ /**
+ * Returns a new navigation object corresponding to the given target and
+ * name of the option. The target has two possibel values "sidebar" and
+ * "course" and indicates the place where the navigation is shown.
+ * The option name is the key of an entry in the array with the navigation
+ * options.
+ *
+ * The navigation options are configured in the global configuration as an
+ * array. For further details see documentation of entry
+ * COURSE_SEARCH_NAVIGATION_OPTIONS in global configuration.
+ *
+ * This is an example with all possible options:
+ *
+ * {
+ * // "courses", "semtree" and "rangetree" are the "old" search options.
+ * // The link text is fixed.
+ * "courses":{
+ * "visible":true,
+ * // The target indicates where the link to this search option is
+ * // placed. Possible values are "sidebar" for a link in the sidebar
+ * // or "courses" to show a link (maybe with picture) below the
+ * // "course search".
+ * "target":"sidebar"
+ * },
+ * "semtree":{
+ * "visible":true,
+ * "target":"sidebar"
+ * },
+ * "rangetree":{
+ * "visible":false,
+ * "target":"sidebar"
+ * },
+ * // New option to acivate the search for modules and the systematic
+ * // search in studycourses, field of study and degrees.
+ * "module":{
+ * "visible":true,
+ * "target":"sidebar"
+ * },
+ * // This option shows a direct link in the sidebar to an entry (level)
+ * // in the range tree. The link text is the name of the level.
+ * "fb3_hist":{
+ * "visible":true,
+ * "target":"sidebar",
+ * "range_tree_id":"d1a07cf0c8057c664279214cc070b580"
+ * },
+ * // The same for an entry in the sem tree.
+ * "grundstudium":{
+ * "visible":true,
+ * "target":"sidebar",
+ * "sem_tree_id":"e1a07cf0c8057c664279214cc070b580"
+ * },
+ * // This shows a link in the sidebar to the course search. The text is
+ * // availlable in two languages.
+ * "vvz":{
+ * "visible":true,
+ * "target":"sidebar",
+ * "url":"dispatch.php/search/courses?level=f&option=vav",
+ * "title":{
+ * "de_DE":"Veranstaltungsverzeichnis",
+ * "en_GB":"Course Catalogue"
+ * }
+ * },
+ * // This option uses an url with search option and shows a link in the
+ * // sidebar to an entry in the range tree with all courses.
+ * "test":{
+ * "visible":true,
+ * "target":"sidebar",
+ * "url":"dispatch.php/search/courses?start_item_id=d1a07cf0c8057c664279214cc070b580&cmd=show_sem_range_tree&item_id=d1a07cf0c8057c664279214cc070b580_withkids&level=ev",
+ * "title":{
+ * "de_DE":"Historisches Institut",
+ * "en_GB":"Historical Institute"
+ * }
+ * },
+ * // This option shows a link to the sem tree with picture below the
+ * // course search (target: courses).
+ * // This is the behaviour of Stud.IP < 4.2.
+ * "csemtree":{
+ * "visible":true,
+ * "target":"courses",
+ * "url":"dispatch.php/search/courses?level=vv",
+ * "img":{
+ * "filename":"directory-search.png",
+ * "attributes":{
+ * "size":"260@100"
+ * }
+ * },
+ * "title":{
+ * "de_DE":"Suche im Vorlesungsverzeichnis",
+ * "en_GB":"Search course directory"
+ * }
+ * },
+ * // This option shows a link to the range tree with picture below the
+ * // course search (target: courses).
+ * // This is the behaviour of Stud.IP < 4.2.
+ * "crangetree":{
+ * "visible":true,
+ * "target":"courses",
+ * "url":"dispatch.php/search/courses?level=ev",
+ * "img":{
+ * "filename":"institute-search.png",
+ * "attributes":{
+ * "size":"260@100"
+ * }
+ * },
+ * "title":{
+ * "de_DE":"Suche in Einrichtungen",
+ * "en_GB":"Search institutes"
+ * }
+ * }
+ * }
+ *
+ *
+ * @param string $target
+ * @param string $option_name
+ * @return Navigation|null
+ */
+ public static function getSearchOptionNavigation($target, $option_name = null): ?Navigation
+ {
+ // return first visible search option
+ if (is_null($option_name)) {
+ $options = Config::get()->COURSE_SEARCH_NAVIGATION_OPTIONS;
+ foreach ($options as $name => $option) {
+ if ($option['visible'] && $option['target'] === $target) {
+ return self::getSearchOptionNavigation($target, $name);
+ }
+ }
+ return null;
+ }
+
+ $installed_languages = array_keys(Config::get()->INSTALLED_LANGUAGES);
+ $language = $_SESSION['_language'] ?? reset($installed_languages);
+ $option = Config::get()->COURSE_SEARCH_NAVIGATION_OPTIONS[$option_name];
+ if (!$option['visible'] || $option['target'] !== $target) {
+ return null;
+ }
+ if (empty($option['url'])) {
+ switch ($option_name) {
+ case 'courses':
+ case 'semtree':
+ return new Navigation(_('Vorlesungsverzeichnis'),
+ URLHelper::getURL('dispatch.php/search/courses',
+ [
+ 'type' => 'semtree'
+ ], true));
+ case 'rangetree':
+ return new Navigation(_('Einrichtungsverzeichnis'),
+ URLHelper::getURL('dispatch.php/search/courses',
+ [
+ 'type' => 'rangetree'
+ ], true));
+ case 'module':
+ return new MVVSearchNavigation(_('Modulverzeichnis'),
+ URLHelper::getURL('dispatch.php/search/module'),null, true);
+ }
+ } else {
+ return new Navigation($option['title'][$language],
+ URLHelper::getURL($option['url'], ['option' => $option_name], true));
+ }
+ if (!empty($option['sem_tree_id'])) {
+ $study_area = StudipStudyArea::find($option['sem_tree_id']);
+ return new Navigation($study_area->name,
+ URLHelper::getURL('dispatch.php/search/courses',
+ [
+ 'start_item_id' => $option['sem_tree_id'],
+ 'path_id' => $option['sem_tree_id'],
+ 'cmd' => 'show_sem_range',
+ 'item_id' => $option['sem_tree_id'] . '_withkids',
+ 'level' => 'vv',
+ 'option' => $option_name
+ ], true));
+ }
+ if (!empty($option['range_tree_id'])) {
+ $item_name = DBManager::get()->fetchColumn('
+ SELECT `name`
+ FROM `range_tree`
+ WHERE item_id = ?',
+ [$option['range_tree_id']]);
+ return new Navigation($item_name,
+ URLHelper::getURL('dispatch.php/search/courses',
+ [
+ 'start_item_id' => $option['range_tree_id'],
+ 'path_id' => $option['range_tree_id'],
+ 'cmd' => 'show_sem_range_tree',
+ 'item_id' => $option['range_tree_id'] . '_withkids',
+ 'level' => 'ev',
+ 'option' => $option_name
+ ], true));
+ }
+
+ return null;
+ }
+
+ /**
+ * The class SemBrowse uses a vast number of variables stored in the
+ * session. This function sets the default values or transfers some
+ * of them to url parameters if a filter in the sidebar has been changed.
+ *
+ * @see SemBrowse::setClassesSelector()
+ * @see SemBrowse::setSemesterSelector()
+ */
+ public static function transferSessionData()
+ {
+ if (empty($_SESSION['sem_browse_data']) || Request::option('reset_all')) {
+ $_SESSION['sem_browse_data'] = [];
+ }
+
+ $_SESSION['sem_browse_data']['qs_choose'] = Request::get('search_sem_qs_choose',
+ $_SESSION['sem_browse_data']['qs_choose'] ?? null);
+
+ // simulate button clicked if semester was changed
+ $old_default_sem = $_SESSION['sem_browse_data']['default_sem'] ?? null;
+ if (Request::option('search_sem_sem', $old_default_sem) != $old_default_sem) {
+ $_SESSION['sem_browse_data']['default_sem'] = Request::option('search_sem_sem');
+ if ($_SESSION['sem_browse_data']['sset']) {
+ Request::set('search_sem_quick_search_parameter', $_SESSION['sem_browse_data']['sset']);
+ Request::set('search_sem_quick_search', $_SESSION['sem_browse_data']['sset']);
+ Request::set('search_sem_qs_choose', $_SESSION['sem_browse_data']['qs_choose']);
+ Request::set('search_sem_category', $_SESSION['sem_browse_data']['show_class']);
+ Request::set('search_sem_do_search', '1');
+ Request::set('search_sem_' . md5('is_sended'), '1');
+ } else {
+ Request::set('search_sem_category', $_SESSION['sem_browse_data']['show_class']);
+ Request::set('search_sem_sem_change', '1');
+ Request::set('search_sem_sem_select', '1');
+ }
+ }
+
+ // simulate button clicked if class was changed
+ $old_show_class = $_SESSION['sem_browse_data']['show_class'] ?? null;
+ if (Request::option('show_class', $old_show_class) != $old_show_class) {
+ $_SESSION['sem_browse_data']['show_class'] = Request::option('show_class');
+
+ if ($_SESSION['sem_browse_data']['show_class']
+ && $_SESSION['sem_browse_data']['show_class'] != 'all') {
+ $class = $GLOBALS['SEM_CLASS'][$_SESSION['sem_browse_data']['show_class']];
+ $_SESSION['sem_browse_data']['sem_status'] = array_keys($class->getSemTypes());
+ } else {
+ $_SESSION['sem_browse_data']['sem_status'] = false;
+ }
+
+ if ($_SESSION['sem_browse_data']['sset']) {
+ Request::set('search_sem_quick_search_parameter', $_SESSION['sem_browse_data']['sset']);
+ Request::set('search_sem_quick_search', $_SESSION['sem_browse_data']['sset']);
+ Request::set('search_sem_qs_choose', $_SESSION['sem_browse_data']['qs_choose']);
+ Request::set('search_sem_category', $_SESSION['sem_browse_data']['show_class']);
+ Request::set('search_sem_do_search', '1');
+ Request::set('search_sem_' . md5('is_sended'), '1');
+ } else {
+ Request::set('search_sem_category', $_SESSION['sem_browse_data']['show_class']);
+ Request::set('search_sem_sem_change', '1');
+ Request::set('search_sem_sem_select', '1');
+ }
+ }
+
+ // set default values
+ if (empty($_SESSION['sem_browse_data']['default_sem'])) {
+ $_SESSION['sem_browse_data']['default_sem'] =
+ Semester::getIndexById(self::getDefaultSemester(), true, true)
+ ?: 'all';
+ }
+ $_SESSION['sem_browse_data']['show_class'] =
+ $_SESSION['sem_browse_data']['show_class'] ?? 'all';
+ $_SESSION['sem_browse_data']['group_by'] =
+ $_SESSION['sem_browse_data']['group_by'] ?? '0';
+ }
+
+ /**
+ * Retrieves the default semester from session or calculate it considering
+ * the value from SEMESTER_TIME_SWITCH.
+ *
+ * @return Semester The semester object of the default semester.
+ */
+ public static function getDefaultSemester()
+ {
+ $default_sem = $_SESSION['_default_sem'];
+ if (!$default_sem) {
+ $current_sem = Semester::findDefault();
+ $default_sem = $current_sem->id;
+ }
+
+ return $default_sem;
+ }
+
+ /**
+ * Adds a widget to the sidebar to select a course class. The result set is
+ * filtered by this class.
+ *
+ * @param string $submit_url The submit url.
+ */
+ public static function setClassesSelector($submit_url)
+ {
+ $classes_filter = new SelectWidget(_('Veranstaltungsklassen'),
+ $submit_url, 'show_class');
+ $classes_filter->addElement(new SelectElement('all', _('Alle'),
+ ($_SESSION['sem_browse_data']['show_class'] ?: 'all') === 'all'));
+ foreach ($GLOBALS['SEM_CLASS'] as $key => $val) {
+ $classes_filter->addElement(new SelectElement($key, $val['name'],
+ ($_SESSION['sem_browse_data']['show_class'] == $key)));
+ }
+ Sidebar::Get()->addWidget($classes_filter);
+ }
+
+ /**
+ * Adds a widget to the sidebar to select a semester. The result set is
+ * filtered by this semester.
+ *
+ * @param string $submit_url The submit url.
+ */
+ public static function setSemesterSelector($submit_url)
+ {
+ $semesters = Semester::findAllVisible();
+ $sidebar = Sidebar::Get();
+ $list = new SelectWidget(_('Semester'),
+ $submit_url, 'search_sem_sem');
+ $list->addElement(new SelectElement('all', _('Alle'),
+ ($_SESSION['sem_browse_data']['default_sem']) === 'all'));
+ foreach(array_reverse($semesters, true) as $i => $semester_data) {
+ $list->addElement(new SelectElement(
+ $i,
+ $semester_data['name'],
+ ($_SESSION['sem_browse_data']['default_sem'] !== 'all'
+ && intval($_SESSION['sem_browse_data']['default_sem']) === $i)
+ ));
+ }
+ $sidebar->addWidget($list, 'filter_semester');
+ }
+
+ /**
+ * Returns the admission status for a course.
+ *
+ * @param string $seminar_id Id of the course
+ * @param bool $prelim State of preliminary setting
+ * @return int
+ */
+ public static function getStatusCourseAdmission($seminar_id, $prelim)
+ {
+ $sql = "SELECT COUNT(`type`) AS `types`,
+ SUM(IF(`type` = 'LockedAdmission', 1, 0)) AS `type_locked`
+ FROM `seminar_courseset`
+ INNER JOIN `courseset_rule` USING (`set_id`)
+ WHERE `seminar_id` = ?
+ GROUP BY `set_id`";
+
+ $stmt = DBManager::get()->prepare($sql);
+ $stmt->execute([$seminar_id]);
+ $result = $stmt->fetch();
+
+ if (!empty($result['types'])) {
+ if ($result['type_locked']) {
+ return 2;
+ }
+ return 1;
+ }
+
+ if ($prelim) {
+ return 1;
+ }
+ return 0;
+ }
+
+ /**
+ * Returns a Quick Search form to put inside a WidgetElement.
+ *
+ * @param string $level The Level of search , expected ('f', 'vv', 'ev')
+ * @return string $search_form_content Contains a form element with a quick search input, predefined (hidden) inputs and search button
+ */
+ public function getQuickSearchForm()
+ {
+ if ($this->sem_browse_data['level'] === 'vv') {
+ $this->search_obj->sem_tree =& $this->sem_tree->tree;
+ if ($this->sem_tree->start_item_id !== 'root') {
+ $this->search_obj->search_scopes[] = $this->sem_tree->start_item_id;
+ }
+ } elseif ($this->sem_browse_data['level'] === 'ev') {
+ $this->search_obj->range_tree =& $this->range_tree->tree;
+ if ($this->range_tree->start_item_id !== 'root'){
+ $this->search_obj->search_ranges[] = $this->range_tree->start_item_id;
+ }
+ }
+
+ $search_form_content = $this->search_obj->getFormStart(URLHelper::getLink(), ['class' => '']);
+ $quicksearch = $this->getQuicksearch();
+ $quicksearch->setInputStyle('height:22px;width: 100%;');
+ $quicksearch->withButton(['search_button_name'=> 'course_search_button']);
+ $quicksearch->disableAutocomplete();
+ $search_form_content .= $quicksearch->render();
+ $search_form_content .= $this->search_obj->getHiddenField('qs_choose','title_lecturer_number');
+
+ if($this->sem_browse_data['level'] == 'vv')
+ $search_form_content .= $this->search_obj->getHiddenField('scope_choose', $this->sem_tree->start_item_id);
+
+ if($this->sem_browse_data['level'] == 'ev')
+ $search_form_content .= $this->search_obj->getHiddenField('range_choose', $this->range_tree->start_item_id);
+
+ $search_form_content .= $this->search_obj->getHiddenField('level', $this->sem_browse_data['level']);
+ $search_form_content .= $this->search_obj->getHiddenField('sem', htmlReady($_SESSION['sem_browse_data']['default_sem']));
+
+ $search_form_content .= $this->search_obj->getFormEnd();
+ return $search_form_content;
+ }
+}