Skip to content
Snippets Groups Projects
courses.php 78.1 KiB
Newer Older
                $captions[$index] = $view_filters[$index];
            }
            foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
                foreach ($plugin->adminAvailableContents() as $index => $label) {
                    if (in_array($plugin->getPluginId() . "_" . $index, $filter_config)) {
                        $captions[$plugin->getPluginId() . "_" . $index] = $label;
                    }
                }
            }

            $tmpname = md5(uniqid('Veranstaltungsexport'));
            if (array_to_csv($data, $GLOBALS['TMP_PATH'] . '/' . $tmpname, $captions)) {
                $this->redirect(FileManager::getDownloadURLForTemporaryFile(
                    $tmpname,
                    'Veranstaltungen_Export.csv'
                ));
                return;
            }
        } else {
            PageLayout::setTitle(_('Spalten zum Export auswählen'));
            $this->fields = $this->getViewFilters();
            $this->selection = $this->getFilterConfig();
        }
    }


    /**
     * Set the lockrules of courses
     */
    public function set_lockrule_action()
    {
        if (!$GLOBALS['perm']->have_perm('admin')) {
            throw new AccessDeniedException();
        }
        $result = false;
        $courses = Request::getArray('lock_sem');
        $errors = [];

        if (!empty($courses)) {
            foreach ($courses as $course_id => $value) {
                if ($GLOBALS['perm']->have_studip_perm('dozent', $course_id)) {
                    // force to pre selection
                    if (Request::get('lock_sem_all') && Request::submitted('all')) {
                        $value = Request::get('lock_sem_all');
                    }

                    $course = Course::find($course_id);
                    if ($value === 'none') {
                    if ($course->lock_rule === $value) {
                        continue;
                    }

                    $course->setValue('lock_rule', $value);
                    if (!$course->store()) {
                        $errors[] = $course->name;
                    } else {
                        $result = true;
                    }
                }
            }

            if ($result) {
                PageLayout::postSuccess(_('Die gewünschten Änderungen wurden erfolgreich durchgeführt!'));
            }
            if ($errors) {
                PageLayout::postError(
                    _('Bei den folgenden Veranstaltungen ist ein Fehler aufgetreten'),
                    array_map('htmlReady', $errors)
                );
            }
        }
        $this->redirect('admin/courses/index');
    }


    /**
     * 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();
        $log_msg = '';
        foreach ($all_courses as $course_id) {
            if ($GLOBALS['perm']->have_studip_perm('dozent', $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::postSuccess(_('Die gewünschten Änderungen wurden ausgeführt!'));
        $this->redirect('admin/courses/index');
    }


    /**
     * Set the visibility of a course
     */
    public function set_visibility_action()
    {
        $result = false;
        $visibilites = Request::intArray('visibility');
        $all_courses = Request::getArray('all_sem');
        $errors = [];

        if (!empty($all_courses)) {
            foreach ($all_courses as $course_id) {
                if ($GLOBALS['perm']->have_studip_perm('tutor', $course_id)) {
                    $course = Course::find($course_id);

                    if ($course->isOpenEnded() || $course->end_semester->visible) {
                        $visibility = $visibilites[$course_id] ?: 0;

                        if ($course->visible == $visibility) {
                            continue;
                        }

                        $course->visible = $visibility;
                        if (!$course->store()) {
                            $errors[] = $course->name;
                        } else {
                            $result = true;
                            StudipLog::log($visibility ? 'SEM_VISIBLE' : 'SEM_INVISIBLE', $course->id);
                        }
                    }
                }
            }

            if ($result) {
                PageLayout::postSuccess(_('Die Sichtbarkeit wurde bei den gewünschten Veranstatungen erfolgreich geändert!'));
            }
            if ($errors) {
                PageLayout::postError(
                    _('Bei den folgenden Veranstaltungen ist ein Fehler aufgetreten'),
                    array_map('htmlReady', $errors)
                );
            }
        }
        $this->redirect('admin/courses/index');
    }


    /**
     * Set the additional course informations
     */
    public function set_aux_lockrule_action()
    {
        $result = false;
        $courses = Request::getArray('lock_sem');
        $lock_sem_forced = Request::getArray('lock_sem_forced');
        $errors = [];
        if (!empty($courses)) {
            foreach ($courses as $course_id => $value) {
                if ($GLOBALS['perm']->have_studip_perm('tutor', $course_id)) {
                    // force to pre selection
                    if (Request::submitted('all')) {
                        $value = Request::get('lock_sem_all');
                        $value_forced = Request::int('aux_all_forced', 0);
                        $value_forced = $lock_sem_forced[$course_id] ?? 0;
                    }

                    $course = Course::find($course_id);

                    if (!$value) {
                        $value_forced = 0;
                    }

                    $course->setValue('aux_lock_rule', $value);
                    $course->setValue('aux_lock_rule_forced', $value_forced);

                    $ok = $course->store();
                    if ($ok === false) {
                        $errors[] = $course->name;
                    } elseif ($ok) {
                        $result = true;
                    }
                }
            }

            if ($result) {
                PageLayout::postSuccess(_('Die gewünschten Änderungen wurden erfolgreich durchgeführt!'));
            }
            if ($errors) {
                PageLayout::postError(
                    _('Bei den folgenden Veranstaltungen ist ein Fehler aufgetreten'),
                    array_map('htmlReady', $errors)
                );
            }
        }
        $this->redirect('admin/courses/index');
    }


    /**
     * Marks a course as complete/incomplete.
     *
     * @param String $course_id Id of the course
     */
    public function toggle_complete_action($course_id)
    {
        if (!$GLOBALS['perm']->have_studip_perm('tutor', $course_id)) {
            throw new AccessDeniedException();
        }
        $course = Course::find($course_id);
        $course->completion = ((int)$course->completion + 1) % 3;
        $course->store();

        if (Request::isXhr()) {
            $this->render_json([
                'state' => (int)$course->completion,
                'label' => $course->getCompetionLabel(),
            ]);
        } else {
            $this->redirect('admin/courses/index#course-' . $course_id);
        }
    }

    /**
     * Changes the notice for a course.
     *
     * @param  string $course_id
     */
    public function notice_action(Course $course)
    {
        if (Request::isPost()) {
            $course->config->store('COURSE_ADMIN_NOTICE', trim(Request::get('notice')));

            if (Request::isXhr()) {
                $this->response->add_header('X-Dialog-Execute', 'STUDIP.AdminCourses.App.loadCourse');
                $this->response->add_header('X-Dialog-Close', '1');
                $this->render_text($course->id);
            } else {
                $this->redirect($this->indexURL("#course-{$course->id}"));
            }
            return;
        }

        $this->course = $course;
        $this->notice = $course->config->COURSE_ADMIN_NOTICE;
    }


    /**
     * Return a specifically action or all available actions
     * @param null $selected
     * @return array
     */
    private function getActions($selected = null)
    {
        // array for the avaiable modules
        $sem_filter = $this->semester ? $this->semester->beginn : 'all';
        $actions = [
            1 => [
                'name'       => _('Grunddaten'),
                'title'      => _('Grunddaten'),
                'url'        => 'dispatch.php/course/basicdata/view?cid=%s',
                'attributes' => ['data-dialog' => 'size=big'],
            ],
            2 => [
                'name'       => _('Studienbereiche'),
                'title'      => _('Studienbereiche'),
                'url'        => 'dispatch.php/course/study_areas/show/?cid=%s&from=admin/courses',
                'attributes' => ['data-dialog' => 'size=big'],
            ],
            3 => [
                'name'       => _('Zeiten/Räume'),
                'title'      => _('Zeiten/Räume'),
                'url'        => 'dispatch.php/course/timesrooms/index?cid=%s',
                'attributes' => ['data-dialog' => 'size=big'],
                'params'     => [
                    'newFilter' => $sem_filter,
                    'cmd'       => 'applyFilter'
                ],
            ],
            8 => [
                'name'      => _('Sperrebene'),
                'title'     => _('Sperrebenen'),
                'url'       => 'dispatch.php/admin/courses/set_lockrule',
                'multimode' => true,
                'partial'   => 'lock.php',
            ],
            9 => [
                'name'      => _('Sichtbarkeit'),
                'title'     => _('Sichtbarkeit'),
                'url'       => 'dispatch.php/admin/courses/set_visibility',
                'multimode' => true,
                'partial'   => 'visibility.php',
            ],
            10 => [
                'name'      => _('Zusatzangaben'),
                'title'     => _('Zusatzangaben'),
                'url'       => 'dispatch.php/admin/courses/set_aux_lockrule',
                'multimode' => true,
                'partial'   => 'aux-select.php',
            ],
            11 => [
                'name'       => _('Veranstaltung kopieren'),
                'title'      => _('Kopieren'),
                'url'        => 'dispatch.php/course/wizard/copy/%s',
                'attributes' => ['data-dialog' => 'size=big'],
            ],
            14 => [
                'name'       => 'Zugangsberechtigungen',
                'title'      => _('Zugangsberechtigungen'),
                'url'        => 'dispatch.php/course/admission?cid=%s',
                'attributes' => ['data-dialog' => 'size=big'],
            ],
            16 => [
                'name'      => _('Löschen'),
                'title'     => _('Löschen'),
                'url'       => 'dispatch.php/course/archive/confirm',
                'multimode' => true,
                'partial'   => 'add_to_archive.php',
            ],
            17 => [
                'name'      => _('Gesperrte Veranstaltungen'),
                'title'     => _('Einstellungen speichern'),
                'url'       => 'dispatch.php/admin/courses/set_locked',
                'multimode' => true,
                'partial'   => 'admission_locked.php',
            ],
            18 => [
                'name'       => _('Startsemester'),
                'title'      => _('Startsemester'),
                'url'        => 'dispatch.php/course/timesrooms/editSemester?cid=%s&origin=admin_courses',
                'attributes' => ['data-dialog' => 'size=400'],
            ],
            19 => [
                'name'       => _('LV-Gruppen'),
                'title'      => _('LV-Gruppen'),
                'url'        => 'dispatch.php/course/lvgselector?cid=%s&from=admin/courses',
                'attributes' => ['data-dialog' => 'size=big'],
            ],
            20 => [
                'name'       => _('Notiz'),
                'title'      => _('Notiz'),
                'url'        => $this->noticeURL('%s'),
                'attributes' => ['data-dialog' => 'size=auto'],
                'partial'    => 'notice-action.php',
            ],
            21 => [
                'name'       => _('Mehrfachzuordnung von Studienbereichen'),
                'title'      => _('Mehrfachzuordnung von Studienbereichen'),
                'url'        => 'dispatch.php/admin/tree/batch_assign_semtree',
                'dialogform' => true,
                'multimode'  => true,
                'partial'    => 'batch_assign_semtree.php'
            ],
            22 => [
                'name'       => _('Teilnehmendenexport'),
                'title'      => _('Teilnehmendenexport'),
                'url'        => 'dispatch.php/admin/user/batch_export_members',
                'dialogform' => true,
                'multimode'  => true,
                'partial'    => 'batch_export_members.php'

            ],
        ];

        if (!$GLOBALS['perm']->have_perm('admin')) {
            unset($actions[8]);
            if (!Config::get()->ALLOW_DOZENT_DELETE) {
                unset($actions[16]);
            }
        }
        if (!$GLOBALS['perm']->have_perm('dozent')) {
            unset($actions[11]);
            unset($actions[16]);
        }

        ksort($actions);

        foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) {
            $actions[get_class($plugin)] = [
                'name'      => $plugin->getPluginName(),
                'title'     => $plugin->getPluginName(),
                'url'       => $plugin->getAdminActionURL(),
                'attributes' => ['data-dialog' => 'size=big'],
                'multimode' => $plugin->useMultimode()
            ];
        }

        if (is_null($selected)) {
            return $actions;
        }

        return $actions[$selected];
    }


    /**
     * Set and return all needed view filters
     * @return array
     */
    private function getViewFilters()
    {
        $views = [
            'number'        => _('Nr.'),
            'name'          => _('Name'),
            'type'          => _('Veranstaltungstyp'),
            'room_time'     => _('Raum/Zeit'),
            'semester'      => _('Semester'),
            'requests'      => _('Raumanfragen'),
            'teachers'      => _('Lehrende'),
            'members'       => _('Teilnehmende'),
            'waiting'       => _('Personen auf Warteliste'),
            'preliminary'   => _('Vorläufige Anmeldungen'),
            'contents'      => _('Inhalt'),
            'last_activity' => _('Letzte Aktivität'),
        ];
        foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
            foreach ($plugin->adminAvailableContents() as $index => $label) {
                $views[$plugin->getPluginId() . "_" . $index] = $label;
            }
        }
        return $views;
    }

    /**
     * Returns all courses matching set criteria.
     *
     * @param array $params Additional parameters
     * @param bool $display_all : boolean should we show all courses or check for a limit of 500 courses?
     * @return array of courses
     */
    private function getCourses($params = [], $display_all = false)
    {
        // Init
        if ($GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === "all") {
            $inst = new SimpleCollection($this->insts);
            $inst->filter(function ($a) use (&$inst_ids) {
                $inst_ids[] = $a->Institut_id;
            });
        } else {
            //We must check, if the institute ID belongs to a faculty
            //and has the string _i appended to it.
            //In that case we must display the courses of the faculty
            //and all its institutes.
            //Otherwise we just display the courses of the faculty.

            $inst_id = $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;

            $institut = new Institute($inst_id);

            if (!$institut->isFaculty() || $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN) {
                // If the institute is not a faculty or the child insts are included,
                // pick the institute IDs of the faculty/institute and of all sub-institutes.
                $inst_ids[] = $inst_id;
                if ($institut->isFaculty()) {
                    foreach ($institut->sub_institutes->pluck('Institut_id') as $institut_id) {
                        $inst_ids[] = $institut_id;
                    }
                }
            } else {
                // If the institute is a faculty and the child insts are not included,
                // pick only the institute id of the faculty:
                $inst_ids[] = $inst_id;
            }
        }

        $active_elements = $this->getActiveElements();

        $filter = AdminCourseFilter::get(true);

        if ($params['datafields']) {
            foreach ($params['datafields'] as $field_id => $value) {
                $datafield = DataField::find($field_id);
                if ($datafield) {
                    //enable filtering by datafield values:
                    //and use the where-clause for each datafield:
                    $filter->settings['query']['joins']['de_'.$field_id] = [
                        'table' => "datafields_entries",
                        'join' => "LEFT JOIN",
                        'on' => "seminare.seminar_id = de_".$field_id.".range_id"
                    ];
                    $filter->where("(de_".$field_id.".datafield_id = :fieldId_".$field_id." "
                        . "AND de_".$field_id.".content = :fieldValue_".$field_id.") "
                        . ($datafield['default_value'] == $value ? " OR (de_".$field_id.".content IS NULL)" : "")." ",
                        [
                            'fieldId_'.$field_id => $field_id,
                            'fieldValue_'.$field_id => $value
                        ]
                    );
                }
            }
        }

        $filter->where("sem_classes.studygroup_mode = '0'");

        // Get only children of given course
Moritz Strohm's avatar
Moritz Strohm committed
        if (!empty($params['parent_course'])) {
            $filter->where("parent_course = :parent",
                [
                    'parent' => $params['parent_course']
                ]
            );
        }

        if ($active_elements['semester'] && is_object($this->semester)) {
            $filter->filterBySemester($this->semester->getId());
        }
        if ($active_elements['courseType'] && $params['typeFilter'] && $params['typeFilter'] !== "all") {
            $parts = explode('_', $params['typeFilter']);
            $class_filter = $parts[0];
            $type_filter = $parts[1] ?? null;
            if (!$type_filter && !empty($GLOBALS['SEM_CLASS'][$class_filter])) {
                $type_filter = array_keys($GLOBALS['SEM_CLASS'][$class_filter]->getSemTypes());
            }
            $filter->filterByType($type_filter);
        }
        if ($active_elements['search'] && $GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT) {
            $filter->filterBySearchString($GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT);
        }
        if ($active_elements['teacher'] && $GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER && ($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER !== "all")) {
            $filter->filterByDozent($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER);
        }
        if ($active_elements['institute']) {
            $filter->filterByInstitute($inst_ids);
        }
        if ($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL && $GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL !== 'all') {
            $filter->filterByStgTeil($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL);
        }
        if ($params['sortby'] === "status") {
            $filter->orderBy(sprintf('sem_classes.name %s, sem_types.name %s, VeranstaltungsNummer %s', $params['sortFlag'], $params['sortFlag'], $params['sortFlag']), $params['sortFlag']);
        } elseif ($params['sortby'] === 'institute') {
            $filter->orderBy('Institute.Name', $params['sortFlag']);
        } elseif ($params['sortby']) {
            $filter->orderBy($params['sortby'], $params['sortFlag']);
        }
        $filter->storeSettings();
        $this->count_courses = $filter->countCourses();
        if ($this->count_courses && ($this->count_courses <= $filter->max_show_courses || $display_all)) {
            $courses = $filter->getCourses();
        } else {
            return [];
        }

Moritz Strohm's avatar
Moritz Strohm committed
        $seminars = [];
        if (!empty($courses)) {
            foreach ($courses as $seminar_id => $seminar) {
                $seminars[$seminar_id] = $seminar[0];
                $seminars[$seminar_id]['seminar_id'] = $seminar_id;
                $seminars[$seminar_id]['obj_type'] = 'sem';
                $dozenten = $this->getTeacher($seminar_id);
                $seminars[$seminar_id]['dozenten'] = $dozenten;

                if (in_array('contents', $params['view_filter'])) {
                    $tools = new SimpleCollection(ToolActivation::findbyRange_id($seminar_id, "ORDER BY position"));
                    $visit_data = get_objects_visits([$seminar_id], 0, null, null, $tools->pluck('plugin_id'));
                    $seminars[$seminar_id]['visitdate'] = $visit_data[$seminar_id][0]['visitdate'];
                    $seminars[$seminar_id]['last_visitdate'] = $visit_data[$seminar_id][0]['last_visitdate'];
                    $seminars[$seminar_id]['tools'] = $tools;
                    $seminars[$seminar_id]['navigation'] = MyRealmModel::getAdditionalNavigations(
                        $seminar_id,
                        $seminars[$seminar_id],
Moritz Strohm's avatar
Moritz Strohm committed
                        $seminars[$seminar_id]['sem_class'] ?? null,
                        $GLOBALS['user']->id,
                        $visit_data[$seminar_id]
                    );
                }
                //add last activity column:
                if (in_array('last_activity', $params['view_filter'])) {
                    $seminars[$seminar_id]['last_activity'] = lastActivity($seminar_id);
                }
                if ((int)$this->selected_action === 17) {
                    $seminars[$seminar_id]['admission_locked'] = false;
Moritz Strohm's avatar
Moritz Strohm committed
                    if ($seminar[0]['course_set']) {
                        $set = new CourseSet($seminar[0]['course_set']);
                        if (!is_null($set) && $set->hasAdmissionRule('LockedAdmission')) {
                            $seminars[$seminar_id]['admission_locked'] = 'locked';
                        } else {
                            $seminars[$seminar_id]['admission_locked'] = 'disable';
                        }
                        unset($set);
                    }
                }
            }
        }

        return $seminars;
    }

    /**
     * Returns the teacher for a given cours
     *
     * @param String $course_id Id of the course
     * @return array of user infos [user_id, username, Nachname, fullname]
     */
    private function getTeacher($course_id)
    {
        $teachers   = CourseMember::findByCourseAndStatus($course_id, 'dozent');
        $collection = SimpleCollection::createFromArray($teachers);
        return $collection->map(function (CourseMember $teacher) {
            return [
                'user_id'  => $teacher->user_id,
                'username' => $teacher->username,
                'Nachname' => $teacher->nachname,
                'fullname' => $teacher->getUserFullname('no_title_rev'),
            ];
        });
    }

    /**
     * Adds the institutes selector to the sidebar
     */
    private function getInstSelector()

        if ($GLOBALS['perm']->have_perm('root') || (count($this->insts) > 1)) {
                $GLOBALS['perm']->have_perm('root') ? _('Alle') : _('Alle meine Einrichtungen')
            );
        }

        foreach ($this->insts as $institut) {
                new SelectElement(
                    $institut['Institut_id'],
                    (!$institut['is_fak'] ? ' ' : '') . $institut['Name'],
                    $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id']

            //check if the institute is a faculty.
            //If true, then add another option to display all courses
            //from that faculty and all its institutes.

            //$institut is an array, we can't use the method isFaculty() here!
            if ($institut['fakultaets_id'] === $institut['Institut_id']) {
                    new SelectElement(
                        $institut['Institut_id'] . '_withinst', //_withinst = with institutes
                        ' ' . $institut['Name'] . ' +' . _('Institute'),
                        ($GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id'] && $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN)
        return new SelectListElement(_('Einrichtung'), 'institute', $list, false, ['class' => 'institute-list', 'onchange' => "STUDIP.AdminCourses.changeFiltersDependendOnInstitute($(this).val()); return false;"], false);
    }

    /**
     * Adds the semester selector to the sidebar
     */
    private function getSemesterSelector()
    {
        $semesters = array_reverse(Semester::getAll());
        $list = [];
        $list[] = new SelectElement('', _('Alle'));
        foreach ($semesters as $semester) {
                $semester->id,
                $semester->name,
                $semester->id === $GLOBALS['user']->cfg->MY_COURSES_SELECTED_CYCLE
        return new SelectListElement(_('Semester'), 'sem_select', $list, false, ['onchange' => "STUDIP.AdminCourses.App.changeFilter({semester_id: $(this).val()}); return false;"], false);
     * Adds the studiengangteil selector to the sidebar
     */
    private function getStgteilSelector($institut_id = null)
        $institut_id = $institut_id ?: $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
        $stgteile = StudiengangTeil::getAllEnriched('fach_name', 'ASC', ['mvv_fach_inst.institut_id' => $institut_id]);
        if (!$institut_id || $institut_id === 'all') {
            $list[] = new SelectElement('', _('Wählen Sie eine Einrichtung'));
        } else if (count($stgteile) === 0) {
            $list[] = new SelectElement('', _('Keine Studiengangteile zu der gewählten Einrichtung'));
            $list[] = new SelectElement('', _('Alle'));
        foreach ($stgteile as $stgteil) {
                $stgteil->id,
                $stgteil->getDisplayName(),
                $stgteil->id === $GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL

        return new SelectListElement(_('Studiengangteil'), 'stgteil_select', $list, false, ['onchange' => "STUDIP.AdminCourses.App.changeFilter({stgteil: $(this).val()}); return false;"], false);
    }


    /**
     * Adds HTML-Selector to the sidebar
     * @param null $selected_action
     */
    private function setActionsWidget()
    {
        $actions = $this->getActions();
        $sidebar = Sidebar::Get();
        $list = new SelectWidget(_('Aktionsbereichauswahl'), $this->url_for('admin/courses/set_action_type'), 'action_area');

        foreach ($actions as $index => $action) {
            $list->addElement(new SelectElement(
                $index,
                $action['name'],
                $GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA == $index),
                'action-aria-' . $index
            );
        $list->setOnSubmitHandler("STUDIP.AdminCourses.App.changeActionArea($(this).find('select').val()); return false;");
        $sidebar->addWidget($list, 'editmode');
    }


    /**
     * Returns a course type widthet depending on all available courses and theirs types
     * @param string $selected
     * @param array $params
     */
    private function getCourseTypeWidget()
        $list = [];
        $list[] = new SelectElement(
            '', _('Alle')
        );
        foreach ($GLOBALS['SEM_CLASS'] as $class_id => $class) {
            if ($class['studygroup_mode']) {
                continue;
            }

            $element = new SelectElement(
                $class_id,
                $class['name'],
                $GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER === (string)$class_id
            $list[] = $element->setAsHeader();

            foreach ($class->getSemTypes() as $id => $result) {
                $element = new SelectElement(
                    $class_id . '_' . $id,
                    $result['name'],
                    $GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER === $class_id . '_' . $id
                $list[] = $element->setIndentLevel(1);

        return new SelectListElement(_('Veranstaltungstypfilter'), 'course_type', $list, false, ['onchange' => "STUDIP.AdminCourses.App.changeFilter({course_type: $(this).val()}); return false;"], false);
    }

    /**
     * Returns a widget to selected a specific teacher
     * @param array $teachers
     */
    private function getTeacherWidget($institut_id = null)
        $institut_id = $institut_id ?: $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
        $teachers = DBManager::get()->fetchAll("
                SELECT auth_user_md5.*, user_info.*
                FROM auth_user_md5
                    LEFT JOIN user_info ON (auth_user_md5.user_id = user_info.user_id)
                    INNER JOIN user_inst ON (user_inst.user_id = auth_user_md5.user_id)
                    INNER JOIN Institute ON (Institute.Institut_id = user_inst.Institut_id)
                WHERE (Institute.Institut_id = :institut_id OR Institute.fakultaets_id = :institut_id)
                    AND auth_user_md5.perms = 'dozent'
                ORDER BY auth_user_md5.Nachname ASC, auth_user_md5.Vorname ASC
            ", [
                'institut_id' => $institut_id
            ],
            function ($data) {
                $ret['user_id'] = $data['user_id'];
                unset($data['user_id']);
                $ret['fullname'] = User::build($data)->getFullName("full_rev");
                return $ret;
            }
        if (!$institut_id || $institut_id === 'all') {
            $list[] = new SelectElement('', _('Wählen Sie eine Einrichtung'));
        } else if (count($teachers) === 0) {
            $list[] = new SelectElement('', _('Keine Lehrenden in der gewählten Einrichtung'));
            $list[] = new SelectElement('', _('Alle'));

        foreach ($teachers as $teacher) {
                $teacher['user_id'],
                $teacher['fullname'],
                $GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER === $teacher['user_id']

        return new SelectListElement(_('Lehrendenfilter'), 'teacher_filter', $list, false, ['onchange' => "STUDIP.AdminCourses.App.changeFilter({teacher_filter: $(this).val()}); return false;"], false);
    }

    /**
     * Adds a search widget to the sidebar
     */
    private function setSearchWiget()
    {
        $sidebar = Sidebar::Get();
        $search = new SearchWidget(URLHelper::getURL('dispatch.php/admin/courses'));
        $search->addNeedle(
            _('Freie Suche'),
            'search',
            true,
            null,
            '',
            $GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT
        );
        $search->setOnSubmitHandler("STUDIP.AdminCourses.App.changeFilter({search: $(this).find('input').val()}); return false;");
        $sidebar->addWidget($search, 'filter_search');
    }

    /**
     * Returns the filter configuration.
     *
     * @return array containing the filter configuration
     */
    {
        $available_filters = array_keys($this->getViewFilters());

        $temp = $GLOBALS['user']->cfg->MY_COURSES_ADMIN_VIEW_FILTER_ARGS;
        if ($temp) {
            $config = json_decode($temp, true);
            if (!is_array($config)) {
                $config = [];
            }

            $config = array_intersect($config, $available_filters);
        } else {
            $config = [];
        }

        if (!$config) {
            $config = $this->setFilterConfig([
                'number', 'name', 'semester', 'institute', 'teachers'
            ]);
    }

    /**
     * Sets the filter configuration.
     *
     * @param Array $config Filter configuration
     * @return array containing the filter configuration
     */
    private function setFilterConfig($config)
    {
        $config = $config ?: array_keys($this->getViewFilters());
        $GLOBALS['user']->cfg->store('MY_COURSES_ADMIN_VIEW_FILTER_ARGS', json_encode($config));

        return $config;
    }

    /**
     * Returns the default element configuration.
     *
     * @return array containing the default element configuration
     */
    private function getActiveElementsDefault()
    {
        return [
            'search' => true,
            'institute' => true,
            'semester' => true,
            'stgteil' => true,
            'courseType' => true,
            'teacher' => true,
        ];
    }

    /**
     * Returns the active element configuration of the current user.
     *
     * @return array containing the active element configuration
     */
    private function getActiveElements()
    {
        $active_elements = $GLOBALS['user']->cfg->ADMIN_COURSES_SIDEBAR_ACTIVE_ELEMENTS;

        if ($active_elements) {
            return json_decode($active_elements, true);
        } else {
            return $this->getActiveElementsDefault();
        }
    }

    /**
     * Sets the active element configuration for the current user.
     *
     * @param Array $active_elements element configuration
     */
    private function setActiveElements($active_elements)
    {
        if ($active_elements == $this->getActiveElementsDefault()) {
            $GLOBALS['user']->cfg->delete('ADMIN_COURSES_SIDEBAR_ACTIVE_ELEMENTS');
        } else {
            $GLOBALS['user']->cfg->store('ADMIN_COURSES_SIDEBAR_ACTIVE_ELEMENTS', json_encode($active_elements));
        }
    }
}