Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • alexander.vorwerk/studip
  • hochschule-wismar/stud-ip
  • tleilax/studip
  • marcus/studip
  • manschwa/studip
  • eberhardt/studip
  • uol/studip
  • pluta/studip
  • thienel/extern-uni-b
  • studip/studip
  • strohm/studip
  • uni-osnabrueck/studip
  • FloB/studip
  • universit-t-rostock/studip
  • Robinyyy/studip
  • jakob.diel/studip
  • HyperSpeeed/studip
  • ann/studip
  • nod3zer0/stud-ip-siple-saml-php-plugin
19 results
Show changes
Commits on Source (137)
Showing
with 713 additions and 216 deletions
# 10.11.2023 v 5.4
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.4&state=all
- Sessionhaltung im Cache konfigurierbar machen [#604]
- CLI-Kommando plugin:register soll die Methode PluginAdministration::registerPlugin() verwenden [#702]
- Bibliothek STUDIP.Dialogs entfernen [#1001]
- Tablesorter erlauben, Widgets mitzugeben [#1307]
- Vereinfachung der Raumanfragen [#1327]
- Gruppierung der Veranstaltungen auf "Meine Veranstaltungen" auch nach MVV-Modul ermöglichen [#1498]
- Neuentwicklung Verzeichnisstrukturen [#1664]
- Umstellung von Blubber auf Vue.js und JSONAPI [#1695]
- Die Views in admission um PHP-Doc erweitern [#1808]
- Polishing TIC: Neues Schmuckbild [#1836]
- Hauptordner der Veranstaltung optional für Studierende sperren [#1908]
- Umstellung der Adminseite für Veranstaltungen auf vue.js [#1965]
- Courseware Wizards Zielauswahl intuitiver und übersichtlicher gestalten [#1980]
- Berechtigungs-Übersicht in der Raumverwaltung: Bulk-Aktion zum Löschen von Berechtigungen hinzufügen [#2009]
- RolePersistence fehlt eine Methode, um alle Nutzer mit einer bestimmten Rolle auszulesen [#2014]
- Erweiterung des Galerie Blocks [#2016]
- Erweiterung des Blickfang Blocks [#2017]
- Erweiterung des Dokument Blocks [#2018]
- Änderung des Abschnittstyps ermöglichen [#2019]
- Einheitliche Dimensionen für Blöcke [#2020]
- Vorlagen beim hinzufügen eine Seite anbieten [#2021]
- Bearbeiten von Block Favoriten vereinfachen [#2022]
- Methode User::isBlocked() implementieren [#2025]
- Automatisiertes Eintragen um Filter für Pluginrollen erweitern [#2029]
- RolePersistence erweitern [#2054]
- „Meine Veranstaltungen“: Trennung „Nur neue Inhalte anzeigen“ zwischen normaler und responsiver Darstellung [#2071]
- Möglichkeit schaffen, um sämtliche farbigen Icons außer blau automatisch generieren zu lassen [#2091]
- Grunddaten einer Lerneinheit unmittelbar bearbeiten [#2107]
- StudIPPlugin um öffentliche Methoden zum hinzufügen von Assets erweitern [#2164]
- Polyfill für PHP-Methoden der Versionen 7.3, 7.4 und 8.0 einbinden [#2189]
- Stud.IP-Cache soll generell auch einen MemoryCache zusätzlich verwenden [#2202]
- Möglichkeit schaffen, um eine Aktionsmenü-Darstellung zu forcieren [#2210]
- Courseware Fortschrittsanzeige prominenter platzieren [#2251]
- Datepicker soll die Möglichkeit erhalten, zumindest Feiertage als deaktiviert/nicht wählbar anzuzeigen [#2267]
- LTI-Block für Courseware [#2326]
- SORM: Definition der I18N-Spalten vereinfachen [#2366]
- Vue-Komponente StudipMessageBox soll einen Event feuern, wenn die MessageBox geschlossen wird [#2367]
- Polyfill für PHP-Methoden der Version 8.1 einbinden [#2368]
- Unterstützung für TypeScript [#2376]
- Übersichtsseite "Anmeldesets > Personenlisten" überarbeiten [#2393]
- PageLayout um Methoden erweitern, um sowohl die Sidebar als auch den Footer ausblenden zu können [#2395]
- Smileys ausbauen [#2403]
- JSONAPI: Attribute im Schema sollen auch als Callable angegeben werden können [#2406]
- JsonApi: Warning: link() expects exactly 2 parameters, 0 given [#2424]
- Restrukturierung der Veranstaltungsverwaltung inklusive Mehr-Seite [#2440]
- Sammelmappe für Courseware Abschnitte und Blöcke [#2448]
- Updates der PHP-Bibliotheken (Stud.IP 5.4) [#2452]
- CLI-Kommando "composer:outdated" ergänzen, das Listen wie für #2452 erstellt [#2453]
- Update algo26-matthias/idna-convert - v3.0.5 > v3.1.0 [#2454]
- Update ezyang/htmlpurifier - v4.14.0 > v4.16.0 [#2455]
- Update guzzlehttp/psr7 - 2.4.1 > 2.4.4 [#2456]
- Update jumbojett/openid-connect-php - v0.9.8 > 0.9.10 [#2458]
- Update league/oauth2-server - 8.3.5 > 8.4.1 [#2459]
- Update monolog/monolog - 2.8.0 > 2.9.1 [#2460]
- Update php-di/php-di - 6.3.4 > 6.3.5 [#2461]
- Update phpstan/phpstan - 1.8.5 > 1.10.8 [#2462]
- Update slim/slim - 4.6.1 > 4.8.1 [#2463]
- Update symfony/console - 5.3.16 > 5.4.21 [#2464]
- Update symfony/process - v5.4.11 > v5.4.21 [#2465]
- Update tecnickcom/tcpdf - 6.5.0 > 6.6.2 [#2466]
- Update tuupola/cors-middleware - 1.2.1 > 1.4.3 [#2467]
- Update symfony/yaml - v3.4.47 > v5.4.21 [#2468]
- Einheitliches CSS für Anfasser zum Verschieben [#2469]
- Bibliothek camspiers/json-pretty entfernen [#2470]
- WYSIWYG: Kompakter Editor (Balloon-Editor) [#2474]
- Update spomky-labs/otphp - v8.3.3 > v10.0.3 [#2476]
- Update phpseclib/phpseclib - 2.0.38 > 3.0.19 [#2478]
- Remove php-http/curl-client - 1.7.1 [#2479]
- Bilder-Pool [#2482]
- Courseware: Übersichtsseite über Feedback und Kommentare [#2487]
- Neuanordnung der Block-Hinzufügen-Liste mit Suchfunktion [#2489]
- REST-API: Deprecated-Meldung aktualisieren [#2493]
- Replace gossi/docblock v1.6 > phpowermove/docblock v2.0.1 [#2494]
- CLI-Kommando "cronjobs:execute" interaktiv machen [#2501]
- PHPDoc für SimpleORMap verbessern [#2514]
- I18N Sprachwähler: Icons ohne Nationalflaggen [#2519]
- CKEditor: "Größerziehen des Textfelds" in Dialogen [#2525]
- Auf einer neu angelegten CW Seite ist per Default ein Listenabschnitt [#2531]
- OER Detailansicht von eigenem Material nicht zugänglich [#2538]
- Automatisiertes Eintragen: Möglichkeit schaffen, um das manuelle Eintragen forcieren zu können [#2576]
- Darstellung der Sortierpfeile angleichen [#2580]
- Persönliche Angaben: Text sollte konfigurierbar sein [#2582]
- Barrierefreiheits-Probleme in StEP 1965 [#2595]
- Veranstaltungsadministration: „Bearbeitungsstatus ändern“ funktioniert nicht [#2596]
- Barrierefreiheits-Probleme in StEP 1327 [#2598]
- Barrierefreiheits-Probleme in TIC 1980 [#2599]
- Barrierefreiheits-Probleme in StEP 2009 [#2601]
- Manuelle Buchung von Widerholungsterminen funktioniert nicht [#2602]
- JS-Tests [#2605]
- Sprach-Icons auf Loginseite haben keine festgelegte Größe [#2634]
- Add End-to-end tests using playwright [#2635]
- Barrierefreiheits-Probleme in StEP 1664 [#2639]
- Barrierefreiheits-Probleme in TIC 2489 [#2658]
- Barrierefreiheits-Probleme in StEP 2440 [#2659]
- Geänderter Blubber-Beitrag wird bei anderen Personen nicht aktualisiert [#2661]
- Barrierefreiheits-Mängel in StEP 2448 [#2675]
- Barrierefreiheits-Mangel: Radio-Buttons werden in einer gemeinsamen Gruppe vorgelesen [#2679]
- Barrierefreiheits-Mängel in StEP #1800 [#2681]
- Courseware: LTI-Block: Pflichtfelder sind nicht als solche gekennzeichnet (Barrierefreiheits-Mangel) [#2682]
- Zerhackte Textstrings im Bilder-Pool StEP [#2687]
- Barrierefreiheits-Mängel in StEP #2487 [#2689]
- Sortierelemente in einer Verzeichnisstruktur sind nicht per Tastatur bedienbar [#2691]
- Contentbar in Verzeichnisstrukturen hat Einträge mit einem fehlerhaften übersetzbaren String [#2692]
- Verzeichnisstrukturen: Inhaltsverzeichnis-Icon in der Contentbar wird nur als „Schalter“ vorgelesen [#2693]
- admin/courses: Info-I am Namen der Veranstaltung in der Tabelle mit Veranstaltungen lädt die Seite neu [#2695]
- Barrierefreiheits-Mängel in TIC #2018 [#2700]
- Erhöhen des Mindestanforderungen an Node.js auf v16 [#2703]
- Textstrings-Review für StEP #1327 [#2709]
- Polishing: LESS-Compiler für Plugins deprecaten [#2718]
- PHP8-Warnungen in den Blubber-Routen [#2725]
- Blubber-Kommentare ohne Autor*in [#2726]
- Blubbersuche: Zurücksetzen-Knopf immer sichtbar. [#2727]
- Fehler, wenn der Tablesorter geladen wird [#2728]
- MVV: Fehler beim Drag&Drop-Sortieren [#2730]
- Deprecation-Warnung beim Kompilieren von den Assets [#2736]
- Blaue Icons haben nicht alle dasselbe Blau [#2739]
- API-Änderung in BlockType durch Sammelmappe für Courseware [#2766]
- Nutzung der REST-API in Blubber [#2800]
- CAS-Login ist kaputt (durch Update der PHP-Bibliotheken) [#2820]
- PHP Warnungen in den Fragebögen [#2837]
- Veranstaltungsadminseite bleibt leer für manche Personen [#2838]
- Letzte Aktivität bei Veranstaltung in Adminbereich zeigt '%x' [#2839]
- Adminbereich Plugins können eventuell keinen Aktionsbereich bereitstellen [#2840]
- Undefined callback STUDIP.AdminCourses.App.reloadCourse [#2841]
- Courseware: Nutzer können Elemente aus fremden Merklisten einfügen [#2844]
- AdminCourseAction nicht komplett kompatibel zur neuen Veranstaltungsadminansicht [#2845]
- Link zu Ankündungen/Fragebögen auf "Meine Veranstaltungen" springt in die Verwaltung [#2846]
- Werkzeuge: Info-Dialoge für Plugins zeigen keine Bilder an [#2847]
- Verwaltung: Fehler beim Umschalten der Sichtbarkeit einer LV [#2849]
- Neue Adminseite - Keine Meldung, dass zu viele Veranstaltung im Hintergrund ausgelesen werden. [#2852]
- SQL-Fehler, wenn "Meine Veranstaltungen" nach Studienbereich gruppiert ist [#2854]
- Veranstaltungsverzeichnis kann auch für nicht eingeloggte Personen zugänglich sein und erzeugt nicht den korrekten Link zur Deteilseite von VA [#2859]
- Letzter Schritt des VA-Anlegeassistenten führt zu einer Fehlermeldung [#2861]
- Zusatzangaben: Navigation geht verloren [#2862]
- Gesperrte Benutzer können von Lehrenden in Veranstaltungen eingetragen werden, ohne dass dabei sichtbar wird, dass der Benutzer gesperrt ist [#2864]
- Zusatzangaben: Autoformsaver nicht aktiv [#2866]
- Hobbies-Text wird ohne Warnung und visuelle Indikatoren abgeschnitten und hat nur 255 Zeichen [#2869]
- Studienbereiche - Suche funktioniert nicht [#2870]
- Darstellung der Lehrenden im Vorlesungsverzeichnis [#2876]
- Migration 5.4.6_tree_changes.php [#2880]
- Bilderpool umhängen in Administration -> Standort [#2900]
- Ankündigungen: Dialog hat kein data-secure [#2907]
- Bilderpool erscheint nicht in der Navigation bei der Rolle Admin [#2916]
- Fakultätsadmins bekommen eine Fehlermeldung beim Aufruf der Standortadministration [#2917]
- Fehlermeldung in der Konsole auf der Startseite [#2918]
- Forum: Schreiben von Beiträgen kaputt [#2919]
- JS-TypeError auf der Startseite (vor dem Login) [#2921]
- Verwaltung von Veranstaltungen: unbegrenzte Veranstaltungen werden nicht mehr gefunden, wenn Semester eingestellt ist [#2923]
- Einfügen aus der Merkliste (Sammelmappe) kopiert verknüpfte Dateien nicht in den Kurs [#2933]
- System-Ankündigung: Weitere Bereiche auffindbar, werden aber nicht gespeichert [#2945]
- Funktion "Barriere melden" kaputt [#2949]
- Mehrfachzuordnung der Studienbereiche hat keine Aktion/Selektion [#2955]
- SQL-Fehler beim Löschen von Veranstaltungen [#2963]
- Stud.IP-Cache funktioniert nicht mehr [#2979]
- Mehrfachzuordnung der Studienbereiche wieder im Dialog öffnen [#2999]
- Werkzeuge: Funktionen im Dialog funktionieren nach Anklicken eines Screenshots nicht mehr [#3005]
- Courseware: Nutzer können fremde Elemente in eigene Merkliste einfügen [#3008]
- Fehlermeldungen nach Entfernen der Spalte sem_tree.studip_object_id [#3014]
- Doppelter Klassenname in den Migrationen: AddMissingLogActions [#3036]
- Vorlesungsverzeichnis: Suche sucht nicht (nur) im ausgewählen Bereich [#3041]
- Vorlesungsverzeichnis: Umstellen der Filter setzt die Suche zurück [#3043]
- Vorlesungsverzeichnis: Suche findet versteckte Veranstaltungen [#3046]
- Bearbeiten der Veranstaltungszuordnungen ist unvollständig implementiert [#3054]
- Aufruf vom Veranstaltungs-Stundenplan führt zu Fehler [#3070]
- Verwaltung von Veranstaltungen: Gesperrte Veranstaltungen werden nicht als gesperrt angezeigt [#3071]
- Courseware: Abschnitt bearbeiten zeigt bei Tabs falsche Vorschau an [#3072]
- Widgets aus Plugins zur Adminübersichtsseite haben keinen Startwert [#3084]
- Sortieren von Werkzeugen [#3089]
- Abschnitt verändern: Stil nicht veränderbar bei ausgeklapptem Inhaltsverzeichnis [#3091]
- Bearbeiten einer Raumanfrage [#3101]
- Datetimepicker ist nur noch datepicker ohne time. [#3104]
- Sperrebene in Veranstaltungen kann nicht geändert werden: navigation item 'course/admin/main' not found [#3117]
- Veranstaltungen > Export ist kaputt [#3118]
- Weitere PHP8 - Warnungen / Fehler [#3125]
- Leerzeichen im Klassennamen führt zu Linting-Fehlern [#3129]
- Administration von Veranstaltungen: csv Export wirft Exception [#3141]
- Courseware: Tippfehler im Label des Ziele-Blocks [#3177]
- Fehler auf der JS-Konsole im neuen Veranstaltungsverzeichnis [#3230]
- Eine einzelne Null kann nicht als Blubberkommentar gesendet werden [#3232]
- Initiales Laden des Veranstaltungsverzeichnisses sowie das Suchen dauert lange [#3234]
- Die Methoden in OptionsWidget sollten vorerst keinen Typen erzwingen [#3322]
- Auslieferungszustand der Impressumsseiten reduzieren (Default-Daten) [#3327]
- Bei AdminCourseOptionsWidget senden die Checkboxen immer nur den true-value [#3328]
- CLI-Kommando oauth2:keys ist defekt [#3332]
- Navigationspunkt "Bilder-Pool" enthält überflüssige Angaben [#3360]
- Fehlerhafte SQL-Daten [#3418]
- Kaputtes Layout im Profil bei "Mehr Funktionen" [#3439]
# 02.11.2023 v 5.3.3
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.3.3&state=all
- CKEditor mit mehrsprachiger Eingabe: Toolbar bricht um [#2471]
- Sidebar rutscht beim Öffnen von Dialogen nach unten [#2929]
- Positionierung der Sidebar beim Scrollen gelegentlich falsch [#2930]
- Sidebar rutscht beim Anspringen von Elementen auf der Seite nach unten [#2934]
- Sidebar nur auf der Veranstaltungsübersicht für Admins/Roots scrollbar machen, falls sie zu lang ist [#2936]
- CKEditor: zweite Zeile der Toolbar hat Abstand nach links [#3211]
- CKEditor: Toolbar läuft nach links aus dem Eingabefeld hinaus [#3212]
- PHP-Warnungen in der Detailansicht von Studiengruppen [#3308]
- Fragebögen: linke Navigation schiebt sich aus dem Dialog heraus [#3330]
- Mathematische Formel wird in den Ankündigungen nicht/falsch gerendert [#3362]
- Zusatzangaben: Fehler beim Löschen von Eingaben [#3368]
- Fehlermeldung TypeError: this.initialNavigation is null auf Seiten, die sich nicht in die Navigation einhängen [#3399]
- Fatal Error in ResponsiveHelper, leere Anzeige auf allen Seiten [#3403]
# 02.11.2023 v 5.2.5
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.2.5&state=all
- Paket league/oauth2-server sollte aufgrund eines Sicherheitsupdate aktualisiert werden [#3334]
- Nicht mehr verwendete JS-Dateien der Ankündigungen entfernen [#3351]
- XSS-Schwachstelle bei der globalen Suche [#3353]
# 01.11.2023 v 5.1.6
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.1.6&state=all
- Insecure header validation in slim/psr7 [#3304]
# 01.11.2023 v 5.0.8
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.0.8&state=all
- Dateibereich: „Im OER Campus veröffentlichen“ wird angezeigt, obwohl der OER-Campus erst ab einer höheren Rechtestufe verfügbar ist [#2638]
- Raumverwaltung: Fehler beim Hinzufügen von Dokumenten zu Räumen [#2829]
- Hauptnavigation: Größeres Logo macht Probleme [#2920]
- Kopierte Fragebögen sollen mit „[Kopie]“ am Ende des Titels gekennzeichnet werden [#3198]
- Tutor kann Dozenten austragen [#3250]
- Wert von meta.page.total in der Route /users ist falsch [#3281]
- Ressourcenverwaltung: Löschen eines Attributs löscht die Werte nicht aus der DB [#3282]
- Fatal Error bei Anzeige von Trails_RoutingError [#3284]
- code injection in phpxmlrpc/phpxmlrpc [#3299]
- XML-RPC for PHP allows access to local files via malicious argument to the Client::send method [#3300]
- XML-RPC for PHP's `Wrapper::buildClientWrapperCode` method allows code injection via malicious `$client` argument [#3301]
- XML-RPC for PHP's debugger vulnerable to possible XSS attack [#3302]
- phpxmlrpc vulnerable to argument injection [#3303]
- Regular Expression Denial of Service (ReDoS) in lodash [#3305]
- Command Injection in lodash [#3306]
- CLI-Skript db:migrate-engine wirft einen Fatal Error am Ende [#3335]
- JSON-API: Abfrage nach Gruppen in einer Einrichtung liefert defekten self-Link [#3357]
- Bearbeiten von Raumanfragen öffnet sich nicht in einem Dialog [#3363]
- fehlendes Escaping bei der Anzeige in der globalen Suche [#3366]
- Mail schreiben: QuickSearch zur Empfängersuche erhält alle Felder des Dialoges [#3381]
- Admins mit admin-Rechten in der Raumverwaltung sehen eine Exception in der Übersicht der Raumverwaltung, wenn es eine freie Raumanfrage (ohne Veranstaltungsbezug) gibt [#3385]
- public/assets/images/oernds_oer_use_blue.svg wird nicht verwendet [#3389]
- Migration von 5.0 auf 5.4: Base table or view not found: 1051 Unknown table 'studip_test54.globalsearch_buzzwords' [#3407]
- JSZip-Version ist zu alt [#3410]
# 04.10.2023 v 5.3.2
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.3.2&state=all
- Courseware: Manche Anfasser zum Sortieren funktionieren nicht mit JAWS nicht und alle benutzen eine unpassende Taste zum Aktivieren/Deaktivieren [#1918]
- Weitere PHP8-Warnungen [#2351]
- PHP8 - Warnungen in der Semester-Klasse [#2356]
- Responsive Navigation: Teile der Sidebar nicht ereichbar, wenn sie zu lang ist [#2388]
- Änderungsliste im Wiki unbrauchbar [#2477]
- Icon für "Kompakte Navigation" wird in der Druckansicht angezeigt [#2746]
- CKeditor: Alignmenteinstellungen von Bildern werden ignoriert [#2772]
- Courseware: neu hinzugefügte Seiten werden im Inhaltsverzeichnis nicht immer angezeigt [#2791]
- WYSIWIG Tabellenüberschriften landen unter der Tabelle [#2812]
- Courseware: "Inhaltsverzeichnis" verhält sich beim scrollen unerwartet [#2855]
- Fragetyp Information hat falsches Icon [#2906]
- VUE-Warnungen in den Fragebögen [#2910]
- Manuelle Buchung: Alle Räume werden als Teilraum angezeigt [#2938]
- Tortendiagramme fehlen in Auswertung [#2939]
- Semesterangabe im Titel fehlt nach dem Umbau der HTML-Struktur [#2947]
- data-secure funktioniert nicht mehr für den ckeditor [#2948]
- Arbeitsplatz > Courseware: Tippfehler in der Startanzeige [#2952]
- Fehler in Migration 5.3.14 [#2953]
- CW Mobil Block-Menü Layout Probleme [#2961]
- Terminvergabe: Zu bestätigender Text wird Admins nicht angezeigt. [#2991]
- "Kopieren" im Aktionsmenü des Lernmaterial meint eigentlich duplizieren [#2992]
- colorblock wird in veranstaltungen nicht mehr angezeigt [#2993]
- Teilnehmende: Unvollständige Meldung beim Eintragen [#3001]
- Export von Gruppenteilnehmern : Alle Tn stehen nochmal in Gruppe "keiner Funktion oder Gruppe" [#3002]
- Sortierpfeile in der Administration der Veranstaltungshierarchie werden nicht mehr angezeigt [#3003]
- QuickSearch verursacht unter PHP 8 Warnungen und ist damit nicht nutzbar [#3016]
- Aktion "Lerninhalt für OER Campus vorschlagen", obwohl Vorschläge deaktiviert sind [#3019]
- [vue-select warn]: Label key "option.title" does not exist in options object [#3020]
- Courseware: Anfasser außerhalb des Abschnitts [#3040]
- Nicht nachvollziehbare sprachliche unterschiede im CW Arbeitsplatz vs. Veranstaltung [#3059]
- Courseware im Arbeitsplatz nutzt den Begriff Lerninhalte [#3060]
- Courseware: Lehrende sind unsicher, auf wen sich der Fortschritt bezieht [#3065]
- Courseware: Lesezeichen sind kaputt [#3074]
- Courseware: Lesezeichen springt nicht zur gemerkten Seite [#3075]
- Barrierefreiheitserklärung (Muster) ist nicht im Release [#3082]
- Courseware Lesezeichen Filter funktioniert nicht [#3083]
- Courseware-Seiten Context-Validierung prüft nicht die Unit [#3090]
- Aktuelle PHP8-Warnungen beseitigen (2023-08-29) [#3106]
- PHP Warnungen / Fehler in ConfigValue [#3126]
- Konfiguration ACCESSIBILITY_RECEIVER_EMAIL nicht aussagekräftig [#3130]
- Interne Links funktionieren nicht mehr nach Update auf 5.3 [#3143]
- Courseware: URLs im Inhaltsverzeichnis funktionieren nicht, wenn sie in neuem Tab geöffnet werden [#3146]
- PHP8 Warnungen in der Veranstaltungsadministration und OER [#3155]
- PHP8 - Warnungen messaging.inc.php und Meine Veranstaltungen [#3156]
- Likert- und Polskala gibt es jeweils nur einmal pro Fragebogen [#3161]
- PHP8 - Warnungen in den Raumbuchungen [#3169]
- PHP8 - Weitere Warnungen [#3170]
- Courseware: Alignmenteinstellungen von Bildern im Textblock werden ignoriert [#3175]
- Courseware: Biografie-Blöcke sind für XSS-Angriffe anfällig [#3176]
- CW: Aufgabenverwaltung - Zuweisung der Personen [#3178]
- Courseware: CSS der Biography/Timeline Blöcke verursacht Probleme in Tabs [#3182]
- Suche im Vorlesungsverzeichnis findet keine Veranstaltungen mehr [#3187]
- Exception bei Kopieren von Dateien [#3188]
- PHP8-Warnungen in der Seminare-Klasse [#3189]
- Fehlerhafte CSS-Regeln [#3214]
- PHP8 - Warnungen in der Shibboleth-Anbindung [#3220]
- Fragebögen: Auswahloptionen stehen bei Anzeige auf separater Zeile [#3222]
- PHP8-Warnungen im Dateibereich [#3228]
- Methode Seminar::setMemberPriority() ist fehlerhaft [#3238]
- PHP- Fehler durch undifinierte Konstanten [#3239]
# 04.10.2023 v 5.2.4
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.2.4&state=all
- Profil: Leere Felder werden angezeigt und verschwenden so Platz [#1374]
- Ankündigungen können über den Arbeitsplatz nicht gespeichert werden [#2365]
- Aktion "Lerninhalt für OER Campus vorschlagen", obwohl der OER-Campus gar nicht aktiviert ist [#2769]
- OER-Suche über OERSI [#2891]
- Datei- und Aktivitätenüberschrift: Fehlermeldung [#2904]
- Courseware: Seiten sind nach dem Verknüpfen in falscher Reihenfolge [#2960]
- Globale Suche für Courseware-Inhalte läßt sich nicht abschalten [#2967]
- Courseware: Suche findet keine Umlaute in Texten [#2972]
- ACTIONMENU_THRESHOLD wird falsch ausgewertet [#3015]
- Formularvalidierung verwendet .toLocaleString() [#3027]
- SelectInput in dem Formularbaukasten tut nicht [#3116]
- Ankündigungen: Bearbeiten der Bereiche funktioniert nach Speicherversuch nicht mehr [#3120]
- PHP8 - Fehler NewsWidget [#3122]
- Courseware: Suche findet keine Umlaute in Texten [#3147]
# 04.10.2023 v 5.1.5
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.1.5&state=all
- PDF-Export der Courseware exportiert Unterseiten in falscher Reihenfolge [#2959]
- Plugin-Verwaltung: Anzeige ausstehender Migrationen weiß nichts von Branches [#3022]
- Umsortierung von Themen defekt [#3031]
- Fehler bei Plugins mit Migrationen mit gleichem Namen [#3069]
- CW: Aufgabenverwaltung Studierendensicht [#3179]
- Veranstaltungsangabe in Benachrichtigung beim Löschen eines Termins [#3195]
- Termin Ausfallen lassen - Einzeltermin löschen - Call to undefined method CourseExDate::toString() [#3199]
- Bearbeiten der Zugangsberechtigungen dauert sehr lange / Performance Anmeldesets mit vielen Bedingungen schlecht [#3248]
# 04.10.2023 v 5.0.7
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.0.7&state=all
- Hilfe-Lasche: Wenn Inhalt zu groß wird, kann nicht gescrollt werden [#504]
- Hilfelasche: CSS teilweise kaputt [#561]
- Dateibereich: Fehlende Verknüpfung von Checkbox und Dateinamen [#819]
- Reiter "Teilnehmende" wird bei freien Veranstaltungen angezeigt [#1049]
- Kopieren von Dateien: Auswahl der passenden Veranstaltung schwierig [#1364]
- Kalender: In den Dialogen verrutscht die Uhrzeit [#1370]
- Verwendung falscher Anführungszeichen im SQL [#1443]
- CSRF-Absicherung in der Sidebar [#1474]
- Courseware als nobody navigierbar [#1613]
- Export von Raumbuchungen: Buchungen von gelöschten Einzelterminen einer manuell gebuchten Terminserie werden als belegt exportiert [#1703]
- Gebäude-Übersicht: Checkboxen in der Tabelle sagen nicht, was mit ihnen ausgewählt werden kann [#1723]
- Exportfunktion für alle User mit Raumrechten [#1725]
- Zeiten/Räume: Bei Überlappungen von Raumbuchungen wird nicht mehr angezeigt, aus welcher Veranstaltung diese stammen [#2119]
- Arbeitsplatz: Paginierung auf "Meine hochgeladenen Dateien" kaputt [#2300]
- Blubber: memory size exhausted bei zu vielen Notifications [#2475]
- Semesterverwaltung: Dialog hat keinen Formsaver [#2502]
- Dokument hinzufügen: Admins finden alle Veranstaltungen, können aber Veranstaltungen fremder Einrichtungen nicht auswählen [#2545]
- ResourcePermissionException beim Ändern eines regelmäßigen Termins [#2570]
- Zeiten/Räume: Terminserie anlegen/bearbeiten: Semesterwochen werden beim Anlegen der Einzeltermine falsch berechnet, wenn der Vorlesungszeitraum des Semesters an einem Samstag beginnt [#2608]
- Courseware: Galerie-Block Pfeile im Karussell-Modus sind nicht fokussierbar und haben keinen Beschreibungstext [#2676]
- Externe Seiten: Umschalten der Sprache wirkt sich nicht auf alle Inhalte aus [#2697]
- Courseware: Bilder im Text-Block sind nach Import in ein anderes Stud.IP kaputt [#2699]
- In "Arbeitsplatz" > "Dateien" > "Übersicht" funktioniert die Aktion "Löschen" nicht [#2737]
- Löschen eines Fragebogens verliert den Kontext [#2850]
- Belegungspläne sind für Stud.IP Benutzer nur sichtbar, wenn die Pläne auch öffentlich gemacht werden [#2856]
- OER-Campus: Entdeckermodus kann nicht verlassen werden [#2871]
- OER-Campus: Fehlermeldung im Bearbeiten eigenes Materials [#2884]
- Dateibereich: Tippfehler [#2888]
- OER-Campus: Niveau Schalter schwer erkennbar [#2895]
- Rollenverwaltung: Tooltip sehr aufdringlich [#2909]
- OER Campus Gendern [#2912]
- Avatarmenu: neuerdings 1px zuviel Rand [#2914]
- OER-Campus: Material wird nicht angezeigt [#2915]
- Eventuell falsche Anzahl an abgegebenen Antworten in Fragebögen angezeigt [#2942]
- Banner sind zu groß [#2943]
- data-secure meldet ckeditor-Felder ohne Änderungen als verändert [#2950]
- Avatar-Menü: linker Rand am Icon fehlt, wenn Benachrichtigungen abgeschaltet sind [#2951]
- „Meine Studiengruppen“: Studiengruppen werden mit dem Standard-Avatarbild für Veranstaltungen angezeigt [#2969]
- Dateibereich (Plugin): Undefined array key "owner" in ...lib/filesystem/VirtualFolderType.php on line 90 [#2974]
- Terminvergabe: Falsche Darstellung der zu bestätigenden Textbox bei Buchung [#2978]
- FileManager::moveFolder erwartet FileRef-Instanzen, obwohl FileType-Instanzen vom Ordner kommen [#2980]
- Sichtbarkeitseinstellungen in Benutzerverwaltung verwirrend [#2983]
- FileManager::moveFolder: Sonderbehandlung für StandardFolder beachtet den Typ des Zielordners nicht [#2985]
- VirtualFolderType-Konstruktor prüft nicht, ob das Beschreibungsfeld in folderdata gesetzt ist [#2986]
- FileArchiveManager::addFileTypeToArchive kann nur mit StandardFile-Instanzen umgehen [#2987]
- file/unzipquestion ist nicht für Dateisystem-Plugins ausgelegt und liefert in dem Fall eine Exception [#2988]
- file/choose_destination ist nicht für das massenhafte Kopieren und Verschieben von Dateien und Ordnern aus Dateibereich-Plugins ausgelegt [#2990]
- file/choose_destination: Warnungen unter PHP8 [#2996]
- file/choose_destination: Bulk-Aktionen funktionieren bei Ordnern nicht für Dateibereich-Plugins [#2997]
- Suche: Raumsuche - wenn Name des Filters ein Leerfeld enthält, wird er nicht angewendet [#3011]
- OER Campus API kann immer aufgerufen werden [#3012]
- MVV: Übersetztung wird nicht gespeichert beim Bearbeiten von externen Ansprechpartnern [#3017]
- Logo fehlt in PDFs [#3021]
- Statistikseite in der Cacheverwaltung wirft Call to undefined method StudipCacheWrapper::getStats() [#3029]
- SSO Login fragt getUser() ab, aber es gibt u.U. keinen Stud.IP Nutzer dazu [#3058]
- Courseware "Seite bearbeiten" im Aktionsmenü stark missverständlich [#3067]
- Upload in der Sidebar funktioniert nicht mehr [#3080]
- Fehler beim Einbinden einer Datei ohne Lizenz in die Courseware [#3085]
- Bearbeiten eines Blocks hat doppelte Überschrift [#3086]
- Courseware: AudioBlock zeigt im Firefox falsche Dauer an [#3087]
- Auf „Meine Einrichtungen“ erscheint eine Exception, wenn man sich aus Einrichtungen austragen möchte, denen man sich selbst zugeordnet hat [#3093]
- JSONAPI Route courses erlaubt nicht die Filterung nach Kategorien, Studienbereichen und EInrichtungen [#3099]
- Fehler beim Löschen von Nutzern [#3100]
- Arbeitsplatz: Gesamte Fläche der Kacheln soll klickbar sein [#3107]
- Inkonsistente Benennung von Rubriken [#3108]
- Datumsauswähler im Terminkalender funktioniert nicht [#3109]
- Meine Veranstaltungen: Navigationspunkt „Export“ ist auch für Studierende sichtbar [#3114]
- OptionsWidget::addSelect() ist defekt und ruft nicht mehr die richtige Seite auf [#3115]
- FileManager::getDownloadURLForTemporaryFile erzeugt ggf. nicht funktionierende URLs [#3124]
- Kalendersauswahl im Terminkalender: Range-ID wird nicht korrekt gesetzt [#3127]
- Verlinkungen im Content brechen nicht um [#3134]
- ResourceNavigation::isActive() ist überflüssig [#3137]
- Avatare bei der Übersicht "Personen, deren Standardvertretung ich bin " auf "Meine Veranstaltungen" sind verkehrt herum [#3142]
- Polyfill für preg_replace_callback_array() entfernen [#3160]
- Icon für "Belegungspläne" springt in der Hauptnavigation [#3163]
- Aufruf von Mitarbeitern einer Einrichtung im nicht eingeloggten Zustand [#3190]
- Ressourceneigenschaften mit einem Anzeigenamen, der nur aus Leerzeichen besteht, werden ohne Label im Bearbeiten-Dialog angezeigt [#3196]
- Raumverwaltung: Fehlermeldung beim Klick auf Eintrag im Anfragenplan [#3205]
- Datepicker: Schaltfläche umbenennen [#3208]
- Anfragenliste: Filter zeigt "Alle meine Einrichtungen", meint aber "Alle" [#3210]
- ILIAS-Schnittstelle: SQL-Fehlermeldung als root bei "ILIAS-Kurs aus einer anderen Veranstaltung zuordnen" [#3233]
- Raumverwaltung: Im Dialog zum Bearbeiten eines Raums fehlt das erste Fieldset [#3236]
- Label zu Checkbox in Formularen steht nicht auf gleicher Höhe wie die Box [#3237]
- OER Campus: Javascript Injection [#3253]
- OER-Campus: mymaterial/edit hat keinen CSRF-Schutz [#3268]
- course/grouping-Controller hat keinen CSRF-Schutz [#3271]
# 14.07.2023 v 5.3.1
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.3.1&state=all
......
# Stud.IP v5.4
**23.05.23**
**08.11.23**
## Neue Features
## New Features
### System:
- Komplett neu entwickelte Verzeichnisstrukturen
- Unter Administraion -> Standort haben Root die Möglichkeit, einen systemweiten Pool an Bildern anzulegen und Lizenzen anzugeben. Die Bilder können dann von Lehrenden in Courseware genutzt werden.
- Barrierefreiheitserklärung und Meldefunktion sind nun im Footer integriert. Eine Mustererklärung ist enthalten, diese muss aber angepasst werden.
- Neben dem Vollbild-Modus (eingeführt in der Version 5.0), der nur in bestimmten Kontexten gezeigt wird, gibt es nun einen Modus "kompakte Navigation". Der neue Modus wird über das bisherige Icon für den Vollbildmodus aktiviert. Bitte passen Sie ihre Dokumentationen an.
- Root können"Banner" auf der Verwaltungsseite für Werkzeuge in Veranstaltungen schalten und damit z.B. auf neue Funktionen hinweisen.
- Der Hinweistext, der Nutzenden unter Profil->Persönliche Angaben->Grunddaten angezeigt wird, wenn die Grunddaten dort nicht änderbar sind, weil bspw. Shibboleth verwendet wird, lässt sich nun global konfigurieren. Damit kann ein Hinweis hinterlegt werden, an welche Stelle man sich zur Änderung der Grunddaten wenden soll.
- Veranstaltungen auf der "Meine Veranstaltungen"-Seite lassen sich nun auch nach Modulen gruppieren (wenn das Modularisierte Vorlesungsverzeichnis MVV verwendet wird)
### Raumverwaltung:
- Vereinfachte Raumanfragen
- Sammelaktionen
### Veranstaltungen:
- Hauptordner im Dateibereich lässt sich für Uploads von Studierenden/Teilnehmenden sperren.
- Die "Mehr"-Seite zur Verwaltung von Veranstaltungswerkzeugen gibt es nicht mehr als separaten Reiter. Alle Funktionen der "mehr"-Seite sind nun unter "Verwaltung" zu finden - bitte weisen Sie die Lehrenden unbedingt darauf hin und passen Sie ggf. ihre Dokumentation an.
- Verwaltungsseite wurde komplett in vue.js neu programmiert.
### Courseware:
- Jede Courseware ist nun ein einzelnes Lernmaterial und kann kopiert, exportiert, importiert werden und gibt Lernfortschritt an.
- Sammelmappe für Abschnitte und Blöcke
- Übersichtsseite für Feedback und Kommentare
- Neue Blöcke zur Darstellung eines Lebenslaufs
- Funktionen zum Teilen von Seiten an Personen und Gruppen, ermöglicht niedrigschwelliges Peerfeedback
- Übersichtsseite für Lehrende über verteilte Aufgaben mit Bearbeitungsstatus, Feedbackfunktion und Fristverlängerungsanfrage
## Breaking changes
......@@ -17,7 +41,12 @@
## Deprecated Features
- Das Verwenden von LESS-Stylesheets in Plugins wurde deprecated und wird zu Stud.IP 6.0 entfernt werden. Die betroffenen Plugins müssen angepasst und auf SCSS umgestellt werden.
- Die REST-API ist als deprecated markiert und wird perspektivisch entfernt. Neue Entwicklungen sollten nicht darauf aufbauen.
- Evaluationen werden perspektivisch entfernt, wenn die "Fragebögen"-Funktion dem Funktionsumfang der Evaluationen gleich kommt.
## Known Issues
- Der Vollbildmodus funktioniert nicht auf Apple iPads. Der Modus kann zwar initiiert werden, beendet sich aber selbsständig, wenn nach oben gescrollt wird. Dieses Verhalten ist en Fehler innerhalb von iOS/iPadOS und kann seitens Stud.IP nicht umgangen werden. Der Fehler ist bei Apple gemeldet.
## Other
- Mindestanforderung an Node.JS ist nun Version 16
RELEASE 5.4.alpha
RELEASE 5.4
......@@ -52,7 +52,7 @@ class Admin_AdditionalController extends AuthenticatedController
}
// purge data
if (Request::submitted('delete')) {
DatafieldEntryModel::deleteBySQL('sec_rage_id = ?', [$this->course->id]);
DatafieldEntryModel::deleteBySQL('sec_range_id = ?', [$this->course->id]);
}
if ($this->course->store()) {
......
......@@ -768,69 +768,7 @@ class Admin_CourseplanningController extends AuthenticatedController
*/
private function getCourses($params = [], $display_all = false): array
{
// 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);
$filter->where("sem_classes.studygroup_mode = '0'");
if (is_object($this->semester)) {
$filter->filterBySemester($this->semester->getId());
}
if ($params['typeFilter'] && $params['typeFilter'] !== "all") {
list($class_filter,$type_filter) = explode('_', $params['typeFilter']);
if (!$type_filter && !empty($GLOBALS['SEM_CLASS'][$class_filter])) {
$type_filter = array_keys($GLOBALS['SEM_CLASS'][$class_filter]->getSemTypes());
}
$filter->filterByType($type_filter);
}
if ($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'] && $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT !== "all") {
$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);
}
$filter->storeSettings();
$this->count_courses = $filter->countCourses();
if ($this->count_courses && ($this->count_courses <= $filter->max_show_courses || $display_all)) {
$courses = $filter->getCourses();
......@@ -842,41 +780,42 @@ class Admin_CourseplanningController extends AuthenticatedController
$sem_types = SemType::getTypes();
}
$seminars = array_map('current', $courses);
$seminars = [];
foreach ($courses as $course) {
$seminars[$course->id] = $course->toArray();
foreach ($seminars as $seminar_id => $seminar) {
$seminars[$seminar_id]['seminar_id'] = $seminar_id;
$seminars[$seminar_id]['obj_type'] = 'sem';
$dozenten = $this->getTeacher($seminar_id);
$seminars[$seminar_id]['dozenten'] = $dozenten;
$seminars[$course->id]['seminar_id'] = $course->id;
$seminars[$course->id]['obj_type'] = 'sem';
$dozenten = $this->getTeacher($course->id);
$seminars[$course->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]['tools'] = $tools;
$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]['sem_class'] = $sem_types[$seminar['status']]->getClass();
$seminars[$seminar_id]['navigation'] = MyRealmModel::getAdditionalNavigations(
$seminar_id,
$seminars[$seminar_id],
$seminars[$seminar_id]['sem_class'],
$tools = new SimpleCollection(ToolActivation::findbyRange_id($course->id, "ORDER BY position"));
$visit_data = get_objects_visits([$course->id], 0, null, null, $tools->pluck('plugin_id'));
$seminars[$course->id]['tools'] = $tools;
$seminars[$course->id]['visitdate'] = $visit_data[$course->id][0]['visitdate'];
$seminars[$course->id]['last_visitdate'] = $visit_data[$course->id][0]['last_visitdate'];
$seminars[$course->id]['sem_class'] = $sem_types[$course->status]->getClass();
$seminars[$course->id]['navigation'] = MyRealmModel::getAdditionalNavigations(
$course->id,
$seminars[$course->id],
$seminars[$course->id]['sem_class'],
$GLOBALS['user']->id,
$visit_data[$seminar_id]
$visit_data[$course->id]
);
}
//add last activity column:
if (in_array('last_activity', $params['view_filter'])) {
$seminars[$seminar_id]['last_activity'] = lastActivity($seminar_id);
$seminars[$course->id]['last_activity'] = lastActivity($course->id);
}
if ($this->selected_action == 17) {
$seminars[$seminar_id]['admission_locked'] = false;
if ($seminar['course_set']) {
$set = new CourseSet($seminar['course_set']);
$seminars[$course->id]['admission_locked'] = false;
if ($course->course_set) {
$set = new CourseSet($course->course_set);
if (!is_null($set) && $set->hasAdmissionRule('LockedAdmission')) {
$seminars[$seminar_id]['admission_locked'] = 'locked';
$seminars[$course->id]['admission_locked'] = 'locked';
} else {
$seminars[$seminar_id]['admission_locked'] = 'disable';
$seminars[$course->id]['admission_locked'] = 'disable';
}
unset($set);
}
......
......@@ -235,6 +235,17 @@ class Admin_CoursesController extends AuthenticatedController
)->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);
}
}
}
}
......@@ -315,21 +326,23 @@ class Admin_CoursesController extends AuthenticatedController
? $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',
'setFilter' => array_filter(array_merge(
$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,
]
)),
'setFilter' => array_filter($filters),
];
}
......@@ -357,59 +370,14 @@ class Admin_CoursesController extends AuthenticatedController
public function search_action()
{
$activeSidebarElements = $this->getActiveElements();
if (Request::get('search')) {
$GLOBALS['user']->cfg->store('ADMIN_COURSES_SEARCHTEXT', Request::get('search'));
} else {
$GLOBALS['user']->cfg->delete('ADMIN_COURSES_SEARCHTEXT');
}
if (Request::option('institut_id') && Request::option('institut_id') !== 'all') {
$GLOBALS['user']->cfg->store('MY_INSTITUTES_DEFAULT', Request::option('institut_id'));
} else {
$GLOBALS['user']->cfg->delete('MY_INSTITUTES_DEFAULT');
}
if (Request::option('semester_id')) {
$GLOBALS['user']->cfg->store('MY_COURSES_SELECTED_CYCLE', Request::option('semester_id'));
} else {
$GLOBALS['user']->cfg->delete('MY_COURSES_SELECTED_CYCLE');
}
if (Request::option('course_type') && Request::option('course_type') !== 'all') {
$GLOBALS['user']->cfg->store('MY_COURSES_TYPE_FILTER', Request::option('course_type'));
} else {
$GLOBALS['user']->cfg->delete('MY_COURSES_TYPE_FILTER');
}
if (Request::option('stgteil')) {
$GLOBALS['user']->cfg->store('MY_COURSES_SELECTED_STGTEIL', Request::option('stgteil'));
} else {
$GLOBALS['user']->cfg->delete('MY_COURSES_SELECTED_STGTEIL');
}
if (Request::option('teacher_filter')) {
$GLOBALS['user']->cfg->store('ADMIN_COURSES_TEACHERFILTER', Request::option('teacher_filter'));
} else {
$GLOBALS['user']->cfg->delete('ADMIN_COURSES_TEACHERFILTER');
}
$datafields_filters = $GLOBALS['user']->cfg->ADMIN_COURSES_DATAFIELDS_FILTERS;
foreach (DataField::getDataFields('sem') as $datafield) {
if (
Request::get('df_'.$datafield->getId())
&& in_array($datafield->getId(), $activeSidebarElements['datafields'])
) {
$datafields_filters[$datafield->getId()] = Request::get('df_'.$datafield->getId());
} else {
unset($datafields_filters[$datafield->getId()]);
}
}
$GLOBALS['user']->cfg->store('ADMIN_COURSES_DATAFIELDS_FILTERS', $datafields_filters);
$this->processFilters();
$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([
......@@ -526,6 +494,57 @@ class Admin_CoursesController extends AuthenticatedController
$this->render_json($data);
}
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 = [
......
......@@ -184,64 +184,78 @@ class Admin_TreeController extends AuthenticatedController
*/
public function batch_assign_semtree_action()
{
$GLOBALS['perm']->check('admin');
if (!$GLOBALS['perm']->have_perm('admin')
&& !RolePersistence::isAssignedRole(User::findCurrent()->id, 'DedicatedAdmin')) {
throw new AccessDeniedException();
}
//set the page title with the area of Stud.IP:
PageLayout::setTitle(_('Veranstaltungszuordnungen bearbeiten'));
Navigation::activateItem('/browse/my_courses/list');
$GLOBALS['perm']->check('admin');
// check the assign_semtree array and extract the relevant course IDs:
$courseIds = Request::optionArray('assign_semtree');
$order = Config::get()->IMPORTANT_SEMNUMBER
? "ORDER BY `start_time` DESC, `VeranstaltungsNummer`, `Name`"
: "ORDER BY `start_time` DESC, `Name`";
$this->courses = Course::findMany($courseIds, $order);
$this->courses = array_filter(
Course::findMany($courseIds, $order),
function (Course $course): bool {
/*
* Check if sem_tree entries are allowed and may be changed and remove all courses
* where this is not the case.
*/
return !LockRules::Check($course->id, 'sem_tree', 'sem')
&& $course->getSemClass()['bereiche'];
}
);
$this->return = Request::get('return');
// check if at least one course was selected (this can only happen from admin courses overview):
if (!$courseIds) {
PageLayout::postWarning('Es wurde keine Veranstaltung gewählt.');
if (count($this->courses) === 0) {
PageLayout::postWarning('Es wurde keine Veranstaltung gewählt oder die Zuordnungen können ' .
'nicht bearbeitet werden.');
$this->relocate('admin/courses');
}
}
public function assign_courses_action($class_id)
{
$GLOBALS['perm']->check('root');
$data = $this->checkClassAndId($class_id);
$GLOBALS['perm']->check('admin');
$this->search = QuickSearch::get('courses[]', new StandardSearch('Seminar_id'))->withButton();
$this->node = $data['id'];
}
/**
* Store (de-)assignments from courses to sem_tree nodes.
* @return void
*/
public function do_batch_assign_action()
{
$GLOBALS['perm']->check('admin');
$astmt = DBManager::get()->prepare("INSERT IGNORE INTO `seminar_sem_tree` VALUES (:course, :node)");
$dstmt = DBManager::get()->prepare(
"DELETE FROM `seminar_sem_tree` WHERE `seminar_id` IN (:courses) AND `sem_tree_id` = :node");
if (!$GLOBALS['perm']->have_perm('admin')
&& !RolePersistence::isAssignedRole(User::findCurrent()->id, 'DedicatedAdmin')) {
throw new AccessDeniedException();
}
CSRFProtection::verifyUnsafeRequest();
$success = true;
// Add course assignments to the specified nodes.
foreach (Request::optionArray('courses') as $course) {
foreach (Request::optionArray('add_assignments') as $a) {
$success = $astmt->execute(['course' => $course, 'node' => $a]);
$courses = Course::findMany(Request::optionArray('courses'));
foreach ($courses as $course) {
if ($GLOBALS['perm']->have_studip_perm('tutor', $course->id)) {
$areas = $course->study_areas->pluck('sem_tree_id');
$newAreas = array_merge($areas, Request::optionArray('add_assignments'));
$delete = Request::optionArray('delete_assignments');
$changed = array_diff($newAreas, $delete);
// Set new areas for course if at least one area remains.
if (count($changed) > 0) {
$course->setStudyAreas($changed);
// Allow to remove all study areas only when there are modules.
} else if ($course->getSemClass()['module'] && count(Lvgruppe::findBySeminar($course->id))) {
$course->setStudyAreas($changed);
} else {
$success = false;
}
} else {
$success = false;
}
}
// Remove course assignments from the specified nodes.
foreach (Request::optionArray('delete_assignments') as $d) {
$success = $dstmt->execute(['courses' => Request::optionArray('courses'), 'node' => $d]);
}
if ($success) {
PageLayout::postSuccess(_('Die Zuordnungen wurden gespeichert.'));
} else {
......
......@@ -393,15 +393,18 @@ class Admin_UserController extends AuthenticatedController
if ($user_id === null) {
if (Request::option('user')) {
$user_id = Request::option('user');
} else {
PageLayout::postInfo(_('Sie haben niemanden ausgewählt!'));
//liste wieder anzeigen
$this->redirect('admin/user/');
return;
}
}
$this->user = User::find($user_id);
if (!$this->user) {
PageLayout::postInfo(_('Sie haben niemanden ausgewählt!'));
//liste wieder anzeigen
$this->redirect('admin/user/');
return;
}
$this->user_roles = $this->user->getRoles();
// Änderungen speichern
......@@ -978,6 +981,7 @@ class Admin_UserController extends AuthenticatedController
*/
public function change_password_action($user_id)
{
CSRFProtection::verifyUnsafeRequest();
// mail address did not change, so skip this check
$GLOBALS['MAIL_VALIDATE_BOX'] = false;
$UserManagement = new UserManagement($user_id);
......@@ -989,7 +993,7 @@ class Admin_UserController extends AuthenticatedController
PageLayout::postError(_('Die Änderungen konnten nicht gespeichert werden.'), $details);
}
if (Request::int('from_index')) {
$this->redirect('admin/user');
$this->relocate('admin/user');
} else {
$this->redirect('admin/user/edit/' . $user_id);
}
......@@ -1031,7 +1035,7 @@ class Admin_UserController extends AuthenticatedController
}
if (Request::int('from_index')) {
$this->redirect('admin/user');
$this->relocate('admin/user');
} else {
$this->redirect('admin/user/edit/' . $user_id);
}
......@@ -1044,6 +1048,7 @@ class Admin_UserController extends AuthenticatedController
*/
public function unlock_action($user_id)
{
CSRFProtection::verifyUnsafeRequest();
$user = User::find($user_id);
$user->locked = 0;
......@@ -1063,7 +1068,7 @@ class Admin_UserController extends AuthenticatedController
}
if (Request::int('from_index')) {
$this->redirect('admin/user');
$this->relocate('admin/user');
} else {
$this->redirect('admin/user/edit/' . $user_id);
}
......@@ -1146,6 +1151,7 @@ class Admin_UserController extends AuthenticatedController
*/
public function delete_studycourse_action($user_id, $fach_id, $abschlus_id)
{
CSRFProtection::verifyUnsafeRequest();
$user_stc = UserStudyCourse::find([$user_id, $fach_id, $abschlus_id]);
$deleted = false;
if ($user_stc) {
......@@ -1167,19 +1173,19 @@ class Admin_UserController extends AuthenticatedController
*/
public function delete_institute_action($user_id, $institut_id)
{
CSRFProtection::verifyUnsafeRequest();
if ($GLOBALS['perm']->have_studip_perm("admin", $institut_id)) {
$groups = GetAllStatusgruppen($institut_id);
$group_list = GetRoleNames($groups, 0, '', true);
if (is_array($group_list) && count($group_list) > 0) {
$query = "DELETE FROM statusgruppe_user
WHERE statusgruppe_id IN (?) AND user_id = ?";
$statement = DBManager::get()->prepare($query);
$statement->execute([array_keys($group_list), $user_id]);
StatusgruppeUser::deleteBySQL(
"`statusgruppe_id` IN (?) AND `user_id` = ?",
[array_keys($group_list), $user_id]
);
}
$db = DBManager::get()->prepare("DELETE FROM user_inst WHERE user_id = ? AND Institut_id = ?");
$db->execute([$user_id, $institut_id]);
if ($db->rowCount() == 1) {
$count = InstituteMember::deleteBySQL("`user_id` = ? AND `Institut_id` = ?", [$user_id, $institut_id]);
if ($count === 1) {
StudipLog::log('INST_USER_DEL', $institut_id, $user_id);
NotificationCenter::postNotification('UserInstitutionDidDelete', $institut_id, $user_id);
InstituteMember::ensureDefaultInstituteForUser($user_id);
......@@ -1203,6 +1209,7 @@ class Admin_UserController extends AuthenticatedController
*/
public function delete_userdomain_action($user_id)
{
CSRFProtection::verifyUnsafeRequest();
$domain_id = Request::get('domain_id');
UserDomain::find($domain_id)->removeUser($user_id);
$result = AutoInsert::instance()->saveUser($user_id);
......@@ -1221,11 +1228,12 @@ class Admin_UserController extends AuthenticatedController
}
/**
* Reset notfication for user
* Reset notification for user
* @param $user_id
*/
public function reset_notification_action($user_id)
{
CSRFProtection::verifyUnsafeRequest();
$resetted = CourseMemberNotification::deleteBySQL("user_id = ?", [$user_id]);
PageLayout::postSuccess(sprintf(_('Die Benachrichtigungseinstellungen für %s Veranstaltungen wurden zurück gesetzt.'), $resetted));
$this->redirect('admin/user/edit/' . $user_id);
......@@ -1237,6 +1245,7 @@ class Admin_UserController extends AuthenticatedController
*/
public function reset_tfa_action($user_id)
{
CSRFProtection::verifyUnsafeRequest();
if (TFASecret::deleteByUser_id($user_id)) {
PageLayout::postSuccess(_('Die Zwei-Faktor-Authentifizierung wurde für diese Person deaktiviert.'));
}
......@@ -1688,7 +1697,7 @@ class Admin_UserController extends AuthenticatedController
_('Personenaccount entsperren'),
$this->url_for("admin/user/unlock/{$this->user->id}"),
Icon::create('lock-unlocked')
);
)->asButton();
} else {
$user_actions->addLink(
_('Personenaccount sperren'),
......@@ -1703,7 +1712,7 @@ class Admin_UserController extends AuthenticatedController
_('Passwortlink zusenden'),
$this->url_for("admin/user/change_password/{$this->user->id}"),
Icon::create('key')
);
)->asButton();
}
$user_actions->addLink(
_('Person löschen'),
......@@ -1716,7 +1725,7 @@ class Admin_UserController extends AuthenticatedController
_('Benachrichtigungen zurücksetzen'),
$this->url_for("admin/user/reset_notification/{$this->user->id}"),
Icon::create('refresh')
);
)->asButton();
}
if ($this->action === 'activities') {
......@@ -1724,7 +1733,7 @@ class Admin_UserController extends AuthenticatedController
_('Alle Dateien des Nutzers aus Veranstaltungen und Einrichtungen als ZIP herunterladen'),
$this->url_for("admin/user/download_user_files/{$this->user->user_id}"),
Icon::create('folder-full')
);
)->asButton();
}
if ($this->user->id !== $GLOBALS['user']->id && TFASecret::exists($this->user->id)) {
......@@ -1732,7 +1741,7 @@ class Admin_UserController extends AuthenticatedController
_('Zwei-Faktor-Authentifizierung deaktivieren'),
$this->url_for("admin/user/reset_tfa/{$this->user->id}"),
Icon::create('code-qr')
);
)->asButton();
}
$sidebar->insertWidget($user_actions, 'actions', 'user_actions');
......
......@@ -414,11 +414,7 @@ class BlubberController extends AuthenticatedController
$statement = DBManager::get()->prepare($query);
$statement->execute([$this->thread->id]);
foreach ($statement->fetchFirst() as $user_id) {
$member = new CourseMember();
$member['user_id'] = $user_id;
$member['seminar_id'] = $course->getId();
$member['status'] = $user_id === $this->thread['user_id'] ? 'dozent' : 'tutor';
$member->store();
CourseMember::insertCourseMember($course->getId(), $user_id, $user_id === $this->thread['user_id'] ? 'dozent' : 'tutor');
}
$this->thread['context_type'] = 'course';
......
......@@ -243,7 +243,11 @@ class Calendar_ScheduleController extends AuthenticatedController
$this->render_template('calendar/schedule/_entry_course');
} else if ($id) {
$entry_columns = CalendarScheduleModel::getScheduleEntries($GLOBALS['user']->id, 0, 0, $id);
$entries = array_pop($entry_columns)->getEntries();
$entries = [];
$entry_columns = array_pop($entry_columns);
if ($entry_columns) {
$entries = $entry_columns->getEntries();
}
$this->show_entry = array_pop($entries);
$this->render_template('calendar/schedule/_entry_schedule');
}
......
......@@ -16,6 +16,10 @@ class Consultation_AdminController extends ConsultationController
{
parent::before_filter($action, $args);
if (!$this->range || $action === 'not_found') {
return;
}
if (!$this->range->isEditableByUser()) {
throw new AccessDeniedException();
}
......
......@@ -12,14 +12,21 @@ abstract class ConsultationController extends AuthenticatedController
{
parent::before_filter($action, $args);
$type = 'person';
if (Request::submitted('username')) {
$this->range = User::findByUsername(Request::username('username'));
} elseif (Request::submitted('cid')) {
$this->range = Context::get();
$type = 'object';
} else {
$this->range = $GLOBALS['user']->getAuthenticatedUser();
}
if (!$this->range) {
$this->redirect($this->not_foundURL($type));
return;
}
if ($this->range instanceof User) {
URLHelper::addLinkParam('username', $this->range->username);
} elseif ($this->range instanceof Course || $this->range instanceof Institute) {
......@@ -47,6 +54,12 @@ abstract class ConsultationController extends AuthenticatedController
};
}
public function not_found_action(string $type): void
{
$this->type = $type;
$this->render_template('consultation/not_found', $this->layout);
}
protected function activateNavigation($path)
{
$path = ltrim($path, '/');
......
......@@ -14,6 +14,10 @@ class Consultation_OverviewController extends ConsultationController
{
parent::before_filter($action, $args);
if (!$this->range) {
return;
}
if ($this->range->isEditableByUser()) {
$this->redirect('consultation/admin');
}
......
......@@ -121,6 +121,7 @@ class Course_AdmissionController extends AuthenticatedController
CSRFProtection::verifyUnsafeRequest();
PageLayout::setTitle(_('Anmeldemodus ändern'));
$request = null;
$question = null;
if (Request::submitted('change_admission_prelim')) {
$request = Request::extract('admission_prelim int, admission_binding submitted, admission_prelim_txt');
$request = array_diff_key($request, array_filter($this->is_locked));
......@@ -278,7 +279,7 @@ class Course_AdmissionController extends AuthenticatedController
$limit = $this->course->getNumWaiting() - $this->course->admission_waitlist_max;
$removed_applicants = $this->course->admission_applicants->findBy('status', 'awaiting')->orderBy('position desc', SORT_NUMERIC)->limit($limit);
}
if ($removed_applicants) {
if (!empty($removed_applicants)) {
$num_moved = 0;
foreach ($removed_applicants as $applicant) {
setTempLanguage($applicant->user_id);
......
......@@ -490,7 +490,7 @@ class Course_BasicdataController extends AuthenticatedController
} else {
// format of input element name is "course_xxx"
$varname = mb_substr($field['name'], 7);
if ($field['i18n']) {
if (!empty($field['i18n'])) {
$req_value = Request::i18n($field['name']);
} else {
$req_value = Request::get($field['name']);
......@@ -528,7 +528,12 @@ class Course_BasicdataController extends AuthenticatedController
$after = array_diff_assoc($sem->getSettings(), $old_settings);
//update admission, if turnout was raised
if($after['admission_turnout'] > $before['admission_turnout'] && $sem->isAdmissionEnabled()) {
if (
!empty($after['admission_turnout'])
&& !empty($before['admission_turnout'])
&& $after['admission_turnout'] > $before['admission_turnout']
&& $sem->isAdmissionEnabled()
) {
AdmissionApplication::addMembers($sem->getId());
}
......
......@@ -20,6 +20,9 @@ class Course_CoursewareController extends CoursewareController
{
parent::before_filter($action, $args);
if (!Context::get()) {
throw new CheckObjectException(_('Sie haben kein Objekt gewählt.'));
}
PageLayout::setTitle(Context::get()->getFullname() . ' - ' . _('Courseware'));
PageLayout::setHelpKeyword('Basis.Courseware');
......@@ -44,7 +47,7 @@ class Course_CoursewareController extends CoursewareController
public function courseware_action($unit_id = null): void
{
global $user;
Navigation::activateItem('course/courseware/unit');
if ($this->unitsNotFound) {
PageLayout::postMessage(MessageBox::info(_('Es wurde kein Lernmaterial gefunden.')));
......
......@@ -67,11 +67,11 @@ class Course_DetailsController extends AuthenticatedController
public function index_action()
{
$this->prelim_discussion = vorbesprechung($this->course->id);
$this->title = $this->course->getFullname();
$this->course_domains = UserDomain::getUserDomainsForSeminar($this->course->id);
$this->sem = new Seminar($this->course);
$this->links = [];
//public folders
$folders = Folder::findBySQL("range_type='course' AND range_id = ? AND folder_type = 'CoursePublicFolder'", [$this->course->id]);
......@@ -233,6 +233,12 @@ class Course_DetailsController extends AuthenticatedController
['data-dialog' => 'size=big']
);
$this->links[] = [
'label' => $abo_msg,
'url' => $this->url_for("course/enrolment/apply/{$this->course->id}"),
'attributes' => ['data-dialog' => 'size=big'],
];
}
if (Config::get()->SCHEDULE_ENABLE
......@@ -253,6 +259,12 @@ class Course_DetailsController extends AuthenticatedController
$this->url_for("calendar/schedule/addvirtual/{$this->course->id}"),
Icon::create('info')
);
$this->links[] = [
'label' => _('Nur im Stundenplan vormerken'),
'url' => $this->url_for("calendar/schedule/addvirtual/{$this->course->id}"),
'attributes' => [],
];
}
}
......
......@@ -267,6 +267,7 @@ class Course_GroupingController extends AuthenticatedController
*/
public function action_action()
{
CSRFProtection::verifyUnsafeRequest();
if (Request::submitted('single_action')) {
list($course_id, $permission) = explode('-', Request::get('single_action'));
......@@ -327,6 +328,8 @@ class Course_GroupingController extends AuthenticatedController
*/
public function move_members_action($source_id)
{
CSRFProtection::verifyUnsafeRequest();
$source = Seminar::getInstance($source_id);
$target = Seminar::getInstance(Request::option('target'));
......@@ -459,6 +462,7 @@ class Course_GroupingController extends AuthenticatedController
*/
public function unassign_parent_action()
{
CSRFProtection::verifyUnsafeRequest();
$parent = $this->course->parent_course;
$this->course->parent_course = null;
NotificationCenter::postNotification('CourseWillRemoveFromGroup', $this->course->id, $parent);
......@@ -477,6 +481,8 @@ class Course_GroupingController extends AuthenticatedController
*/
public function assign_child_action()
{
CSRFProtection::verifyUnsafeRequest();
if ($child = Request::option('child')) {
$child_course = Course::find($child);
......
......@@ -331,6 +331,7 @@ class Course_IliasInterfaceController extends AuthenticatedController
LEFT JOIN seminare ON (object_id = Seminar_id)
WHERE module_type = 'crs'
AND system_type = ?";
$params = [$this->ilias_index];
} else {
$query = "SELECT DISTINCT object_id, module_id, Name
FROM object_contentmodules
......@@ -340,9 +341,10 @@ class Course_IliasInterfaceController extends AuthenticatedController
AND system_type = ?
AND seminar_user.status = 'dozent'
AND seminar_user.user_id = ?";
$params = [$this->ilias_index, User::findCurrent()->id];
}
$statement = DBManager::get()->prepare($query);
$statement->execute([$this->ilias_index, User::findCurrent()->id]);
$statement->execute($params);
$this->studip_course_list = [];
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
$this->studip_course_list[$row['module_id']] = my_substr($row['Name'],0,60)." ".sprintf(_("(Kurs-ID %s)"), $row['module_id']);
......@@ -351,7 +353,7 @@ class Course_IliasInterfaceController extends AuthenticatedController
if (Request::get('cmd') === 'assign_course') {
$crs_id = IliasObjectConnections::getConnectionModuleId($this->seminar_id, 'crs', $this->ilias_index);
if (Request::get('ilias_course_id') && !$crs_id) {
IliasObjectConnections::setConnection($this->seminar_id, Request::get(ilias_course_id), 'crs', $this->ilias_index);
IliasObjectConnections::setConnection($this->seminar_id, Request::get('ilias_course_id'), 'crs', $this->ilias_index);
PageLayout::postInfo(_('Kurs wurde zugeordnet.'));
}
$this->redirect('course/ilias_interface');
......@@ -370,7 +372,7 @@ class Course_IliasInterfaceController extends AuthenticatedController
if (Request::get('cmd') === 'assign_course') {
$crs_id = IliasObjectConnections::getConnectionModuleId($this->seminar_id, 'crs', $this->ilias_index);
if (Request::get('ilias_course_id') && !$crs_id) {
IliasObjectConnections::setConnection($this->seminar_id, Request::get(ilias_course_id), 'crs', $this->ilias_index);
IliasObjectConnections::setConnection($this->seminar_id, Request::get('ilias_course_id'), 'crs', $this->ilias_index);
PageLayout::postInfo(_('Kurs wurde zugeordnet.'));
}
$this->redirect('course/ilias_interface');
......
......@@ -78,11 +78,14 @@ class Course_LtiController extends StudipController
/**
* Display the launch form for a tool as an iframe.
*/
public function iframe_action()
public function iframe_action(string $position)
{
$this->launch_url = Request::get('launch_url');
$this->launch_data = Request::getArray('launch_data');
$this->signature = Request::get('signature');
$lti_data = LtiData::findByCourseAndPosition($this->course_id, $position);
$lti_link = $this->getLtiLink($lti_data);
$this->launch_url = $lti_data->getLaunchURL();
$this->launch_data = $lti_link->getBasicLaunchData();
$this->signature = $lti_link->getLaunchSignature($this->launch_data);
$this->set_layout(null);
}
......@@ -146,6 +149,8 @@ class Course_LtiController extends StudipController
*/
public function edit_action($position = '')
{
$this->lti_data = new LtiData();
if ($position !== '') {
$this->lti_data = LtiData::findByCourseAndPosition($this->course_id, $position);
}
......