Skip to content
Snippets Groups Projects
courses.php 78.1 KiB
Newer Older
<?php
/**
 * courses.php - Controller for admin and seminar related
 * pages under "Meine Veranstaltungen"
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * @author      David Siegfried <david@ds-labs.de>
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2 or later
 * @category    Stud.IP
 * @since       3.1
 */
require_once 'lib/meine_seminare_func.inc.php';
require_once 'lib/object.inc.php';
require_once 'lib/archiv.inc.php'; //for lastActivity in getCourses() method

class Admin_CoursesController extends AuthenticatedController
{

    /**
     * This method returns the appropriate widget for the given datafield.
     *
     * @param DataField datafield The datafield whose widget is requested.
     *
     * @return SidebarWidget|null Returns a SidebarWidget derivative or null in case of an error.
     */
    private function getDatafieldWidget(DataField $datafield)
    {
        if ($datafield->accessAllowed()) {
            //The current user is allowed to see this datafield.
            //Now we must distinguish between the different types of data fields:

            $datafields_filters = $GLOBALS['user']->cfg->ADMIN_COURSES_DATAFIELDS_FILTERS;

            $type = $datafield->type;

            if ($type == 'bool') {
                //bool fields just need a checkbox for the states TRUE and FALSE
                $checkboxWidget = new OptionsWidget($datafield->name);
                $checkboxWidget->addCheckbox(
                    _('Feld gesetzt'),
                    Request::bool('df_'.$datafield->id, $datafields_filters[$datafield->id] ?? false),
                    URLHelper::getURL(
                        'dispatch.php/admin/courses/index',
                        ['df_'.$datafield->id => '1']
                    ),
                    URLHelper::getURL(
                        'dispatch.php/admin/courses/index'
                    ),
                    ['onclick' => "$(this).toggleClass(['options-checked', 'options-unchecked']); STUDIP.AdminCourses.App.changeFilter({'df_".$datafield->id."': $(this).hasClass('options-checked') ? 1 : 0}); return false;"]
                );
                return $checkboxWidget;
            } elseif ($type == 'selectbox' || $type == 'radio' || $type == 'selectboxmultiple') {
                $options = array_map('trim', explode("\n", DBManager::get()->fetchColumn(
                    'SELECT typeparam FROM datafields WHERE datafield_id = ?',
                    [$datafield->id]
                )));

                if ($options) {
                    $selectWidget = new SelectWidget(
                        $datafield->name,
                        '?',
                        'df_' . $datafield->id
                    );
                    $selectWidget->addElement(
                        new SelectElement(
                            '',
                            '(' . _('keine Auswahl') . ')'
                        )
                    );
                    foreach ($options as $option) {
                        $selectWidget->addElement(
                            new SelectElement(
                                $option,
                                $option,
                                Request::get('df_'.$datafield->id, $datafields_filters[$datafield->id] ?? null) === $option
                            )
                    $selectWidget->setOnSubmitHandler("STUDIP.AdminCourses.App.changeFilter({'df_".$datafield->id."': $(this).find('select').val()}); return false;");
                    return $selectWidget;
                }
                return null;
            } else {
                //all other fields get a text field
                $textWidget = new SearchWidget();
                $textWidget->setTitle($datafield->name);
                $textWidget->addNeedle(
                    '',
                    $datafields_filters[$datafield->id] ?? null
                $textWidget->setOnSubmitHandler("STUDIP.AdminCourses.App.changeFilter({'df_".$datafield->id."': $(this).find('input').val()}); return false;");
                return $textWidget;
            }
        }
    }

    /**
     * This method is responsible for building the sidebar.
     *
     * Depending on the sidebar elements the user has selected some of those
     * elements are shown or not. To find out what elements
     * the user has selected the user configuration is accessed.
     *
     * @param string courseTypeFilterConfig The selected value for the course type filter field, defaults to null.
     * @return null This method does not return any value.
     */
    {
        /*
            Depending on the elements the user has selected
            some of the following elements may not be presented
            in the sidebar.
        */
        $visibleElements = $this->getActiveElements();

        $this->sem_create_perm = in_array(Config::get()->SEM_CREATE_PERM, ['root', 'admin', 'dozent'])
            ? Config::get()->SEM_CREATE_PERM
            : 'dozent';

        $sidebar = Sidebar::get();

        /*
            Order of elements:
            * Navigation
            * selected filters (configurable)
            * selected actions widget
            * view filter (configurable)
            * export
        */

        if ($GLOBALS['perm']->have_perm($this->sem_create_perm)) {
            $actions = new ActionsWidget();
            $actions->addLink(
                _('Neue Veranstaltung anlegen'),
                  URLHelper::getURL('dispatch.php/course/wizard'),
                  Icon::create('add')
            )->asDialog('size=50%');
            $actions->addLink(
                _('Diese Seitenleiste konfigurieren'),
                URLHelper::getURL('dispatch.php/admin/courses/sidebar'),
                Icon::create('admin')
            )->asDialog();


            $sidebar->addWidget($actions, 'links');
        }

        $filter = new OptionsWidget(_('Filter'));
        $filter->setId('admin-filter-widget');

        /*
            Now draw the configurable elements according
            to the values inside the visibleElements array.
        */
        if (!empty($visibleElements['search'])) {
            $this->setSearchWiget();
        }
        if (!empty($visibleElements['institute'])) {
            $filter->addElement($this->getInstSelector());
        if (!empty($visibleElements['semester'])) {
            $filter->addElement($this->getSemesterSelector());
        if (!empty($visibleElements['stgteil'])) {
            $filter->addElement($this->getStgteilSelector());
        if (!empty($visibleElements['courseType'])) {
            $filter->addElement($this->getCourseTypeWidget());
        if (!empty($visibleElements['teacher'])) {
            $filter->addElement($this->getTeacherWidget());
        $sidebar->addWidget($filter, 'filter');

        //if there are datafields in the list, draw their input fields, too:
Moritz Strohm's avatar
Moritz Strohm committed
        if (!empty($visibleElements['datafields'])) {
            //The datafields entry contains an array with datafield-IDs.
            //We must fetch them from the database and show an appropriate widget
            //for each datafield.

            $visibleDatafieldIds = $visibleElements['datafields'];

            $datafields = DataField::getDataFields('sem');

            if ($datafields) {
                foreach ($datafields as $datafield) {
                    if (in_array($datafield->id, $visibleDatafieldIds)) {
                        $widget = $this->getDatafieldWidget($datafield);

                        if ($widget) {
                            $sidebar->addWidget($widget);
                        }
                    }
                }
            }
        }

        //this shall be visible in every case:

        //"export as Excel" is always visible:
        if ($this->sem_create_perm) {
            $params = [];

            if ($GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT) {
                $params['search'] = $GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT;
            }
            $export = new ExportWidget();
            $export->addLink(
                _('Als CSV-Datei exportieren'),
                 URLHelper::getURL('dispatch.php/admin/courses/export_csv', $params),
                 Icon::create('file-excel')
            )->asDialog('size=auto');
            $sidebar->addWidget($export);
        }

        foreach (PluginEngine::getPlugins(AdminCourseWidgetPlugin::class) as $plugin) {
            foreach ($plugin->getWidgets() as $name => $widget) {
                $position = $widget->getPositionInSidebar();
                if ($position) {
                    $sidebar->insertWidget($widget, $position, $name);
                } else {
                    $sidebar->addWidget($widget, $name);
                }
            }
        }
    }


    /**
     * Common tasks for all actions
     *
     * @param String $action Called action
     * @param Array  $args   Possible arguments
     */
    public function before_filter(&$action, &$args)
    {
        parent::before_filter($action, $args);

        if ($GLOBALS['perm']->have_perm('admin')) {
            Navigation::activateItem('/browse/my_courses/list');
        } else {
            Navigation::activateItem('/browse/admincourses');
        }

        // we are defintely not in an lecture or institute
        closeObject();

        //delete all temporary permission changes
        if (is_array($_SESSION)) {
            foreach (array_keys($_SESSION) as $key) {
                if (strpos($key, 'seminar_change_view_') === 0) {
                    unset($_SESSION[$key]);
                }
            }
        }

        $this->insts = Institute::getMyInstitutes($GLOBALS['user']->id);

        if (empty($this->insts) && !$GLOBALS['perm']->have_perm('root')) {
            PageLayout::postError(_('Sie wurden noch keiner Einrichtung zugeordnet'));
        }

        // Semester selection
        if ($GLOBALS['user']->cfg->MY_COURSES_SELECTED_CYCLE) {
            $this->semester = Semester::find($GLOBALS['user']->cfg->MY_COURSES_SELECTED_CYCLE);
        }

        if (Request::get('reset-search')) {
            $GLOBALS['user']->cfg->delete('ADMIN_COURSES_SEARCHTEXT');
        }

        PageLayout::setHelpKeyword('Basis.Veranstaltungen');
        PageLayout::setTitle(_('Verwaltung von Veranstaltungen und Einrichtungen'));
        // Add admission functions.
        PageLayout::addScript('studip-admission.js');
    }

    /**
     * Show all courses with more options
     */
    public function index_action()
    {
        $this->fields = $this->getViewFilters();
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->sortby = $GLOBALS['user']->cfg->MEINE_SEMINARE_SORT ?? (Config::get()->IMPORTANT_SEMNUMBER ? 'number' : 'name');
        $this->sortflag = $GLOBALS['user']->cfg->MEINE_SEMINARE_SORT_FLAG ?? 'ASC';

        $this->buildSidebar();

        PageLayout::addHeadElement('script', [
            'type' => 'text/javascript',
        ], sprintf(
              'window.AdminCoursesStoreData = %s;',
              json_encode($this->getStoreData())
        ));
    }

    private function getStoreData(): array
    {
        $configuration = User::findCurrent()->getConfiguration();

        $institut_id = $configuration->MY_INSTITUTES_DEFAULT && $configuration->MY_INSTITUTES_DEFAULT !== 'all'
                     ? $configuration->MY_INSTITUTES_DEFAULT
                     : null;

        $filters = array_merge(
            array_merge(...PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'getFilters')),
            $this->getDatafieldFilters(),
            [
                'institut_id'    => $institut_id,
                'search'         => $configuration->ADMIN_COURSES_SEARCHTEXT,
                'semester_id'    => $configuration->MY_COURSES_SELECTED_CYCLE,
                'course_type'    => $configuration->MY_COURSES_TYPE_FILTER,
                'stgteil'        => $configuration->MY_COURSES_SELECTED_STGTEIL,
                'teacher_filter' => $configuration->ADMIN_COURSES_TEACHERFILTER,
            ]
        );

        return [
            'setActivatedFields' => $this->getFilterConfig(),
            'setActionArea' => $configuration->MY_COURSES_ACTION_AREA ?? '1',
        ];
    }

    private function getDatafieldFilters(): array
    {
        $visibleElements = $this->getActiveElements();
        if (empty($visibleElements['datafields'])) {
            return [];
        }

        $datafields = DataField::getDataFields('sem');
        $config = $GLOBALS['user']->cfg->ADMIN_COURSES_DATAFIELDS_FILTERS;
        $datafields = array_filter($datafields, function (Datafield $datafield) use ($visibleElements, $config) {
            return in_array($datafield->id, $visibleElements['datafields'])
                && isset($config[$datafield->id]);
        });
        $result = [];
        foreach ($datafields as $datafield) {
            $result["df_{$datafield->id}"] = $config[$datafield->id];
        }
        return $result;
    }
        $filter = AdminCourseFilter::get();
        if (Request::option('course_id')) { //we have only one course and want to see if that course is part of the result set
            $filter->query->where('course_id', 'seminare.Seminar_id = :course_id', ['course_id' => Request::option('course_id')]);
        PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'applyFilters', $filter);

        $count = $filter->countCourses();
        if ($count > $this->max_show_courses && !Request::submitted('without_limit')) {
            $this->render_json([
                'count' => $count
            ]);
            return;
        }
        $courses = AdminCourseFilter::get()->getCourses();

        $data = [
            'data' => []
        if (Request::submitted('activated_fields')) {
            $GLOBALS['user']->cfg->store('MY_COURSES_ADMIN_VIEW_FILTER_ARGS', json_encode(Request::getArray('activated_fields')));
        }
        $activated_fields = $this->getFilterConfig();

        $GLOBALS['user']->cfg->store('MY_COURSES_ACTION_AREA', Request::option('action'));
            if ($course->parent && !Request::option('course_id')) {
                if (!in_array($course->parent->id, $course_ids)) {
                    $data['data'][] = $this->getCourseData($course->parent, $activated_fields);
                    $course_ids[] = $course->parent->id;
                }
                if (!in_array($course->id, $course_ids)) {
                    $data['data'][] = $this->getCourseData($course, $activated_fields);
                    $course_ids[] = $course->id;
                }
                if (!in_array($course->id, $course_ids)) {
                    $data['data'][] = $this->getCourseData($course, $activated_fields);
                    $course_ids[] = $course->id;
                }
                foreach ($course->children as $childcourse) {
                    if (!in_array($childcourse->id, $course_ids)) {
                        $data['data'][] = $this->getCourseData($childcourse, $activated_fields);
                        $course_ids[] = $childcourse->id;
                    }
            }
        }
        $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'] . '/app/views');
        switch ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA) {
            case 1:
            case 2:
            case 3:
            case 4:
                break;
            case 8: //Sperrebenen
                $template = $tf->open('admin/courses/lock_preselect');
                $template->course = $course;
                $template->all_lock_rules = new SimpleCollection(array_merge(
                    [[
                        'name'    => '--' . _('keine Sperrebene') . '--',
                        'lock_id' => 'none'
                    ]],
                    LockRule::findAllByType('sem')
                ));
                $data['buttons_top'] = $template->render();
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(_('Sperrebenen'), 'locking_button', ['formaction' => URLHelper::getURL('dispatch.php/admin/courses/set_lockrule')]);
                break;
            case 9: //Sichtbarkeit
                $data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(_('Sichtbarkeit'), 'visibility_button', ['formaction' => URLHelper::getURL('dispatch.php/admin/courses/set_visibility')]);
                break;
            case 10: //Zusatzangaben
                $template = $tf->open('admin/courses/aux_preselect');
                $template->course = $course;
                $template->aux_lock_rules = AuxLockRule::findBySQL('1 ORDER BY name ASC');
                $data['buttons_top'] = $template->render();
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(_('Zusatzangaben'), 'aux_button', ['formaction' => URLHelper::getURL('dispatch.php/admin/courses/set_aux_lockrule')]);
                break;
            case 11: //Veranstaltung kopieren
                break;
            case 14: //Zugangsberechtigungen
                break;
            case 16: //Löschen
                $data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(_('Löschen'), 'deleting_button', ['formaction' => URLHelper::getURL('dispatch.php/course/archive/confirm')]);
                break;
            case 17: //Gesperrte Veranstaltungen
                $data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(_('Einstellungen speichern'), 'locking_button', ['formaction' => URLHelper::getURL('dispatch.php/admin/courses/set_locked')]);
                break;
            case 18: //Startsemester
                break;
            case 19: //LV-Gruppen
                break;
            case 20: //Notiz
                break;
            case 21: //Mehrfachzuordnung Studienbereiche
                $data['buttons_top'] = '<label>' . _('Alle auswählen') .
                    '<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(
                    _('Mehrfachzuordnung von Studienbereichen'), 'batch_assign_semtree',
                    [
                        'formaction' => URLHelper::getURL('dispatch.php/admin/tree/batch_assign_semtree'),
                        'data-dialog' => 'size=big'
                    ]);
            case 22: //Mehrfachzuordnung Studienbereiche
                $data['buttons_top'] = '<label>' . _('Alle auswählen') .
                    '<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
                $data['buttons_bottom'] = (string) \Studip\Button::createAccept(
                    _('Teilnehmendenexport'), 'batch_export_members',
                    [
                        'formaction' => URLHelper::getURL('dispatch.php/admin/user/batch_export_members'),
                        'data-dialog' => 'size=big'
                    ]);
                break;
            default:
                foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) {
                    if ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA === get_class($plugin)) {
                        $multimode = $plugin->useMultimode();
                        if ($multimode) {
                            $data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>';
                            if ($multimode instanceof Flexi_Template) {
                                $data['buttons_bottom'] = $multimode->render();
                            } elseif ($multimode instanceof \Studip\Button) {
                                $data['buttons_bottom'] = (string) $multimode;
                            } elseif (is_string($multimode)) {
                                $data['buttons_bottom'] = (string) \Studip\Button::create($multimode, '', ['formaction' => $plugin->getAdminActionURL()]);
                            } else {
                                $data['buttons_bottom'] = (string) \Studip\Button::create(_('Speichern'), '', ['formaction' => $plugin->getAdminActionURL()]);
                            }
                        }
                    }
                }
        }
        if (!isset($data['buttons_top'])) {
            $data['buttons_top'] = '';
        }
        if (!isset($data['buttons_bottom'])) {
            $data['buttons_bottom'] = '';
        }
    private function processFilters(): void
    {
        $filters = Request::getArray('filters');
        $config = User::findCurrent()->getConfiguration();

        // Simple filters
        $mapping = [
            'search'         => 'ADMIN_COURSES_SEARCHTEXT',
            'semester_id'    => 'MY_COURSES_SELECTED_CYCLE',
            'stgteil'        => 'MY_COURSES_SELECTED_STGTEIL',
            'teacher_filter' => 'ADMIN_COURSES_TEACHERFILTER',
            'course_type'    => 'MY_COURSES_TYPE_FILTER',
            'institut_id'    => 'MY_INSTITUTES_DEFAULT',
        ];

        foreach ($mapping as $key => $field) {
            if (isset($filters[$key])) {
                $config->store($field, $filters[$key]);
            }

            unset($filters[$key]);
        }

        // Datafield filters
        $activeSidebarElements = $this->getActiveElements();

        $datafields_filters = $GLOBALS['user']->cfg->ADMIN_COURSES_DATAFIELDS_FILTERS;
        foreach (DataField::getDataFields('sem') as $datafield) {
            $key = "df_{$datafield->id}";

            if (
                !empty($filters[$key])
                && in_array($datafield->id, $activeSidebarElements['datafields'])
            ) {
                $datafields_filters[$datafield->id] = $filters[$key];
            } else {
                unset($datafields_filters[$datafield->id]);
            }
        }
        $config->store('ADMIN_COURSES_DATAFIELDS_FILTERS', $datafields_filters);

        // Plugin filters
        foreach (PluginEngine::getPlugins(AdminCourseWidgetPlugin::class) as $plugin) {
            $plugin_filters = array_intersect_key(
                $filters,
                $plugin->getFilters()
            );
            $plugin->setFilters($plugin_filters);
        }
    }

    protected function getCourseData(Course $course, $activated_fields)
    {
        $d = [
            'id' => $course->id,
            'parent_course' => $course->parent_course
        ];
        if (in_array('name', $activated_fields)) {
            $params = tooltip2(_('Veranstaltungsdetails anzeigen'));
            $params['style'] = 'cursor: pointer';
            $d['name'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">'
                . htmlReady($course->name)
                .'</a> '
                .'<a href="'.URLHelper::getLink('dispatch.php/course/details/index/'. $course->id).'" data-dialog><button class="undecorated">'.Icon::create('info-circle', Icon::ROLE_INACTIVE)->asImg($params).'</button></a> '
                .(!$course->visible ? _('(versteckt)') : '');
        }
        if (in_array('number', $activated_fields)) {
            $d['number'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">'
                .$course->veranstaltungsnummer
                .'</a>';
        }
        if (in_array('avatar', $activated_fields)) {
            $d['avatar'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">'
                .CourseAvatar::getAvatar($course->getId())->getImageTag(Avatar::SMALL, ['title' => $course->name])
                ."</a>";
        }
        if (in_array('type', $activated_fields)) {
            $semtype = $course->getSemType();
            $d['type'] = $semtype['name'];
        }
        if (in_array('room_time', $activated_fields)) {
            $seminar = new Seminar($course);
            $d['room_time'] = $seminar->getDatesHTML([
                'show_room'   => true,
            ]) ?: _('nicht angegeben');
        }
        if (in_array('semester', $activated_fields)) {
            $d['semester'] = $course->semester_text;
        }
        if (in_array('institute', $activated_fields)) {
            $d['institute'] = $course->home_institut ? $course->home_institut->name : $course->institute;
        }
        if (in_array('requests', $activated_fields)) {
            $d['requests'] = '<a href="'.URLHelper::getLink('dispatch.php/course/room_requests', ['cid' => $course->id]).'">'.count($course->room_requests)."</a>";
        }
        if (in_array('teachers', $activated_fields)) {
            $teachers = $this->getTeacher($course->id);
            $teachers = array_map(function ($teacher) {
                return '<a href="'.URLHelper::getLink('dispatch.php/profile', ['username' => $teacher['username']]) .'">'. htmlReady($teacher['fullname']).'</a>';
            }, $teachers);
            $d['teachers'] = implode(', ', $teachers);
        }
        if (in_array('members', $activated_fields)) {
            $d['members'] = '<a href="'.URLHelper::getLink('dispatch.php/course/members', ['cid' => $course->id]).'">'
                .$course->countMembersWithStatus('user autor')
                .'</a>';
        }
        if (in_array('waiting', $activated_fields)) {
            $d['waiting'] = '<a href="'.URLHelper::getLink('dispatch.php/course/members', ['cid' => $course->id]).'">'
                .$course->getNumWaiting()
                .'</a>';
        }
        if (in_array('preliminary', $activated_fields)) {
            $d['preliminary'] = '<a href="'.URLHelper::getLink('dispatch.php/course/members', ['cid' => $course->id]).'">'
                .$course->getNumPrelimParticipants()
                .'</a>';
        }
        if (in_array('contents', $activated_fields)) {
            $icons = [];
            foreach ($course->tools as $tool) {
                $module = $tool->getStudipModule();
                if ($module) {
                    $last_visit = object_get_visit($course->id, $module->getPluginId());
                    $nav = $module->getIconNavigation($course->id, $last_visit, $GLOBALS['user']->id);
                    if (isset($nav) && $nav->isVisible(true)) {
                        $icons[] = $nav;
                    }
                }
            }
            $d['contents'] = '<div class="icons">
                <ul class="my-courses-navigation">';

            foreach ($icons as $icon) {
                $d['contents'] .= '<li class="my-courses-navigation-item '. ($icon->getImage()->signalsAttention() ? 'my-courses-navigation-important' : '').'">
                        <a href="'. URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id, 'redirect_to' => $icon->getURL()]).'"'. ($icon->getTitle() ? ' title="'.htmlReady($icon->getTitle()).'"' : '') .'>
                            '. $icon->getImage()->asImg(20) .'
                        </a>
                    </li>';
            }
            $d['contents'] .= '</ul></div>';
        }
        if (in_array('last_activity', $activated_fields)) {
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
            $last_activity = lastActivity($course->id);
            $d['last_activity'] = strftime('%x', $last_activity);
            $d['last_activity_raw'] = $last_activity;
        foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
            foreach ($plugin->adminAvailableContents() as $index => $label) {
                if (in_array($plugin->getPluginId() . '_' . $index, $activated_fields)) {
                    $content = $plugin->adminAreaGetCourseContent($course, $index);
                    $d[$plugin->getPluginId()."_".$index] = $content instanceof Flexi_Template ? $content->render() : $content;
                }
            }
        }
        $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'].'/app/views');
        switch ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA) {
            case 1:
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Grunddaten'),
                    URLHelper::getURL('dispatch.php/course/basicdata/view', ['cid' => $course->id]),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 2:
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Studienbereiche'),
                    URLHelper::getURL('dispatch.php/course/study_areas/show', ['cid' => $course->id, 'from' => 'admin/courses']),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 3:
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Zeiten/Räume'),
                    URLHelper::getURL('dispatch.php/course/timesrooms/index', ['cid' => $course->id, 'cmd' => 'applyFilter']),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 4:
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Raumanfragen'),
                    URLHelper::getURL('dispatch.php/course/room_requests/index', ['cid' => $course->id, 'origin' => 'admin_courses']),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 8: //Sperrebenen
                $template = $tf->open('admin/courses/lock');
                $template->course = $course;
                $template->aux_lock_rules = AuxLockRule::findBySQL('1 ORDER BY name ASC');
                $template->all_lock_rules = new SimpleCollection(array_merge(
                    [[
                        'name'    => '--' . _('keine Sperrebene') . '--',
                        'lock_id' => 'none'
                    ]],
                    LockRule::findAllByType('sem')
                ));
                $d['action'] = $template->render();
                break;
            case 9: //Sichtbarkeit
                $d['action'] = '<input type="hidden" name="all_sem[]" value="'.htmlReady($course->id).'"><input type="checkbox" name="visibility['.$course->id.']" '.($course->visible ? ' checked ' : '').'value="1">';
                break;
            case 10: //Zusatzangaben
                $template = $tf->open('admin/courses/aux-select');
                $template->course = $course;
                $template->aux_lock_rules = AuxLockRule::findBySQL('1 ORDER BY name ASC');
                $d['action'] = $template->render();
                break;
            case 11: //Veranstaltung kopieren
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Kopieren'),
                    URLHelper::getURL('dispatch.php/course/wizard/copy/' . $course->id),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 14: //Zugangsberechtigungen
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Zugangsberechtigungen'),
                    URLHelper::getURL('dispatch.php/course/admission', ['cid' => $course->id]),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 16: //Löschen
                $d['action'] = '<input type="checkbox" name="archiv_sem[]" value="'.htmlReady($course->id).'" aria-label="'.htmlReady(sprintf(_('Veranstaltung %s löschen'), $course->getFullName())).'">';
                break;
            case 17: //Gesperrte Veranstaltungen
                $cs = CourseSet::getSetForCourse($course->id);
                if ($cs) {
                    $locked = true;
                    $disabled = !$cs->hasAdmissionRule('LockedAdmission');
                $d['action'] = '<input type="hidden" name="all_sem[]" value="'.htmlReady($course->id).'"><input type="checkbox" name="admission_locked['.$course->getId().']" '.($locked ? 'checked' : '').' '.($disabled ? 'disabled' : '').' value="1" aria-label="'.htmlReady(sprintf(_('Veranstaltung %s sperren'), $course->getFullName())).'">';
                break;
            case 18: //Startsemester
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('Startsemester'),
                    URLHelper::getURL('dispatch.php/course/timesrooms/editSemester', ['cid' => $course->id, 'origin' => 'admin_courses']),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 19: //LV-Gruppen
                $d['action'] = (string) \Studip\LinkButton::create(
                    _('LV-Gruppen'),
                    URLHelper::getURL('dispatch.php/course/lvgselector', ['cid' => $course->id, 'from' => 'admin/courses']),
                    ['data-dialog' => '', 'role' => 'button']
                );
                break;
            case 20: //Notiz
                $method = $course->config->COURSE_ADMIN_NOTICE ? 'createHasNotice' : 'createHasNoNotice';
                $d['action'] = (string) \Studip\LinkButton::$method(
                    _('Notiz'),
                    URLHelper::getURL('dispatch.php/admin/courses/notice/'.$course->id),
                    [
                        'data-dialog' => 'size=auto',
                        'title' => $course->config->COURSE_ADMIN_NOTICE,
                        'role' => 'button'
                    ]
                );
                break;
            case 21: //Mehrfachzuweisung Studienbereiche
                $template = $tf->open('admin/courses/batch_assign_semtree');
                $template->course = $course;
                $d['action'] = $template->render();
                break;
            case 22: //Masssenexport Teilnehmendendaten
                $template = $tf->open('admin/courses/batch_export_members');
                $template->course = $course;
                $d['action'] = $template->render();
                break;
            default:
                foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) {
                    if ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA === get_class($plugin)) {
                        $output = $plugin->getAdminCourseActionTemplate($course->getId());
                        $d['action'] = $output instanceof Flexi_Template ? $output->render() : (string) $output;
                    }
                }
        }
        $d['completion'] = $course->completion;
        return $d;
    }
    /**
     * This action just stores the new settings for sorting the table of courses.
     * @return void
     */
    public function sort_action()
    {
        if (Request::isPost()) {
            $GLOBALS['user']->cfg->store('MEINE_SEMINARE_SORT', Request::get('sortby'));
            $GLOBALS['user']->cfg->store('MEINE_SEMINARE_SORT_FLAG', Request::get('sortflag'));
        }
        $this->render_nothing();
    }


    /**
     * The sidebar action is responsible for showing a dialog
     * that lets the user configure what elements of the sidebar are visible
     * and which will be invisible.
     *
     * @return null This method does not return any value.
     */
    public function sidebar_action()
    {
        if (Request::get('updateConfig', false)) {
            /*
                The user has changed the configuration.
                Collect the activated elements:
            */

            $searchActive = Request::get('searchActive');
            $instituteActive = Request::get('instituteActive');
            $semesterActive = Request::get('semesterActive');
            $stgteilActive = Request::get('stgteilActive');
            $courseTypeActive = Request::get('courseTypeActive');
            $teacherActive = Request::get('teacherActive');
            $activeDatafields = Request::getArray('activeDatafields');

            /*
                Update or create an entry for the current user
                in the user configuration table.
            */
            $activeArray = [];
            if ($searchActive) {
                $activeArray['search'] = true;
            }
            if ($instituteActive) {
                $activeArray['institute'] = true;
            }
            if ($semesterActive) {
                $activeArray['semester'] = true;
            }
            if ($stgteilActive) {
                $activeArray['stgteil'] = true;
            }
            if ($courseTypeActive) {
                $activeArray['courseType'] = true;
            }
            if ($teacherActive) {
                $activeArray['teacher'] = true;
            }

            if ($activeDatafields) {
                $activeArray['datafields'] = $activeDatafields;
            }

            //store the configuration value:
            $this->setActiveElements($activeArray);

            $this->redirect('admin/courses/index');
        } else {
            /*
                The user accesses the page to check the current configuration.
            */

            $this->datafields = DataField::getDataFields('sem');

            $this->userSelectedElements = $this->getActiveElements();

            //add the last activity for each Course object:
            $this->lastActivities = [];
        }
    }

    public function get_stdgangteil_selector_action($institut_id)
    {
        $selector = $this->getStgteilSelector($institut_id);
        $this->render_text($selector->render());
    }

    public function get_teacher_selector_action($institut_id)
    {
        $selector = $this->getTeacherWidget($institut_id);
        $this->render_text($selector->render());

    /**
     * Export action
     */
    public function export_csv_action()
    {
        $filter_config = Request::getArray('fields');

        if (count($filter_config) > 0) {
            $filter = AdminCourseFilter::get();
            PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'applyFilters', $filter);
            $courses = $filter->getCourses();

            $view_filters = $this->getViewFilters();

            $data = [];

            foreach ($courses as $course) {
                $sem = new Seminar($course);
                $row = [];

                if (in_array('number', $filter_config)) {
                    $row['number'] = $course['VeranstaltungsNummer'];
                }

                if (in_array('name', $filter_config)) {
                }

                if (in_array('type', $filter_config)) {
                    $row['type'] = sprintf(
                        '%s: %s',
                        $course->getSemClass()['name'],
                        $course->getSemType()['name']
                    );
                }

                if (in_array('room_time', $filter_config)) {
                    $_room = $sem->getDatesExport([
                        'semester_id' => $this->semester->id,
                        'show_room' => true
                    ]);
                    $row['room_time'] = $_room ?: _('nicht angegeben');
                }

                if (in_array('requests', $filter_config)) {
                    $row['requests'] = $course->room_requests->count();
                }

                if (in_array('teachers', $filter_config)) {
                        array_map(
                            function ($d) {
                                return $d->getUserFullName();
                            },
                            CourseMember::findByCourseAndStatus($course->id, 'dozent')
                        )
                }

                if (in_array('members', $filter_config)) {
                    $row['members'] = $course->getNumParticipants();
                }

                if (in_array('waiting', $filter_config)) {
                    $row['waiting'] = $course->getNumWaiting();
                }

                if (in_array('preliminary', $filter_config)) {
                    $row['preliminary'] = $course->getNumPrelimParticipants();
                }

                if (in_array('last_activity', $filter_config)) {
                    $row['last_activity'] = strftime('%x', lastActivity($course->id));
                }

                if (in_array('semester', $filter_config)) {
                    $row['semester'] = $course->getTextualSemester();
                    $row['institute'] = $course->home_institut ? (string) $course->home_institut['name'] : $course['institut_id'];
                foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) {
                    foreach ($plugin->adminAvailableContents() as $index => $label) {
                        if (in_array($plugin->getPluginId() . "_" . $index, $filter_config)) {
                            $content = $plugin->adminAreaGetCourseContent($course, $index);
                            $row[$plugin->getPluginId() . "_" . $index] = strip_tags(is_a($content, 'Flexi_Template')
                                ? $content->render()
                                : $content
                            );
                        }
                    }
                }

            }

            $captions = [];
            foreach ($filter_config as $index) {