diff --git a/app/controllers/calendar/calendar.php b/app/controllers/calendar/calendar.php index 939b9d32aef399639c5388859fd54a1b8459e586..7f3cff84f518a14b5bebd5b2eb19695605dc0888 100644 --- a/app/controllers/calendar/calendar.php +++ b/app/controllers/calendar/calendar.php @@ -86,7 +86,7 @@ class Calendar_CalendarController extends AuthenticatedController { $tmpl_factory = $this->get_template_factory(); - $filters = new OptionsWidget(); + $filters = new SidebarWidget(); $filters->setTitle('Auswahl'); $tmpl = $tmpl_factory->open('calendar/single/_jump_to'); @@ -99,6 +99,7 @@ class Calendar_CalendarController extends AuthenticatedController $tmpl->action_url = $this->url_for(); $tmpl->category = $this->category; $filters->addElement(new WidgetElement($tmpl->render())); + Sidebar::get()->addWidget($filters); if (Config::get()->CALENDAR_GROUP_ENABLE || Config::get()->COURSE_CALENDAR_ENABLE) { @@ -107,14 +108,16 @@ class Calendar_CalendarController extends AuthenticatedController $tmpl->action_url = $this->url_for('calendar/group/switch'); $tmpl->view = $this->action; $filters->addElement(new WidgetElement($tmpl->render())); - $filters->addCheckbox(_('Abgelehnte Termine anzeigen'), - $this->settings['show_declined'], - $this->url_for($this->base . 'show_declined', - ['show_declined' => 1]), - $this->url_for($this->base . 'show_declined', - ['show_declined' => 0])); + + $settings = new OptionsWidget(); + $settings->addCheckbox( + _('Abgelehnte Termine anzeigen'), + $this->settings['show_declined'] ?? false, + $this->url_for($this->base . 'show_declined', ['show_declined' => 1]), + $this->url_for($this->base . 'show_declined', ['show_declined' => 0]) + ); + Sidebar::get()->addWidget($settings); } - Sidebar::get()->addWidget($filters); } public function index_action() diff --git a/app/controllers/oer/endpoints.php b/app/controllers/oer/endpoints.php index 7349d240d66c96421a6b95a8a94cb82e3c47db07..25160a628464292fa159a47bd3a3f44deef1f62f 100755 --- a/app/controllers/oer/endpoints.php +++ b/app/controllers/oer/endpoints.php @@ -5,6 +5,20 @@ class Oer_EndpointsController extends StudipController protected $with_session = true; //we do need to have a session for this controller + public function before_filter(&$action, &$args) + { + parent::before_filter($action, $args); + if ( + !Config::get()->OERCAMPUS_ENABLED + || ( + Config::get()->OER_PUBLIC_STATUS !== 'nobody' + && !$GLOBALS['perm']->have_perm(Config::get()->OER_PUBLIC_STATUS) + ) + ) { + throw new AccessDeniedException(); + } + } + public function index_action() { $this->controllerreflection = new ReflectionClass($this); diff --git a/app/controllers/profile.php b/app/controllers/profile.php index c5a136f78bce1b1c25ba17081a31a2c65234edd1..6ee759a88a4e4b451bfdcd745c1963f3b7cdbeed 100644 --- a/app/controllers/profile.php +++ b/app/controllers/profile.php @@ -142,12 +142,12 @@ class ProfileController extends AuthenticatedController $this->questionnaires = $response->body; } - // Hier werden Lebenslauf, Hobbys, Publikationen und Arbeitsschwerpunkte ausgegeben: + // Hier werden Lebenslauf, Hobbys, Publikationen und Schwerpunkte ausgegeben: $ausgabe_felder = [ 'lebenslauf' => _('Lebenslauf'), 'hobby' => _('Hobbys'), 'publi' => _('Publikationen'), - 'schwerp' => _('Arbeitsschwerpunkte'), + 'schwerp' => _('Schwerpunkte'), ]; $ausgabe_inhalt = []; diff --git a/app/controllers/settings/details.php b/app/controllers/settings/details.php index 5f6f738dda5e273b4da23c806257e141f15f721d..5c4f40ff794dd10a0bc279a1be77a640ee641c3c 100644 --- a/app/controllers/settings/details.php +++ b/app/controllers/settings/details.php @@ -32,7 +32,7 @@ class Settings_DetailsController extends Settings_SettingsController PageLayout::setHelpKeyword('Basis.HomepageLebenslauf'); PageLayout::setTitle($this->user->perms == 'dozent' - ? _('Lebenslauf, Arbeitsschwerpunkte und Publikationen bearbeiten') + ? _('Lebenslauf, Schwerpunkte und Publikationen bearbeiten') : _('Lebenslauf bearbeiten')); Navigation::activateItem('/profile/edit/details'); } @@ -109,7 +109,7 @@ class Settings_DetailsController extends Settings_SettingsController 'motto' => _('Motto'), 'hobby' => _('Hobbys'), 'lebenslauf' => _('Lebenslauf'), - 'schwerp' => _('Arbeitsschwerpunkte'), + 'schwerp' => _('Schwerpunkte'), 'publi' => _('Publikationen'), 'oercampus_description' => _('Beschreibung auf dem OER Campus') ]; diff --git a/app/views/calendar/single/_select_calendar.php b/app/views/calendar/single/_select_calendar.php index 6b8ee1a0af23e690f4df85228c50e89defd3a80a..a6d3b07a56abf3ef6c4b8ac789e5ec2f93b4a517 100644 --- a/app/views/calendar/single/_select_calendar.php +++ b/app/views/calendar/single/_select_calendar.php @@ -3,7 +3,7 @@ <section class="hgroup"> <?= _('Kalender') ?> <select class="sidebar-selectlist submit-upon-select" style="width: 16em;" name="range_id"> - <option value="user.<?= get_username() ?>"<?= (get_userid() == $calendar_id ? ' selected' : '') ?>> + <option value="<?= get_userid() ?>"<?= get_userid() === $calendar_id ? ' selected' : '' ?>> <?= _("Eigener Kalender") ?> </option> <? $groups = Calendar::getGroups($GLOBALS['user']->id); ?> diff --git a/app/views/contents/overview/index.php b/app/views/contents/overview/index.php index 155d2a7d85905c2dd2e91f47943eadc1de0e5840..7f79113953115fafd537899a08d567772608b610 100755 --- a/app/views/contents/overview/index.php +++ b/app/views/contents/overview/index.php @@ -1,7 +1,7 @@ <ul class="content-items"> <? foreach ($tiles as $key => $navigation): ?> <? if ($navigation->isVisible() && $key !== 'overview'): ?> - <li class="content-item content-item-courseware"> + <li class="content-item content-item-<?= htmlReady($key) ?>"> <a href="<?= URLHelper::getLink($navigation->getURL()) ?>" class="content-item-link"> <div class="content-item-img-wrapper"> <? if ($navigation->getImage()): ?> diff --git a/app/views/my_institutes/index.php b/app/views/my_institutes/index.php index cff61cea5d2b8f2d1f0415d24810491882f26283..8190a6fe1a941229f8b301f14c98223cb887c2c6 100644 --- a/app/views/my_institutes/index.php +++ b/app/views/my_institutes/index.php @@ -4,8 +4,8 @@ _('Wollen Sie sich aus dem/der %s wirklich austragen?'), htmlReady($flash['name']) ), - $controller->declineURL($flash['inst_id'], ['cmd' => 'kill', 'studipticket' => $flash['studipticket']]), - $controller->declineURL($flash['inst_id'], ['cmd'=> 'back', 'studipticket' => $flash['studipticket']]) + $controller->decline_instURL($flash['inst_id'], ['cmd' => 'kill', 'studipticket' => $flash['studipticket']]), + $controller->decline_instURL($flash['inst_id'], ['cmd'=> 'back', 'studipticket' => $flash['studipticket']]) ) ?> <? endif ?> diff --git a/lib/classes/JsonApi/Routes/Courses/CoursesIndex.php b/lib/classes/JsonApi/Routes/Courses/CoursesIndex.php index bddda07e5b78b53c544a04ebff63f7238fb20b94..fcbad91ca91e1e36e3414ca0daf476a81c697f75 100644 --- a/lib/classes/JsonApi/Routes/Courses/CoursesIndex.php +++ b/lib/classes/JsonApi/Routes/Courses/CoursesIndex.php @@ -10,7 +10,7 @@ use JsonApi\JsonApiController; class CoursesIndex extends JsonApiController { - protected $allowedFilteringParameters = ['q', 'fields', 'semester']; + protected $allowedFilteringParameters = ['q', 'fields', 'semester', 'category', 'scope_choose', 'range_choose']; protected $allowedIncludePaths = [ 'blubber-threads', @@ -92,9 +92,9 @@ class CoursesIndex extends JsonApiController 'q' => '%%%', 'fields' => 'all', // Titel, Lehrende... 'semester' => 'all', // Semester - 'search_sem_category' => null, // SEM_CLASS - 'search_sem_scope_choose' => null, // Studienbereiche - 'search_sem_range_choose' => null, // Einrichtungen, + 'category' => null, // SEM_CLASS + 'scope_choose' => null, // Studienbereiche + 'range_choose' => null, // Einrichtungen, 'combination' => 'OR', // OR|AND ]; @@ -112,8 +112,6 @@ class CoursesIndex extends JsonApiController */ private function searchCourses(\User $user, array $filters) { - require_once 'lib/classes/searchtypes/SearchType.class.php'; - require_once 'lib/classes/searchtypes/SeminarSearch.class.php'; $visibleOnly = !(is_object($GLOBALS['perm']) && $GLOBALS['perm']->have_perm(\Config::Get()->SEM_VISIBILITY_PERM, $user->id)); @@ -123,9 +121,9 @@ class CoursesIndex extends JsonApiController 'quick_search' => $filters['q'], 'qs_choose' => $filters['fields'], 'sem' => $filters['semester'], - 'category' => $filters['search_sem_category'], - 'scope_choose' => $filters['search_sem_scope_choose'], - 'range_choose' => $filters['search_sem_range_choose'], + 'category' => $filters['category'], + 'scope_choose' => $filters['scope_choose'], + 'range_choose' => $filters['range_choose'], ], $visibleOnly ); diff --git a/lib/classes/Seminar.class.php b/lib/classes/Seminar.class.php index aad157b6cde968546415aede2cef4b06bf9826db..b25e17f5ac31ae0f9cf8fd5aea2d18a61048147b 100644 --- a/lib/classes/Seminar.class.php +++ b/lib/classes/Seminar.class.php @@ -1668,7 +1668,7 @@ class Seminar $query = "SELECT CONCAT(seminare.VeranstaltungsNummer, ' ', seminare.name, '(', semester_data.name, ')') FROM seminare LEFT JOIN semester_data ON (seminare.start_time = semester_data.beginn) - WHERE seminare.Seminar_id='$s_id'"; + WHERE seminare.Seminar_id = ?"; $statement = DBManager::get()->prepare($query); $statement->execute([$s_id]); $semlogname = $statement->fetchColumn() ?: sprintf('unknown sem_id: %s', $s_id); diff --git a/lib/classes/sidebar/OptionsWidget.php b/lib/classes/sidebar/OptionsWidget.php index 32aab516d24c22853d5d214919e8668beb5a1836..99efc8ac720bf876335b6dd40e796f6cd8c1bc16 100644 --- a/lib/classes/sidebar/OptionsWidget.php +++ b/lib/classes/sidebar/OptionsWidget.php @@ -75,20 +75,26 @@ class OptionsWidget extends ListWidget */ public function addSelect($label, $url, $name, $options, $selected_option = false, $attributes = []) { - $widget = new SelectWidget($label, $url, $name); - $widget->layout = false; + $option_content = ''; - foreach ($options as $value => $option_label) { - $widget->addElement(new SelectElement($value, $option_label, $value === $selected_option)); + foreach ($options as $value => $option) { + $selected = $value === $selected_option ? 'selected' : ''; + $option_content .= sprintf( + '<option value="%s" %s>%s</option>', + htmlReady($value), + $selected, + htmlReady($option) + ); } - if (isset($widget->attributes) && is_array($widget->attributes)) { - $widget->attributes = array_merge($widget->attributes, $attributes); - } else { - $widget->attributes = $attributes; - } - - $content = $widget->render(); + $content = sprintf( + '<select data-formaction="%s" class="sidebar-selectlist submit-upon-select" name="%s" aria-label="%s" %s>%s</select>', + htmlReady($url), + htmlReady($name), + htmlReady($label), + arrayToHtmlAttributes($attributes), + $option_content + ); $this->addElement(new WidgetElement($content)); } diff --git a/lib/extern/modules/views/persondetails_preview.inc.php b/lib/extern/modules/views/persondetails_preview.inc.php index d60de0849728810ed88c89504ebdba91ae2c2781..01b077a9d81f97b620af692c5255fbcf11f63577 100644 --- a/lib/extern/modules/views/persondetails_preview.inc.php +++ b/lib/extern/modules/views/persondetails_preview.inc.php @@ -37,7 +37,7 @@ foreach ($order as $position) { $data["content"] = str_repeat(_("Das ist mein Lebenslauf.") . " ", 15); break; case "schwerp" : - $data["content"] = str_repeat(_("Das sind meine Arbeitsschwerpunkte.") . " ", 15); + $data["content"] = str_repeat(_("Das sind meine Schwerpunkte.") . " ", 15); break; case "publi" : $data["content"] = str_repeat(_("Das sind meine Publikationen.") . " ", 15); diff --git a/lib/models/Courseware/BlockTypes/Text.php b/lib/models/Courseware/BlockTypes/Text.php index 7edeebc9262e359fb6c77acefbea5587010bdee7..427d02f6bc35ffb87e75bca094ebbbc2983a452f 100755 --- a/lib/models/Courseware/BlockTypes/Text.php +++ b/lib/models/Courseware/BlockTypes/Text.php @@ -46,6 +46,21 @@ class Text extends BlockType public function setPayload($payload): void { + $document = new \DOMDocument(); + $old_libxml_error = libxml_use_internal_errors(true); + $document->loadHTML($payload['text']); + libxml_use_internal_errors($old_libxml_error); + $imageElements = $document->getElementsByTagName('img'); + foreach ($imageElements as $element) { + if (!$element instanceof \DOMElement || !$element->hasAttribute('src')) { + continue; + } + $src = $element->getAttribute('src'); + if (str_contains($src, 'sendfile.php') && !str_contains($src, $GLOBALS['ABSOLUTE_URI_STUDIP'])) { + $find = explode('sendfile.php', $src)[0]; + $payload['text'] = str_replace($find, $GLOBALS['ABSOLUTE_URI_STUDIP'], $payload['text']); + } + } $payload['text'] = \Studip\Markup::purifyHtml(\Studip\Markup::markAsHtml($payload['text'])); parent::setPayload($payload); diff --git a/lib/models/User.class.php b/lib/models/User.class.php index 26b2726106548fadd1e49ffb50cf2f55add4f2e0..249b7f6be1ea1728a37dc3522462a6e8343cd754 100644 --- a/lib/models/User.class.php +++ b/lib/models/User.class.php @@ -877,7 +877,7 @@ class User extends AuthUserMd5 implements Range, PrivacyObject } if ($this->info->schwerp && !$GLOBALS['NOT_HIDEABLE_FIELDS'][$this->perms]['schwerp']) { $homepage_elements['schwerp'] = [ - 'name' => _('Arbeitsschwerpunkte'), + 'name' => _('Schwerpunkte'), 'visibility' => $homepage_visibility['schwerp'] ?: get_default_homepage_visibility($this->id), 'extern' => true, 'identifier' => 'privatedata' diff --git a/lib/navigation/BrowseNavigation.php b/lib/navigation/BrowseNavigation.php index e1788177ece1aef5fcef0e49581121c8c1b7f7da..d250e78ab67c3be914b194cf4874d12e6d3f52ef 100644 --- a/lib/navigation/BrowseNavigation.php +++ b/lib/navigation/BrowseNavigation.php @@ -50,24 +50,23 @@ class BrowseNavigation extends Navigation */ public function initSubNavigation() { - global $user, $perm; - parent::initSubNavigation(); - $sem_create_perm = in_array(Config::get()->SEM_CREATE_PERM, ['root', 'admin', 'dozent']) ? Config::get()->SEM_CREATE_PERM : 'dozent'; - // my courses - if (is_object($user) && $user->id != 'nobody') { + if (User::findCurrent()) { - if ($perm->have_perm('admin')) { + if ($GLOBALS['perm']->have_perm('admin')) { $navigation = new Navigation(_('Administration')); } else { $navigation = new Navigation(_('Meine Veranstaltungen')); } - $navigation->addSubNavigation('list', new Navigation($perm->have_perm('admin') ? _('Veranstaltungsadministration') : _('Aktuelle Veranstaltungen'), 'dispatch.php/my_courses')); + $navigation->addSubNavigation('list', new Navigation( + $GLOBALS['perm']->have_perm('admin') ? _('Veranstaltungsadministration') : _('Aktuelle Veranstaltungen'), + 'dispatch.php/my_courses' + )); - if ($perm->have_perm('admin')) { + if ($GLOBALS['perm']->have_perm('admin')) { $navigation->addSubNavigation('overlapping', new Navigation(_('Überschneidungsfreiheit'), 'dispatch.php/admin/overlapping')); $navigation->addSubNavigation('schedule', new Navigation(_('Veranstaltungs-Stundenplan'), 'dispatch.php/admin/courseplanning')); } else { @@ -83,7 +82,7 @@ class BrowseNavigation extends Navigation $this->addSubNavigation('my_studygroups', $navigation); } - if (!$perm->have_perm('admin')) { + if (!$GLOBALS['perm']->have_perm('admin')) { $navigation = new Navigation(_('Meine Einrichtungen'), 'dispatch.php/my_institutes'); $this->addSubNavigation('my_institutes', $navigation); @@ -93,7 +92,7 @@ class BrowseNavigation extends Navigation } } - if ($perm->have_perm('admin') || ($perm->have_perm('dozent') && Config::get()->ALLOW_DOZENT_COURSESET_ADMIN)) { + if ($GLOBALS['perm']->have_perm('admin') || ($GLOBALS['perm']->have_perm('dozent') && Config::get()->ALLOW_DOZENT_COURSESET_ADMIN)) { $navigation = new Navigation(_('Anmeldesets'), 'dispatch.php/admission/courseset/index'); $this->addSubNavigation('coursesets', $navigation); $navigation->addSubNavigation('sets', new Navigation(_('Anmeldesets verwalten'), 'dispatch.php/admission/courseset/index')); @@ -102,7 +101,7 @@ class BrowseNavigation extends Navigation } // export - if (Config::get()->EXPORT_ENABLE) { + if (Config::get()->EXPORT_ENABLE && $GLOBALS['perm']->have_perm('tutor')) { $navigation = new Navigation(_('Export'), 'export.php'); $this->addSubNavigation('export', $navigation); } diff --git a/public/export.php b/public/export.php index bd97656e72ff5000f70a251e55e94ee41e431503..68bc25ce5fae3bc869bb8b0dc7aae458e1b98675 100644 --- a/public/export.php +++ b/public/export.php @@ -53,9 +53,9 @@ $format = Request::option('format'); $choose = Request::quoted('choose'); $range_id = Request::option('range_id'); -if (($o_mode != "direct") AND ($o_mode != "passthrough")) +if ($o_mode !== 'direct' && $o_mode !== 'passthrough') { - $perm->check("tutor"); + $GLOBALS['perm']->check('tutor'); include ('lib/seminar_open.php'); // initialise Stud.IP-Session } diff --git a/public/plugins_packages/core/ContentsWidget/templates/index.php b/public/plugins_packages/core/ContentsWidget/templates/index.php index b03df2a89201dd707cd018f2cc9fa8aaef1796d7..8b1b794e6f9024d88b3ad033ab900fd9b998842a 100644 --- a/public/plugins_packages/core/ContentsWidget/templates/index.php +++ b/public/plugins_packages/core/ContentsWidget/templates/index.php @@ -5,7 +5,7 @@ <ul class="content-items"> <? foreach ($tiles as $key => $navigation): ?> <? if ($navigation->isVisible() && $key !== 'overview'): ?> - <li class="content-item content-item-courseware"> + <li class="content-item content-item-<?= htmlReady($key) ?>"> <a href="<?= URLHelper::getLink($navigation->getURL()) ?>" class="content-item-link"> <div class="content-item-img-wrapper"> <? if ($navigation->getImage()): ?> diff --git a/public/sendfile.php b/public/sendfile.php index bb6d941cd762abff4720c066beef99fbb5e6f3fc..3ffdd612c9aec630b35c94cea436d13e7dcff820 100644 --- a/public/sendfile.php +++ b/public/sendfile.php @@ -57,7 +57,7 @@ init_i18n($_SESSION['_language']); // Set Base URL, otherwise links will fail on SENDFILE_LINK_MODE = rewrite URLHelper::setBaseURL($GLOBALS['ABSOLUTE_URI_STUDIP']); -$file_id = escapeshellcmd(basename(Request::get('file_id'))); +$file_id = basename(Request::get('file_id')); $type = Request::int('type'); if ($type < 0 || $type > 7) { $type = 0; diff --git a/resources/assets/javascripts/bootstrap/forms.js b/resources/assets/javascripts/bootstrap/forms.js index cd5d239768144e6690bfb6583d2f2ce30efdb708..a88f42c0104c459bf87f4a8ea9719fbc3443b245 100644 --- a/resources/assets/javascripts/bootstrap/forms.js +++ b/resources/assets/javascripts/bootstrap/forms.js @@ -107,6 +107,9 @@ $(document) // Submit only if value has changed and either enter was pressed or // select was opened by click if (!is_default && shouldSubmit) { + if ($(this).data('formaction')) { + $(this.form).attr('action', $(this).data('formaction')); + } $(this.form).submit(); return false; } diff --git a/resources/assets/stylesheets/scss/contents.scss b/resources/assets/stylesheets/scss/contents.scss index d03b831d2e26efa35b4b4bab35d034158a2f61be..0d8abde5c341d03be5eace2289e1514262b167fa 100644 --- a/resources/assets/stylesheets/scss/contents.scss +++ b/resources/assets/stylesheets/scss/contents.scss @@ -44,17 +44,20 @@ padding: 0; .content-item { - background-color: $dark-gray-color-5; - border: solid thin $light-gray-color-40; + align-items: stretch; + background-color: var(--dark-gray-color-5); + border: solid thin var(--light-gray-color-40); + display: flex; height: 150px; + justify-content: stretch; .content-item-link { color: unset; display: grid; + flex: 1; grid-template-columns: 74px auto; grid-gap: 5px; - height: 130px; - padding: 15px 10px 0 10px; + padding: 25px 10px 10px; transition: 0.5s; .content-item-img-wrapper { @@ -63,7 +66,7 @@ .content-item-text { .content-item-title { - color: $base-color; + color: var(--base-color); font-size: 2rem; width: 100%; max-width: 160px; @@ -76,13 +79,13 @@ } &:hover { - background-color: $white; + background-color: var(--white); color: unset; .content-item-link { .content-item-text { .content-item-title { - color: $red; + color: var(--red); } } } diff --git a/resources/vue/components/courseware/CoursewareAudioBlock.vue b/resources/vue/components/courseware/CoursewareAudioBlock.vue index 218f11dc6664352366e9394ac0125c521740068b..8877b4796a3b13204fbc5b1d5fbf1e2201613a4f 100755 --- a/resources/vue/components/courseware/CoursewareAudioBlock.vue +++ b/resources/vue/components/courseware/CoursewareAudioBlock.vue @@ -15,7 +15,7 @@ class="cw-audio-player" ref="audio" @timeupdate="onTimeUpdateListener" - @loadeddata="setDuration" + @durationchange="setDuration" @ended="onEndedListener" /> <div v-if="!emptyAudio" class="cw-audio-container"> @@ -462,9 +462,6 @@ export default { }, onTimeUpdateListener() { this.currentSeconds = this.$refs.audio.currentTime; - if (this.durationSeconds === 0) { - this.setDuration(); - } }, onEndedListener() { this.stopAudio();