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 (624)
Showing
with 1146 additions and 449 deletions
......@@ -20,3 +20,6 @@ block_comment_start = /*
block_comment_end = */
line_comment = //
quote_type = single
[*.yml]
indent_size = 2
\ No newline at end of file
......@@ -3,7 +3,17 @@
# MYSQL_PASSWORD=""
# MYSQL_DATABASE=""
# DEBUG_BAR="1" // Enable to display the debug bar in development mode
# Enable the next line to display the debug bar in development mode
# DEBUG_BAR=1
# Enable the following to allow opening files from exception displays in your
# editor. Beware: You need to provide a full path for prefix your files since
# the exception only displays the relative path.
#
# Variables being substituted: %{file} and %{line}
#
# EDITOR_URL="phpstorm://open?file=<path-to-your-studip>/%{file}&line=%{line}"
# EDITOR_URL="vscode://file/<path-to-your-studip>/%{file}:%{line}:0
# STUDIP_CACHING_ENABLE=""
# STUDIP_CACHE_IS_SESSION_STORAGE=""
......
{
"parserOptions": {
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"env": {
"browser": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential",
"@vue/eslint-config-typescript"
],
"globals": {
"STUDIP": "writable",
"CKEDITOR": "writable",
"$": "writable",
"_": "writable",
"jQuery": "writable"
},
"plugins": [
"vue"
],
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "off",
"no-async-promise-executor": "error",
"no-await-in-loop": "error",
"no-promise-executor-return": "error",
"require-atomic-updates": "error",
"max-nested-callbacks": ["error", 4],
"no-return-await": "error",
"prefer-promise-reject-errors": "error",
"vue/multi-word-component-names": "off"
}
}
......@@ -23,6 +23,7 @@ data/oer_logos/*
data/upload_doc/*
public/.htaccess
public/.rnd
public/assets/javascripts/*.js
public/assets/javascripts/*.js.map
public/assets/stylesheets/*.css
......
......@@ -29,6 +29,7 @@ stages:
- checks
- analyse
- test
- cache
- packaging
- release
......@@ -159,17 +160,11 @@ lint-js:
interruptible: true
before_script:
- *mkdir-reports
- npm install -g npm@7
- npm install
--no-save --no-audit --no-fund
--loglevel=error
eslint eslint-formatter-gitlab
- npm ci --prefer--offline
script:
- npx eslint
--ext .js,.vue
- npm run lint-js --
--cache --cache-location $CACHE_LOCATION
--format gitlab
resources/assets/javascripts resources/vue
artifacts:
reports:
codequality: $ESLINT_CODE_QUALITY_REPORT
......@@ -183,24 +178,20 @@ lint-css:
STYLELINT_CODE_QUALITY_REPORT: $REPORT_DIR/stylelint-codequality.json
interruptible: true
cache:
- key: "$CI_JOB_NAME_SLUG:CI_COMMIT_REF_SLUG"
- key: "CI_COMMIT_REF_SLUG-lint-css"
paths:
- $CACHE_LOCATION
policy: pull-push
when: always
before_script:
- *mkdir-caches
- *mkdir-reports
- npm install
--no-save --no-audit --no-fund
--loglevel=error
stylelint@^14.9.1
stylelint-config-standard@^26.0.0
stylelint-formatter-gitlab
script:
- npx
stylelint
- npm run lint-css --
--cache --cache-location $CACHE_LOCATION
--custom-formatter=node_modules/stylelint-formatter-gitlab
--output-file $STYLELINT_CODE_QUALITY_REPORT
resources/assets/stylesheets
artifacts:
reports:
codequality: $STYLELINT_CODE_QUALITY_REPORT
......@@ -211,9 +202,7 @@ phpstan:
variables:
CACHE_LOCATION: $CACHE_DIR/phpstan
PHPSTAN_CODE_QUALITY_REPORT: $REPORT_DIR/phpstan-codequality.json
allow_failure: true
interruptible: true
when: manual
cache:
- *composer-cache
- key: "$CO_JOB_NAME_SLUG:$CI_COMMIT_REF_SLUG"
......
{
"extends": "stylelint-config-standard",
"extends": "stylelint-config-standard-scss",
"rules": {
"alpha-value-notation": null,
"at-rule-empty-line-before": null,
"at-rule-no-vendor-prefix": null,
"block-closing-brace-empty-line-before": null,
"block-closing-brace-newline-after": null,
"block-closing-brace-newline-before": null,
"block-closing-brace-space-before": null,
"block-no-empty": null,
"block-opening-brace-newline-after": null,
"block-opening-brace-space-after": null,
"block-opening-brace-space-before": null,
"color-function-notation": null,
"color-hex-case": null,
"color-hex-length": null,
"color-no-invalid-hex": null,
"comment-empty-line-before": null,
"comment-whitespace-inside": null,
"declaration-bang-space-after": null,
"declaration-bang-space-before": null,
"custom-property-empty-line-before": null,
"declaration-block-no-duplicate-properties": null,
"declaration-block-no-redundant-longhand-properties": null,
"declaration-block-no-shorthand-property-overrides": null,
"declaration-block-semicolon-newline-after": null,
"declaration-block-semicolon-space-before": null,
"declaration-block-single-line-max-declarations": null,
"declaration-block-trailing-semicolon": null,
"declaration-colon-newline-after": null,
"declaration-colon-space-after": null,
"declaration-colon-space-before": null,
"declaration-empty-line-before": null,
"font-family-name-quotes": null,
"font-family-no-missing-generic-family-keyword": null,
"function-comma-space-after": null,
"function-comma-space-before": null,
"function-name-case": null,
"function-no-unknown": null,
"function-parentheses-newline-inside": null,
"function-parentheses-space-inside": null,
"function-url-quotes": null,
"hue-degree-notation": null,
"indentation": null,
"import-notation": "string",
"keyframes-name-pattern": null,
"length-zero-no-unit": null,
"max-empty-lines": null,
"max-line-length": null,
"media-feature-range-notation": "prefix",
"media-feature-name-no-vendor-prefix": null,
"no-descending-specificity": null,
"no-duplicate-selectors": null,
"no-empty-first-line": null,
"no-empty-source": null,
"no-eol-whitespace": null,
"no-extra-semicolons": null,
"no-invalid-position-at-import-rule": null,
"no-irregular-whitespace": null,
"no-missing-end-of-source-newline": null,
"number-leading-zero": null,
"number-max-precision": null,
"number-no-trailing-zeros": null,
"property-no-vendor-prefix": null,
"rule-empty-line-before": null,
"selector-attribute-quotes": null,
"selector-class-pattern": null,
"selector-combinator-space-after": null,
"selector-combinator-space-before": null,
"selector-descendant-combinator-no-non-space": null,
"selector-id-pattern": null,
"selector-list-comma-newline-after": null,
"selector-no-vendor-prefix": null,
"selector-not-notation": null,
"selector-pseudo-element-colon-notation": null,
"shorthand-property-no-redundant-values": null,
"string-quotes": null,
"value-keyword-case": null,
"value-list-max-empty-lines": null,
"value-no-vendor-prefix": null,
"custom-property-pattern": [
"^([a-z][a-z0-9]*-+)*[a-z0-9]+$",
{"message": "Expected custom property name to be kebab-case-ish (multiple dashes are allowed"}
]
],
"scss/at-extend-no-missing-placeholder": null,
"scss/at-mixin-pattern": null,
"scss/dollar-variable-empty-line-before": null,
"scss/dollar-variable-pattern": null,
"scss/double-slash-comment-empty-line-before": null,
"scss/function-unquote-no-unquoted-strings-inside": null,
"scss/no-global-function-names": null
},
"overrides": [
{
"files": ["**/*.scss"],
"customSyntax": "postcss-scss",
"rules": {
"at-rule-no-unknown": null
}
}
],
"ignoreFiles": [
"resource/assets/stylesheets/jquery-ui.structure.css",
"resources/assets/stylesheets/vendor/*"
......
# 28.02.2025 v 5.5.4
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.5.4&state=all
- Pipeline für 5.5 lintet nicht gegen PHP 7.4 [#5134]
- Courseware: Beim Kopieren und Importieren wird die Einstellung "Titelseite" nicht übernommen [#5138]
- Inhaltsverzeichnis-Block zeigt Seite in Kachelansicht nicht an [#5158]
- Löschen eines Accounts erzeugt fehlerhafte Nachrichten [#5161]
- Wiki: Anlegen einer Seite mit Name ".*" löscht den Inhalt aller Seiten, die ".*" enthalten [#5207]
- Call to a member function each() on null in /srv/studip/lib/models/ConsultationEvent.php:37 [#5266]
- Wiki: "Mach die Welt ein Stückchen schlauer" ist unschlau [#5273]
- Austragen einer Person aus einer Kontaktgruppe führt zu einem Fehler [#5319]
# 28.02.2025 v 5.4.7
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.4.7&state=all
- Veranstaltungsverwaltung: Fehlerhafte Darstellung der Studienbereiche [#2863]
- Veranstaltungsverwaltung: Reiter steht in der DB an falscher Position [#4417]
- Blubber in Veranstaltungen zeigt alle globalen und persönlichen Blubberthreads [#4546]
- Undefined key "ref_id" beim Sprung vom Arbeitsplatz ins mit PHP8 [#4939]
- Studiengruppe Werkzeuge-Seite Tabellarische Ansicht kaputt [#4972]
- Falsche Feldnamen in 5.4.6_tree_changes.php [#5129]
- Courseware: Beim Importieren wird zu jeder Seite ein leerer Abschnitt hinzugefügt [#5139]
- Schnittstelle Ilias: In Ilias gelöschte Nutzer führen zu Inkonsistenz [#5145]
- Zusatzangaben: Widget "Veranstaltungen" wird auch Dozenten angezeigt [#5154]
- Rollenzuweisung für Ankündigungen funktioniert nicht mehr richtig. [#5178]
- QR-Code skaliert nicht horizontal [#5190]
- Raumanfragen: Option für Rückmeldung an alle Lehrenden soll wieder immer verfügbar sein (nochmal) [#5264]
- Courseware: Fehler bei der Auswahl von Farben [#5295]
- JSON-API liefert auch bei gesetztem Accept-Language Header nur den Originalstring [#5306]
# 28.02.2025 v 5.3.10
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.3.10&state=all
- InfoIcon im Dialog wird direkt angezeigt [#773]
- SimpleORMap liest falsche Default-Werte aus dem Schema [#4462]
- PHP8 - Warnungen in den Hilfetouren [#4667]
- Teilnehmende: "Diese Seite für Studierende verbergen" funktioniert nicht mehr [#5009]
- Timeout für HTTP Requests in Ilias-Schnittstelle implementieren [#5014]
- Courseware Aufgaben: Fehlende Funktion im Store [#5019]
- Fehler beim Speichern von I18N-Datenfeldern [#5031]
- Im fromSORM fehlt Eingabename des `templates/forms/select_input.php` [#5080]
- Semesterdarstellung ist bei der Anzeige der Veranstaltungen einer Einrichtung verschoben [#5119]
- BIESt 831 taucht beim AdvancedBasicDataWizard auf [#5121]
- User::name not found [#5122]
- LVGroupsWizardStep läuft auf eine Exception [#5123]
- Leerzeichen in Footer von Text Mails [#5128]
- Log-Events schneiden Pluginnamen ab [#5135]
- Änderung des Inhaltstyps macht Aufgabe unbrauchbar [#5144]
- Externe Seiten: Konfiguration kann mit PHP 8 nicht mehr gespeichert werden [#5184]
- Notwendigkeit von »r« (read) und »w« (write) bei den Einstellungen der Zeitgesteuerten Ordner [#5194]
- Beim Löschen von Konten werden die Einladungen in Studiengruppen nicht gelöscht [#5195]
- Inkonsistente Bezeichnungen der Ordnertypen [#5197]
- Fragebögen: Icon in Startzeitpunkt/Endzeitpunkt bewegt sich beim Öffnen des Dialogs [#5202]
- MVV: Bearbeitungskontext geht nach Bearbeitung einer Fachsemsterzuordnung verloren [#5203]
- Fragebogen: Einstellung "Pflichtfrage" funktioniert bei Freitextfrage nicht [#5204]
- Elemente auf "Privatspäre" unter Profil > Einstellungen sind nicht übersetzt [#5205]
- I18N-Datenfelder auf der MitarbeiterInnen-Seite einer Einrichtung können zur Anzeige von "default_value" führen [#5208]
- Inkonsistentes Verhalten von Datenfeldern [#5213]
- Weitere PHP8-Warnungen [#5216]
- Systemplugins sollten vor allen anderen Plugins geladen werden [#5241]
- Globale Suche nach Veranstaltungen berücksichtigt SEM_VISIBILITY_PERM nicht [#5250]
- Methode User::search() liefert ggf. Einträge ohne User-ID zurück [#5279]
- Funktionen/Gruppen: Multipersonsearch führt zu Speichermangel [#5282]
# 20.12.2024 v 5.5.3
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.5.3&state=all
- Fullcalendar: Das Jahr wird in den Spalten bei der Hochkant-Darstellung auf Mobilgeräten abgeschnitten [#3632]
- Polishing: GUI des neuen Terminkalenders verbessern [#3692]
- Terminkalender: Fehler beim Löschen eines Termins [#4291]
- Courseware: Blöcke landen bei Doppelklick unter "nicht zugewiesene Inhalte" [#4403]
- ILIAS-Schnittstelle: neues Feld matriculation_number wird nicht berücksichtigt [#4446]
- Wiki: Berechtigungen für AutorInnen sind nicht korrekt [#4490]
- Wiki: Speichern der Inhalte umgeht den HTML-Purifier [#4528]
- Terminvergabe: Benachrichtigung bei Absage trotz ausgeschalteter Benachrichtigungen [#4532]
- Position der Anfasser in der Merkliste ist inkorrekt, wenn diese herunter gescrollt wird [#4549]
- Courseware: Merkliste springt beim Aklicken des Aktionsmenüs nach oben [#4552]
- Hinzufügen Button im Inhaltsverzeichnis wird ausgeblendet [#4573]
- Courseware: Quellcode-Bearbeitungsfenster im Textblock ist zu klein [#4579]
- Matrikelnummer kann nicht geleert werden und CSRF-Protection wird nicht abgefragt [#4584]
- Im Wiki einer Veransatltung können beliebige Wikiseiten aus anderen Veranstaltungen angeschaut werden [#4585]
- Wiki-Link zeigt die falsche Seite an [#4602]
- User::convert() referenziert nicht mehr vorhandene Tabellen "wiki" und "wiki_locks" [#4608]
- Elemente in der Schnellsuche sind stellenweise nicht richtig angeordnet [#4617]
- PHP 8: Inkompabilität der Bibliothek `lcobucci/jwt:3.4.6` [#4621]
- Diverse PHP8-Warnungen in den Raumanfragen etc- [#4623]
- Löschen von Nutzerkonten: E-Mail-Benachrichtigung auch bei deaktivierter Option [#4624]
- Scrollen funktioniert nicht im Menü „Abschnitt hinzufügen“ in der CW [#4625]
- PHP8 - Fehler im Kalender [#4657]
- Falscher Fokus im CKEditor bei den Courseware-Zertifikatseinstellungen [#4681]
- Raumanfragen: Räume werden beim Auflösen einer Raumanfrage nicht gebucht [#4690]
- Terminbuchung SQL-Fehler bei Buchung auf eigener Terminvergabe-Seite [#4703]
- Kalender: Vertrauliche Termine können von anderen eingesehen werden [#4706]
- Probleme beim Verschieben von Terminen im Terminkalender [#4723]
- Probleme mit Wiederholungsterminen im Terminkalender [#4724]
- UX-Problem im Terminkalender: Der Terminkalender merkt sich das Datum nicht über Aktionen hinweg [#4725]
- Terminkalender: Mehrtägige Termine können nicht gelöscht werden [#4726]
- lib/fullcalendar.js: Dialoge zum Verschieben von Fullcalendar-Einträgen ist zu groß [#4727]
- Wiki triggert jsupdater auf jeder Seite im Stud.IP [#4738]
- Zugriff auf WikiPage::content überschreibt SORM-Daten [#4780]
- „Invalid day number“ im Kalender-Widget der Startseite, wenn es einen Wiederholungstermin gibt, der sich Sonntags wiederholt [#4801]
- register.js nach Umbau der Registrierung obsolet [#4802]
- Eintrag im Stundenplan verschwindet bei Zuweisung der Farbe grau [#4838]
- Dateiwähler ist nach Upload nicht aktuell [#4861]
- 5.5: Im Terminkalender können keine mehrtägigen ganztägigen Termine angelegt werden [#4918]
- Einrichtung bearbeiten: Homepage ist ein Pflichtfeld [#4930]
- Externe Seiten verwenden SimpleORMapCollection statt SimpleCollection oder Array [#4937]
- Themen von unregelmäßigen Veranstaltungsterminen werden in der Übersicht doppelt ausgegeben [#4944]
- Migration 5.5.23 und 5.5.23.1 zusammenfassen [#4981]
- Wiki: Exception taucht auf, wenn ich mit autor-Berechtigungen eine nicht existierende Seite aufrufe [#4991]
- Wiki in Einrichtung kann keine Startseite haben [#4992]
- Alte Links auf Wikiseiten funktionieren nicht mehr [#4996]
# 20.12.2024 v 5.4.6
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.4.6&state=all
- Lehrendenfilter bleibt leer bei nur einer Einrichtung [#4241]
- Blubber "Benachrichtigungen aktiviert umschalten" funktioniert nicht [#4558]
- Fehler im Job "phpstan" der Pipeline [#4559]
- OER: Besser zurück Typ der Methode (oerModuleIntegrateMaterialToCourse()) [#4561]
- Startseitenwidgets: Englische Pluginbeschreibung wird ignoriert [#4568]
- OER: Die Klasse `CoreDocuments` lädt zweimal [#4581]
- Zeiten/Räume: geschlossene Raumanfragen können nicht wieder geöffnet werden [#4582]
- PHP8-Warnungen in den Kontakten [#4609]
- Veranstaltungsverwaltung: Falscher ursprünglicher Name eines Werkzeugs beim Umbenennen [#4633]
- PHP8-Warnung in der Pluginverwaltung [#4640]
- Fehlerhafte Navigation im Vorlesungs-/Einrichtungsverzeichnis [#4748]
- Veranstaltungsverzeichnis/Einrichtungsverzeichnis findet keine unbegrenzt laufenden Veranstaltungen mehr [#4752]
- Filter nach Kategorien in Verwaltung falsche Ansicht von nicht aktivierten Elementen [#4781]
- PHP8-Warnings beim Anpassen der Farbe auf Meine VA [#4803]
- PHP8 Warnungen in Admin-VA [#4809]
- PHP8-Warnungen beim Auflösen von Raumanfragen [#4821]
- StudipModule/StandardPlugins können nicht mehr in Veranstaltungen aktiviert werden [#4862]
- Hilfelasche: Icon vor "Weiterführende Hilfe" steht in eigener Zeile [#4896]
- Admin-VA: unbegrenzte Veranstaltungen werden nicht exportiert [#4907]
- Diverse Felder auf der Admin-Verwaltungsseite für Veranstaltungen sind nicht gegen XSS geschützt [#4911]
# 20.12.2024 v 5.3.9
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.3.9&state=all
- Verwirrende Sichtbarkeitseinstellungen für Tools in einer Veranstaltung [#613]
- OER Campus: Filter Niveaustufe lässt sich nicht wieder entfernen [#2429]
- Warnung "Einstellungen [...] können nur gespeichert werden, wenn der Selbsteintrag aktiviert ist." beim Anlegen einer Gruppe [#2518]
- Courseware: Leinwand Block [#2867]
- RVV: Ablehnen einer Raumanfrage [#2941]
- Arbeitsplatz: Filter im Dateibereich funktioniert nicht mehr [#3267]
- Bulk Update der Gruppengröße bei Gruppen mit Ordner löscht die Verknüpfung zum Ordner [#3342]
- 'data-proxyfor' triggert change nicht [#3467]
- Falsches HTML in der Modulsuche [#3838]
- Datenschutzerklärung kann während Auswahl der Sichtbarkeit/Nutzungsbedingung nicht geöffnet werden [#3912]
- Orphaned `etask_assignments` [#3971]
- SimpleORMap erzeugt mit PHP 8.1 eine Deprecation Warning [#4134]
- Cache-Verwaltung: Einstellung des Memcached-Server wird beim Hinzufügen von Servern überschrieben [#4265]
- MultiPersonSearch respektiert die Sichtbarkeitseinstellungen nicht [#4318]
- ILIAS-Schnittstelle: Kategorien werden nicht angelegt [#4443]
- ILIAS-Schnittstelle: Geschlechts-Eintrag wird nicht korrekt übergeben [#4444]
- ILIAS-Schnittstelle: falscher Typ für Konstanten in IliasUser.php [#4445]
- ILIAS-Schnittstelle: Option, Kategorie auf den Persönlichen Schreibtisch zu legen, wird angezeigt [#4447]
- Veranstaltungstitel in Dateiübersicht sind nicht verlinkt [#4457]
- Breadcrumbs in der Contentbar brechen nicht richtig um [#4503]
- Warnings beim Kalender [#4527]
- Zeiten/Räume erlaubt Nutzern das Bearbeiten und Löschen fremder Termine [#4530]
- Kontakte - Gruppen können nicht angelegt werden [#4555]
- TypeError: Argument 1 passed to ActionMenu::setContext() must be of the type string, null given [#4556]
- Das Eintragen von Personen über [Grunddaten > Personal] führt zu Fehler [#4557]
- StudipFileCache: Funktion "write" findet existierende Datei nicht [#4560]
- URLHelper in JavaScript verhält sich bei "null"-Werten anders als der in PHP [#4564]
- PHP - Warnungen in den Raumbuchungen [#4566]
- Abstände in der Content-Bar [#4569]
- Externe Seiten: Aufruf der Grundeinstellungen führt zu Fehler [#4571]
- Externe Seiten: Speichern der Konfiguration führt zu Fehler (Mitarbeiter templatebasiert) [#4572]
- Fehlerhaftes Form-Tag eingefügt [#4574]
- app/views/course/wizard/steps/basicdata/index_studygroup.php: htmlReady fehlt [#4575]
- Toter Code: course/studygroup/create wird nicht mehr benutzt [#4576]
- SimpleORMap::getNewId funktioniert nicht für int-Primärschlüssel mit auto_increment [#4586]
- Inkonsequente Status-Auswertung des Coureware-Inhaltselement einer VA im Arbeitsplatz [#4588]
- Courseware: Arbeitsplatz->Courseware->Meine Veranstaltungen zeigt nur ein Lernmaterial pro VA an [#4590]
- Vorschau im Dateidialog erhöht Downloadcounter [#4591]
- PHP-8 Warnungen im Dateibereich [#4597]
- PHP8-Warnungen in Visibility [#4598]
- PHP8-Fehler in der Rest-API [#4599]
- PHP8-Warnungen in MyRealmModel [#4600]
- PHP8-Warnungen in den Wartelisten [#4603]
- PHP8-Warnungen in StudipMail [#4607]
- PHP8-Warnungen im jsupdater [#4610]
- PHP8-Warnungen im Forum [#4611]
- PHP8-Warnungen in den Raumbuchungen [#4612]
- PHP8-Warnungen in den Raumanfragen [#4613]
- PHP8 - Warnungen in den Zeiten / Räume [#4614]
- PHP8-Warnung in der SHibboleth-Anbindung [#4616]
- OER-Campus: Alignment im Editor bei den Tags verschoben [#4629]
- PHP8: Gesammelte Warnings aus der 5.5 in Vechta [#4631]
- Warteliste wird nicht angezeigt [#4632]
- Einträge im Aktionsmenü sind per Tastatur nicht mehr erreichbar [#4641]
- Opengraph-Komponente hat noch Flash-Reste [#4643]
- Courseware: Fehler beim Import [#4649]
- Syntax Highlighting wird nicht mehr ausgeführt [#4650]
- JSON-API wirft Fehler bei Anfragen mit Transfer-Encoding [#4652]
- PHP8 - Warnungen auf Meine Veranstaltungen [#4655]
- PHP8 - Warnungen im Kalender [#4658]
- Weitere diverse PHP8 - Warnungen [#4659]
- PHP8 - Warnungen in den Nachrichten [#4662]
- PHP8-Warnungen in der Teilnehmendenliste [#4663]
- PHP8-Warnungen in der Courseware [#4664]
- PHP8 - Warnungen / Fehler [#4665]
- Gelöschter Absender einer Nachricht wirft Exception [#4678]
- Zeiten/Räume: "Alle auswählen" wählt keine Termine mehr aus [#4688]
- „Ordner für Hausaufgaben“ und „Unsichtbare Ordner“ nutzen das gleiche Icon [#4691]
- Diverse kritische Aktionen über ungeschützten GET Request [#4692]
- Blaue Kopfleiste wächst bei Hover auf Benachrichtigungen [#4698]
- Administration/Veranstaltungs-Stundenplan kann ohne Admin Rechte aufgerufen werden [#4701]
- Parameter $avatar bei PersonalNotifications::addUser() hat falschen Default [#4705]
- ToolsNavigation ist verwaist [#4709]
- fehlende Einstellungen in der config-Tabelle für Notifications [#4711]
- JSON-API setzt die baseURL des URLHelper zu spät [#4712]
- JSONAPI: Lehrende und TutorInnen können nicht ausgelesen werden [#4714]
- Prioritätsverteilung kann durch Studierende manipuliert werden [#4717]
- Fehler beim Logout via SSO [#4731]
- Plugin kann durch die Variable $class gestört werden [#4739]
- Buttons im Dialog reagieren nicht auf Änderungen des zugrundeliegenden Buttons [#4745]
- PHP8-Warning bei der Anzeige der Log-Events [#4757]
- SimpleCollection-Methoden verändern den Typ der Collection [#4758]
- SimpleORMap leeres additional_fields set wirft TypeError in Php8 [#4761]
- Änderungen am Proxy triggern nicht mehr andere Helper-Attribute [#4762]
- Fehler in der JSONAPI [#4764]
- Fehler in ExportPDF, wenn eine eingebundene Datei nicht mehr existiert [#4765]
- Kopieren von Lerninhalten aus bestehenden Lernmaterialien klappt nicht [#4766]
- PHP8 - Warnungen in den Anmeldesets [#4767]
- Typo in CourseWareWelcomeScreen [#4772]
- PHP8-Warnungen in der Modulverwaltung [#4773]
- Request::i18n() ist fehlerhaft, wenn als Default ein I18NString angegeben wird [#4774]
- Zugriff auf CourseDate::statusgruppen ist nicht performant [#4776]
- Migration für #4008, um die falschen Einträge abzuräumen [#4777]
- PHP8-Warnung bei der globalen Suche [#4778]
- Kontrastprobleme Hover Effekt wenn Kontrastreiches Farbeschema aktiviert ist [#4782]
- Import von Courseware läuft in einen Fehler, wenn die Datenbank im Strict-Modus ist [#4792]
- PHP8 - Fehler im Dateibereich [#4804]
- PHP8-Warnungen beim Anlegen von Veranstaltungen [#4805]
- Cache kann nicht konfiguriert werden, wenn CACHING_ENABLE ausgeschaltet ist [#4806]
- Browserslist: caniuse-lite is outdated [#4808]
- Fehler beim Anlegen einer Einrichtung [#4811]
- PHP8-Warnung in der MultipersonSearch [#4812]
- PHP8 - Warnungen in der alten RestAPI [#4813]
- PHP8-Warnungen in den Raumanfragen [#4814]
- Diverse weitere PHP8 - Fehler / Warnungen [#4823]
- Weitere PHP8-Warnungen in der Version 5.5 [#4829]
- PHP8 - Warnungen in der Teilnehmendenliste [#4830]
- PHP8-Warnungen in der Courseware [#4834]
- PHP8 - Fehler / Warnungen beim Anlegen von Standorten / Gebäuden und Räumen [#4841]
- Paging/Offset der JSON-API für User funktioniert nicht [#4844]
- Forum: Abfrage nach Kategorie "Allgemein" funktioniert nicht zuverlässig [#4850]
- Forum: Nach Aktivierung ist das Icon rot ohne relevante Inhalte [#4851]
- 2FA: nach zu vielen ungültigen Versuchen kann Token nicht erneut eingegeben werden [#4855]
- Ausgabe von ResourceRequest::getDateString() für Einzeltermine ist unsortiert [#4856]
- Die Übersetzungsdomäne für Plugins wird nicht beim Initialisieren der Übersetzungen gesetzt [#4857]
- Fehlerhafte Type Hints in I18NString [#4860]
- I18NString speichert unter Umständen zu viele Daten [#4863]
- SimpleORMap::isFieldDirty() ist defekt für i18n-Felder [#4864]
- Personendaten drucken (DSGVO) , formatReady fehlt bei den Inhalten [#4882]
- PHP8-Warnungen im htmlpurifier [#4883]
- Speichern von I18N-Datenfeldern ist defekt [#4891]
- Eintragen von Standardvertretung scheitert mit "Unzulässige Request-Methode" [#4897]
- PHP8-TypeError beim Genehmigen eines Studiengangs [#4899]
- PHP8 Warning in Auswertung von Likert- und Polskala-Fragen [#4906]
- Probleme mit Nicht-Pflicht-Fragen bei Likert- und Polskalen [#4908]
- Drag & Drop von Räumen mit sehr langem Namen in Raumgruppen funktioniert nicht wie erwartet [#4917]
- Weitere PHP8-Warnungen [#4925]
- OER Campus: Löschen von Themen beim Anlegen eines Materials fehlerbehaftet [#4931]
- Zeiten/Räume: Sammelaktion bucht Termine nicht mehr in der auswählten Reihenfolge [#4938]
- PHP8 Warning in LVGrizosWizardStep [#4941]
- Funktion "tooltipHtmlIcon()" interpretiert kein HTML und zeigt alle Tooltips als wichtig an [#4947]
- PHP >= 8.1: Probleme durch Änderungen am Verhalten von Rückgaben durch PDO [#4971]
- CKEditor: readonly wird nicht gesetzt [#4979]
- Im Stundenplan werden veraltete Termine angezeigt [#4984]
- Raumgruppen: Admin kann beim Zuweisen von Rechten unsichtbare Accounts nicht finden [#4994]
- Meldung bei fehlender Datenbankverbindung anpassen [#5012]
# 03.09.2024 v 5.5.2
https://gitlab.studip.de/studip/studip/-/issues?milestone_title=Stud.IP+5.5.2&state=all
......
......@@ -87,12 +87,12 @@ optimize-icons: npm
find public/assets/images/icons/blue -type f | xargs -P0 npx svgo -q --config=config/svgo.config.js
icons: optimize-icons
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#000000/" {} > {}' | sed 's#icons/blue#icons/black#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#00962d/" {} > {}' | sed 's#icons/blue#icons/green#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#6e6e6e/" {} > {}' | sed 's#icons/blue#icons/grey#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#cb1800/" {} > {}' | sed 's#icons/blue#icons/red#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#ffffff/" {} > {}' | sed 's#icons/blue#icons/white#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#ffad00/" {} > {}' | sed 's#icons/blue#icons/yellow#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#000000/g" {} > {}' | sed 's#icons/blue#icons/black#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#00962d/g" {} > {}' | sed 's#icons/blue#icons/green#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#6e6e6e/g" {} > {}' | sed 's#icons/blue#icons/grey#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#cb1800/g" {} > {}' | sed 's#icons/blue#icons/red#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#ffffff/g" {} > {}' | sed 's#icons/blue#icons/white#2' | sh
find public/assets/images/icons/blue -type f -print0 | xargs -0 -n1 -I{} echo 'sed "s/#28497c/#ffad00/g" {} > {}' | sed 's#icons/blue#icons/yellow#2' | sh
# default rules for gettext handling
js-%.pot: $(VUE_SOURCES)
......
......@@ -4,8 +4,73 @@
## Neue Features
### System
- Der Stud.IP-Cache ist nun kompatibel zu PSR-6. ([TIC #3701](https://gitlab.studip.de/studip/studip/-/issues/3701))
- Das `User`-Model hat die Methode `hasPermissionLevel()` erhalten, um einfach abfragen zu können, ob eine Person einen bestimmten Berechtigungsstatus hat. ([Issue #3453](https://gitlab.studip.de/studip/studip/-/issues/3453))
- In der Standort-Verwaltung können nun nicht nur Ferien sondern auch Feiertage konfiguriert werden. Dies erlaubt das Markieren von Feiertagen als gesetzliche Feiertage, da diese je nach Bundesland variieren können. ([Issue #2795](https://gitlab.studip.de/studip/studip/-/issues/2795))
- Die Nutzungsbedingungen sind nun nicht mehr als statische HTML-Dateien hinterlegt, sondern können analog zu Impressum, Datenschutz- und Barrierefreiheitserklärung direkt über die Oberfläche bearbeitet werden. Initial ist diese Seite aber im Entwurfsmodus und daher für Nicht-Roots unsichtbar. Damit andere Personen beim ersten Login diese Nutzungsbedingungen sehen und ihnen zustimmen können, muss der Entwurfsmodus für diese Seite abgeschaltet werden. ([TIC #4433](https://gitlab.studip.de/studip/studip/-/issues/4433))
### Layout
- Die Login-Seite wurde überarbeitet
- Das Design von Stud.IP wurde modernisiert
- Neue Avatarbilder
### Courseware
- Rechte und Sichtbarkeit überarbeitet
- Verbesserter Übersichtsdialog
- Rechte und Sichtbarkeit können für ein ganzes Lernmaterial gesetzt werden
- [Issue #3442](https://gitlab.studip.de/studip/studip/-/issues/3442)
- Peer-Review für Aufgaben
- Lehrende können Peer-Review-Prozess für Aufgaben einstellen
- Lernende sehen Aufgabenlösungen ein, geben Feedback und Bewertung dazu ab
- [Issue #2484](https://gitlab.studip.de/studip/studip/-/issues/2484)
- Blubber-Block
- Blubber Diskussionen können jetzt als Block eingebunden werden
- Lernmaterialübersicht im Inhaltsverzeichnis
- Schafft einen Überblick über weitere Lernmaterialien in der Veranstaltungen ohne den Kontext verlassen zu müssen
- Neues Layout für den Merksatz-Block
### Vips Plugin wird als Aufgaben-Werkzeug in Kern integriert
- Mit Vips lassen sich Selbsttests, Übungen und Klausuren erstellen
- Lernende können Vips Aufgabenblätter in Stud.IP bearbeiten und erhalten dort auch ihre Ergebnisse
- Für eine Vielzahl von Aufgabentypen besteht die Möglichkeit einer Autokorrektur
- [Issue #4258](https://gitlab.studip.de/studip/studip/-/issues/4258)
- [Plugin](https://develop.studip.de/studip/plugins.php/pluginmarket/presenting/details/81097da5ef66a002998b75d5eeece1f0)
### Neues Benachrichtigungssystem
- Vereinheitlichung wie Stud.IP mit Nutzenden kommuniziert
- Messageboxen, Companionmeldungen und Notifications werden vereinheitlicht
- [Issue #660](https://gitlab.studip.de/studip/studip/-/issues/660)
### Garuda Plugin in Kern integriert
- Mit Garuda können Zielgruppen definiert werden, um diesen Sammelnachrichten zukommen zu lassen
- [Issue #3326](https://gitlab.studip.de/studip/studip/-/issues/3326)
- [Plugin](https://develop.studip.de/studip/plugins.php/pluginmarket/presenting/details/d24cb47ee246033c325496b832e64147)
### Bilderpool
- Neuer Archiv Upload
- Ermöglicht das Einpflegen von einer Vielzahl von Bilder mit nur einem Upload
- Metadaten werden in dem Archiv als CSV-Datei mitgegeben und müssen nicht mehr einzeln eingegeben werden
- Stud.IP Bildersammlung kann mit nur einem Upload integriert werden
- Die Stud.IP Bildersammlung finden Sie [hier](https://gitlab.studip.de/studip/bilderpool)
### Anzeige von ILIAS-Kursen auf "Mein Arbeitsplatz"
- Bei aktivierter ILIAS-Schnittstelle können Lehrende ihre Stud.IP Veranstaltungen mit ILIAS-Kursen verknüpfen
- Lernende erhalten eine Übersicht über ihre ILIAS-Kurse im Stud.IP Arbeitsplatz
### Assistent für Roots nach Updates
- Nach einem Update auf eine neue Stud.IP Version werden Nutzenden mit Root-Rechten die neuen Features der Version präsentiert
### Studiengruppen
- Um Studiengruppen sichtbarer und interessanter zu machen wurde eine Reihe von Verbesserungen vorgenommen
- Neues Widget für die Startseite
- Möglichkeit Studiengruppen für eine Veranstaltungen vorzuschlagen
- [Issue #3616](https://gitlab.studip.de/studip/studip/-/issues/3616)
## Breaking changes
......@@ -77,6 +142,7 @@
- Die Zuordnung von Veranstaltungen zu Semestern anhand von Timestamps wurde entfernt. In der Datenbank wurden die Spalten `start_time` und `duration_time` der Tabelle `seminare` entfernt. ([Issue #4391]https://gitlab.studip.de/studip/studip/-/issues/4391))
- Plugins, die Veranstaltungen anhand von Timestamps laden oder anderweitig verwenden, müssen angepasst werden!
- Das Mapping von Veranstaltungen zu Semestern findet nun ausschließlich anhand der Semester-ID über die Verknüpfungstabelle `semester_courses` statt.
- Die ELearning-Schnittstelle wurde ausgebaut. In diesem Rahmen wurden auch die Methoden `printhead()` und `printcontent()` ersatzlos entfernt. ([Issue #4109](https://gitlab.studip.de/studip/studip/-/issues/4109))
## Security related issues
......
......@@ -31,7 +31,9 @@ class Admin_AdditionalController extends AuthenticatedController
"Veranstaltung zu verändern."));
}
Sidebar::get()->addWidget(new CourseManagementSelectWidget());
if ($GLOBALS['perm']->have_studip_perm('admin', $this->course->id)) {
Sidebar::get()->addWidget(new CourseManagementSelectWidget());
}
}
/**
......
......@@ -44,11 +44,11 @@ class Admin_AutoinsertController extends AuthenticatedController
if (Request::submitted('suchen')) {
if (Request::get('sem_search')) {
$this->sem_search = Request::get('sem_search');
$this->sem_select = Request::option('sem_select');
$this->sem_select = Request::option('sem_select') ?: null;
$search = new SeminarSearch();
$this->seminar_search = $search->getResults
(Request::get('sem_search'),
['search_sem_sem' => Request::option('sem_select')]
$this->seminar_search = $search->getResults(
$this->sem_search,
['search_sem_sem' => $this->sem_select]
);
if (count($this->seminar_search) == 0) {
PageLayout::postInfo(_('Es wurden keine Veranstaltungen gefunden.'));
......
......@@ -47,16 +47,14 @@ class Admin_CacheController extends AuthenticatedController
$this->sidebar->addWidget($views);
if ($this->enabled) {
$actions = new ActionsWidget();
$actions->addLink(
_('Cache leeren'),
$this->url_for('admin/cache/flush'),
Icon::create('decline'),
['data-confirm' => _('Soll der gesamte Inhalt des Caches wirklich gelöscht werden?')]
);
$this->sidebar->addWidget($actions);
}
$actions = new ActionsWidget();
$actions->addLink(
_('Cache leeren'),
$this->url_for('admin/cache/flush'),
Icon::create('decline'),
['data-confirm' => _('Soll der gesamte Inhalt des Caches wirklich gelöscht werden?')]
);
$this->sidebar->addWidget($actions);
}
/**
......@@ -123,7 +121,7 @@ class Admin_CacheController extends AuthenticatedController
*/
public function flush_action()
{
$cache = \Studip\Cache\Factory::getCache();
$cache = \Studip\Cache\Factory::loadSystemCache(true);
$cache->flush();
PageLayout::postSuccess(_('Die Inhalte des Caches wurden gelöscht.'));
......
......@@ -12,10 +12,12 @@ class Admin_CourseplanningController extends AuthenticatedController
{
parent::before_filter($action, $args);
if ($GLOBALS['perm']->have_perm('admin')) {
Navigation::activateItem('/browse/my_courses/schedule');
if (!$GLOBALS['perm']->have_perm('admin')) {
throw new AccessDeniedException();
}
Navigation::activateItem('/browse/my_courses/schedule');
$this->insts = Institute::getMyInstitutes($GLOBALS['user']->id);
if (empty($this->insts) && !$GLOBALS['perm']->have_perm('root')) {
......@@ -82,7 +84,7 @@ class Admin_CourseplanningController extends AuthenticatedController
foreach ($this->events as $event) {
$start_date_time = explode('T', $event['start']);
$time_elements = explode(':', $start_date_time[1]);
if (!$event['conform'] || $time_elements[0] % 2) {
if (empty($event['conform']) || $time_elements[0] % 2) {
Sidebar::get()->getWidget('actions')->addLink(
_('Veranstaltungen außerhalb des Rasters'),
$this->nonconformURL(),
......
......@@ -23,7 +23,6 @@
* @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
......@@ -171,11 +170,16 @@ class Admin_CoursesController extends AuthenticatedController
Now draw the configurable elements according
to the values inside the visibleElements array.
*/
$institute_id = null;
if (!empty($visibleElements['search'])) {
$this->setSearchWiget();
}
if (!empty($visibleElements['institute'])) {
$filter->addElement($this->getInstSelector());
$inst_selector = $filter->addElement($this->getInstSelector());
if (count($inst_selector->getOptions()) === 1) {
$institute_id = $this->insts[0]['Institut_id'];
}
}
if (!empty($visibleElements['semester'])) {
$filter->addElement($this->getSemesterSelector());
......@@ -187,7 +191,7 @@ class Admin_CoursesController extends AuthenticatedController
$filter->addElement($this->getCourseTypeWidget());
}
if (!empty($visibleElements['teacher'])) {
$filter->addElement($this->getTeacherWidget());
$filter->addElement($this->getTeacherWidget($institute_id));
}
$sidebar->addWidget($filter, 'filter');
......@@ -293,7 +297,6 @@ class Admin_CoursesController extends AuthenticatedController
PageLayout::setHelpKeyword('Basis.Veranstaltungen');
PageLayout::setTitle(_('Verwaltung von Veranstaltungen und Einrichtungen'));
// Add admission functions.
PageLayout::addScript('studip-admission.js');
$this->max_show_courses = Config::get()->MAX_SHOW_ADMIN_COURSES;
}
......@@ -424,7 +427,6 @@ class Admin_CoursesController extends AuthenticatedController
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') . '--',
......@@ -441,7 +443,6 @@ class Admin_CoursesController extends AuthenticatedController
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')]);
......@@ -480,7 +481,17 @@ class Admin_CoursesController extends AuthenticatedController
$data['buttons_bottom'] = (string) \Studip\Button::createAccept(
_('Teilnehmendenexport'), 'batch_export_members',
[
'formaction' => URLHelper::getURL('dispatch.php/admin/user/batch_export_members'),
'formaction' => URLHelper::getURL('dispatch.php/admin/courses/batch_export_members'),
'data-dialog' => 'size=big'
]);
break;
case 23: // Mass mail to selected courses
$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(
_('Nachricht an ausgewählte Veranstaltungen'), 'massmail',
[
'formaction' => URLHelper::getURL('dispatch.php/massmail/quick/courses'),
'data-dialog' => 'size=big'
]);
break;
......@@ -628,7 +639,7 @@ class Admin_CoursesController extends AuthenticatedController
}
if (in_array('number', $activated_fields)) {
$d['number'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">'
.$course->veranstaltungsnummer
. htmlReady($course->veranstaltungsnummer)
.'</a>';
}
if (in_array('avatar', $activated_fields)) {
......@@ -638,18 +649,18 @@ class Admin_CoursesController extends AuthenticatedController
}
if (in_array('type', $activated_fields)) {
$semtype = $course->getSemType();
$d['type'] = $semtype['name'];
$d['type'] = htmlReady($semtype['name']);
}
if (in_array('room_time', $activated_fields)) {
$strings = $course->getAllDatesInSemester()->toStringArray();
$d['room_time'] = implode('<br>', $strings) ?: _('nicht angegeben');
}
if (in_array('semester', $activated_fields)) {
$d['semester'] = $course->semester_text;
$d['semester'] = htmlReady($course->semester_text);
$d['semester_sort'] = $course->start_semester ? $course->start_semester->beginn : 0;
}
if (in_array('institute', $activated_fields)) {
$d['institute'] = $course->home_institut ? $course->home_institut->name : $course->institute;
$d['institute'] = htmlReady($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>";
......@@ -693,8 +704,8 @@ class Admin_CoursesController extends AuthenticatedController
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 href="'. URLHelper::getLink('dispatch.php/course/go', ['to' => $course->id, 'redirect_to' => $icon->getURL()]).'"'. ($icon->getTitle() ? ' title="'.htmlReady($icon->getTitle()).'"' : '') .'>
'. $icon->getImage()->asImg() .'
</a>
</li>';
}
......@@ -830,7 +841,12 @@ class Admin_CoursesController extends AuthenticatedController
$d['action'] = $template->render();
break;
case 22: //Masssenexport Teilnehmendendaten
$template = $tf->open('admin/courses/batch_export_members');
$template = $tf->open('admin/courses/export_members');
$template->course = $course;
$d['action'] = $template->render();
break;
case 23: //Masssenexport Teilnehmendendaten
$template = $tf->open('admin/courses/massmail');
$template->course = $course;
$d['action'] = $template->render();
break;
......@@ -956,9 +972,7 @@ class Admin_CoursesController extends AuthenticatedController
if (count($filter_config) > 0) {
$filter = AdminCourseFilter::get();
PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'applyFilters', $filter);
$filter->query->join('semester_courses', 'semester_courses', 'semester_courses.course_id = seminare.Seminar_id')
->join('semester_data', 'semester_data', 'semester_data.semester_id = semester_courses.semester_id')
->orderBy('semester_data.beginn, seminare.name');
$filter->query->orderBy('seminare.name');
$courses = $filter->getCourses();
$view_filters = $this->getViewFilters();
......@@ -1185,7 +1199,7 @@ class Admin_CoursesController extends AuthenticatedController
$course = Course::find($course_id);
if ($course->isOpenEnded() || $course->end_semester->visible) {
$visibility = $visibilites[$course_id] ?: 0;
$visibility = $visibilites[$course_id] ?? 0;
if ($course->visible == $visibility) {
continue;
......@@ -1316,6 +1330,73 @@ class Admin_CoursesController extends AuthenticatedController
$this->notice = $course->config->COURSE_ADMIN_NOTICE;
}
public function batch_export_members_action()
{
PageLayout::setTitle(_('Teilnehmendendaten exportieren'));
$courseIds = Request::optionArray('export_members');
$order = Config::get()->IMPORTANT_SEMNUMBER
? "ORDER BY `VeranstaltungsNummer`, `Name`"
: "ORDER BY `Name`";
$this->courses = Course::findMany($courseIds, $order);
// check if at least one course was selected (this can only happen from admin courses overview):
if (count($this->courses) === 0) {
PageLayout::postWarning('Es wurde keine Veranstaltung gewählt.');
$this->relocate('admin/courses');
}
}
/*
* Export member data of all selected courses
*/
public function do_batch_export_action()
{
if (Request::submitted('xlsx')) {
$export_format = 'xlsx';
} else if (Request::submitted('csv')) {
$export_format = 'csv';
} else {
PageLayout::postError('Nicht unterstütztes Exportformat.');
$this->relocate('admin/courses');
}
$tmp_folder = $GLOBALS['TMP_PATH'] . '/temp_folder_' . md5(uniqid());
mkdir($tmp_folder);
$courses = Course::findMany(Request::optionArray('courses'));
$header = [
_('Status'),
_('Anrede'),
_('Titel'),
_('Vorname'),
_('Nachname'),
_('Titel nachgestellt'),
_('Benutzername'),
_('Adresse'),
_('Telefonnr.'),
_('E-Mail'),
_('Anmeldedatum'),
_('Matrikelnummer'),
_('Studiengänge'),
_('Position'),
];
foreach ($courses as $course) {
if ($GLOBALS['perm']->have_studip_perm('dozent', $course->id)) {
$members = $course->getMembersData();
$filename = FileManager::cleanFileName('Teilnehmendenexport ' . $course->Name . '.' . $export_format);
$filepath = $tmp_folder . '/'. $filename;
$this->render_spreadsheet($header, $members, $export_format, $filename, $filepath);
}
}
$archive_file_path = $GLOBALS['TMP_PATH'] . '/archiv.zip';
$archive_filename = 'Export_Teilnehmendendaten.zip';
FileArchiveManager::createArchiveFromPhysicalFolder($tmp_folder, $archive_file_path);
rmdirr($tmp_folder);
$this->render_temporary_file($archive_file_path, $archive_filename, 'application/zip');
}
/**
* Return a specifically action or all available actions
......@@ -1426,12 +1507,20 @@ class Admin_CoursesController extends AuthenticatedController
22 => [
'name' => _('Teilnehmendenexport'),
'title' => _('Teilnehmendenexport'),
'url' => 'dispatch.php/admin/user/batch_export_members',
'url' => 'dispatch.php/admin/courses/batch_export_members',
'dialogform' => true,
'multimode' => true,
'partial' => 'batch_export_members.php'
'partial' => 'export_members.php'
],
23 => [
'name' => _('Nachricht schreiben'),
'title' => _('Nachricht schreiben'),
'url' => 'dispatch.php/massmail/quick/courses',
'dialogform' => true,
'multimode' => true,
'partial' => 'massmail.php'
]
];
if (!$GLOBALS['perm']->have_perm('admin')) {
......
......@@ -156,7 +156,13 @@ class Admin_DatafieldsController extends AuthenticatedController
} elseif ($type === 'studycourse') {
$datafield->object_class = Request::option('object_class');
} else {
$datafield->object_class = array_sum(Request::getArray('object_class')) ?: null;
$object_class = Request::getArray('object_class');
if (empty($object_class) || (count($object_class) === 1 && $object_class[0] === 'NULL')) {
$object_class = null;
} else {
$object_class = array_sum($object_class);
}
$datafield->object_class = $object_class;
}
$datafield->edit_perms = Request::get('edit_perms');
$datafield->view_perms = Request::get('visibility_perms');
......@@ -188,6 +194,7 @@ class Admin_DatafieldsController extends AuthenticatedController
$this->institutes = Institute::getMyInstitutes();
if (!$this->object_typ) {
$this->render_action('type_select');
return;
}
if (Request::isXhr() && $this->type_name) {
......
......@@ -35,7 +35,7 @@ class Admin_HolidaysController extends AuthenticatedController
URLHelper::addLinkParam('filter', $this->filter);
}
$this->setSidebar();
$this->setSidebar($action);
}
/**
......@@ -123,13 +123,33 @@ class Admin_HolidaysController extends AuthenticatedController
$this->redirect('admin/holidays');
}
public function holidays_action(): void
{
$this->holidays = Holidays::getHolidays(true, true);
$this->customized = Config::get()->CUSTOMIZED_HOLIDAYS;
}
public function store_holidays_action(): void
{
CSRFProtection::verifyUnsafeRequest();
Config::get()->store(
'CUSTOMIZED_HOLIDAYS',
Request::intArray('holidays')
);
PageLayout::postSuccess(_('Die Änderungen wurden gespeichert.'));
$this->redirect($this->holidaysURL());
}
/**
* Checks a string if it is a valid date and returns the according
* unix timestamp if valid.
*
* @param string $name Parameter name to extract from request
* @param string $time Optional time segment
* @return mixed Unix timestamp or false if not valid
* @return int|false Unix timestamp or false if not valid
*/
private function getTimeStamp($name, $time = '0:00:00')
{
......@@ -146,27 +166,46 @@ class Admin_HolidaysController extends AuthenticatedController
/**
* Adds the content to sidebar
*/
private function setSidebar()
private function setSidebar(string $action): void
{
$sidebar = Sidebar::Get();
$views = new ViewsWidget();
$views->addLink(_('Alle Einträge'),
$this->url_for('admin/holidays', ['filter' => null]))
->setActive(!$this->filter);
$views->addLink(_('Aktuelle/zukünftige Einträge'),
$this->url_for('admin/holidays', ['filter' => 'current']))
->setActive($this->filter === 'current');
$views->addLink(_('Vergangene Einträge'),
$this->url_for('admin/holidays', ['filter' => 'past']))
->setActive($this->filter === 'past');
$sidebar->addWidget($views);
$links = new ActionsWidget();
$links->addLink(_('Neue Ferien anlegen'),
$this->url_for('admin/holidays/edit', ['filter' => null]),
Icon::create('add', 'clickable'))
->asDialog('size=auto');
$sidebar->addWidget($links);
$is_vacation_view = !in_array($action, ['holidays', 'store_holidays']);
$views = $sidebar->addWidget(new ViewsWidget());
$views->addLink(
_('Ferien'),
$this->indexURL()
)->setActive($is_vacation_view);
$views->addLink(
_('Feiertage'),
$this->holidaysURL()
)->setActive(!$is_vacation_view);
if (!$is_vacation_view) {
return;
}
$views = $sidebar->addWidget(new ViewsWidget());
$views->setTitle(_('Ansichtseinstellungen'));
$views->addLink(
_('Alle Einträge'),
$this->indexURL(['filter' => null])
)->setActive(!$this->filter);
$views->addLink(
_('Aktuelle/zukünftige Einträge'),
$this->indexURL(['filter' => 'current'])
)->setActive($this->filter === 'current');
$views->addLink(
_('Vergangene Einträge'),
$this->indexURL(['filter' => 'past'])
)->setActive($this->filter === 'past');
$links = $sidebar->addWidget(new ActionsWidget());
$links->addLink(
_('Neue Ferien anlegen'),
$this->editURL(['filter' => null]),
Icon::create('add')
)->asDialog('size=auto');
}
}
......@@ -51,6 +51,8 @@ class Admin_IliasInterfaceController extends AuthenticatedController
PageLayout::setHelpKeyword('Basis.Ilias');
$this->modules_available = ConnectedIlias::getSupportedModuleTypes();
$this->studip_roles = ['autor', 'tutor', 'dozent', 'admin', 'root'];
$this->sidebar = Sidebar::get();
}
......@@ -93,18 +95,19 @@ class Admin_IliasInterfaceController extends AuthenticatedController
public function save_interface_settings_action()
{
if (Request::submitted('submit')) {
$this->ilias_interface_config['edit_moduletitle'] = (boolean)Request::get('ilias_interface_edit_moduletitle');
$this->ilias_interface_config['show_offline'] = (boolean)Request::get('ilias_interface_show_offline');
$this->ilias_interface_config['search_active'] = (boolean)Request::get('ilias_interface_search_active');
$this->ilias_interface_config['show_tools_page'] = (boolean)Request::get('ilias_interface_show_tools_page');
$this->ilias_interface_config['add_statusgroups'] = (boolean)Request::get('ilias_interface_add_statusgroups');
$this->ilias_interface_config['cache'] = (boolean)Request::get('ilias_interface_cache');
$this->ilias_interface_config['edit_moduletitle'] = Request::bool('ilias_interface_edit_moduletitle', false);
$this->ilias_interface_config['show_offline'] = Request::bool('ilias_interface_show_offline', false);
$this->ilias_interface_config['search_active'] = Request::bool('ilias_interface_search_active', false);
$this->ilias_interface_config['show_course_paths'] = Request::bool('ilias_interface_show_course_paths', false);
$this->ilias_interface_config['show_tools_page'] = Request::bool('ilias_interface_show_tools_page', false);
$this->ilias_interface_config['add_statusgroups'] = Request::bool('ilias_interface_add_statusgroups', false);
$this->ilias_interface_config['cache'] = Request::bool('ilias_interface_cache', false);
$this->ilias_interface_config['allow_change_course'] = Request::get('ilias_interface_allow_change_course');
$this->ilias_interface_config['allow_add_own_course'] = Request::get('ilias_interface_allow_add_own_course');
//store config entry
Config::get()->store('ILIAS_INTERFACE_BASIC_SETTINGS', $this->ilias_interface_config);
Config::get()->store('ILIAS_INTERFACE_MODULETITLE', Request::quoted('ilias_interface_moduletitle'));
Config::get()->store('ILIAS_INTERFACE_MODULETITLE', Request::get('ilias_interface_moduletitle'));
PageLayout::postSuccess(_('Einstellungen wurden gespeichert.'));
}
$this->redirect($this->url_for('admin/ilias_interface'));
......@@ -119,7 +122,7 @@ class Admin_IliasInterfaceController extends AuthenticatedController
$this->valid_url = false;
$this->ilias_version = '';
$this->ilias_version_date = '';
$this->clients = [];
$this->ilias_clients = [];
if ($index === 'new') {
// default values
$this->ilias_config = [
......@@ -127,8 +130,11 @@ class Admin_IliasInterfaceController extends AuthenticatedController
'name' => '',
'version' => '',
'url' => _('https://<URL zur ILIAS-Installation>'),
'http_connection_timeout' => 1,
'http_request_timeout' => 3,
'client' => '',
'ldap_enable' => '',
'reconnect_accounts' => false,
'no_account_updates' => false,
'admin' => 'ilias_soap_admin',
'admin_pw' => '',
......@@ -150,7 +156,8 @@ class Admin_IliasInterfaceController extends AuthenticatedController
'author_role_name' => 'Author',
'author_role' => '',
'author_perm' => 'tutor'
'author_perm' => 'tutor',
'additional_roles' => []
];
// fetch existing indicies from previously connected ILIAS installations
......@@ -163,9 +170,11 @@ class Admin_IliasInterfaceController extends AuthenticatedController
// get ILIAS server info
if (Request::get('ilias_url')) {
$info = ConnectedIlias::getIliasInfo(Request::get('ilias_url'));
if (count($info)) {
if (is_array($info) && count($info)) {
$this->valid_url = true;
$this->ilias_config['url'] = Request::get('ilias_url');
$this->ilias_config['http_connection_timeout'] = (int) Request::get('ilias_http_connection_timeout');
$this->ilias_config['http_request_timeout'] = (int) Request::get('ilias_http_request_timeout');
if ($info['version']) {
$this->ilias_version = $info['version'];
$this->ilias_version_date = $info['version_date'];
......@@ -215,6 +224,8 @@ class Admin_IliasInterfaceController extends AuthenticatedController
if (Request::get('ilias_name')) {
$this->ilias_config['name'] = Request::get('ilias_name');
$this->ilias_config['url'] = Request::get('ilias_url');
$this->ilias_config['http_connection_timeout'] = (int) Request::get('ilias_http_connection_timeout');
$this->ilias_config['http_request_timeout'] = (int) Request::get('ilias_http_request_timeout');
}
$info = ConnectedIlias::getIliasInfo($this->ilias_config['url']);
if (count($info)) {
......@@ -236,14 +247,15 @@ class Admin_IliasInterfaceController extends AuthenticatedController
*/
public function edit_content_action($index)
{
$this->ilias_config = $this->ilias_configs[$index];
$this->ilias_index = $index;
$this->ilias_datafields = [];
$connected_ilias = new ConnectedIlias($index);
$this->ilias_config = $connected_ilias->ilias_config;
if ($admin_id = $connected_ilias->soap_client->lookupUser($this->ilias_config['admin'])) {
$user = $connected_ilias->soap_client->getUser($admin_id);
if (array_key_exists('udfs', $user)) {
if (!empty($user) && array_key_exists('udfs', $user)) {
$this->ilias_datafields = $user['udfs'];
}
}
......@@ -255,8 +267,11 @@ class Admin_IliasInterfaceController extends AuthenticatedController
*/
public function edit_permissions_action($index)
{
$this->ilias_config = $this->ilias_configs[$index];
$this->ilias_index = $index;
$connected_ilias = new ConnectedIlias($index);
$this->ilias_config = $connected_ilias->ilias_config;
$this->global_roles = $connected_ilias->soap_client->getRoles('global', -1);
}
/**
......@@ -282,7 +297,7 @@ class Admin_IliasInterfaceController extends AuthenticatedController
{
CSRFProtection::verifyUnsafeRequest();
if (Request::submitted('submit')) {
if (Request::submittedSome('submit', 'add_additional_role', 'remove_additional_role')) {
// set basic server settings
if (Request::getInstance()->offsetExists('ilias_name')) {
$this->ilias_configs[$index]['name'] = Request::get('ilias_name');
......@@ -290,6 +305,8 @@ class Admin_IliasInterfaceController extends AuthenticatedController
$this->ilias_configs[$index]['version'] = Request::get('ilias_version');
}
$this->ilias_configs[$index]['url'] = Request::get('ilias_url');
$this->ilias_configs[$index]['http_connection_timeout'] = (int) Request::get('ilias_http_connection_timeout');
$this->ilias_configs[$index]['http_request_timeout'] = (int) Request::get('ilias_http_request_timeout');
if (Request::getInstance()->offsetExists('ilias_client')) {
$this->ilias_configs[$index]['client'] = Request::get('ilias_client');
}
......@@ -351,6 +368,7 @@ class Admin_IliasInterfaceController extends AuthenticatedController
$this->ilias_configs[$index]['course_veranstaltungsnummer'] = Request::get('ilias_course_veranstaltungsnummer');
}
$this->ilias_configs[$index]['delete_ilias_users'] = Request::get('ilias_delete_ilias_users');
$this->ilias_configs[$index]['reconnect_accounts'] = Request::bool('ilias_reconnect_accounts', false);
$this->ilias_configs[$index]['delete_ilias_courses'] = Request::get('ilias_delete_ilias_courses');
$this->ilias_configs[$index]['category_create_on_add_module'] = Request::get('ilias_category_create_on_add_module');
$this->ilias_configs[$index]['category_to_desktop'] = Request::get('ilias_category_to_desktop');
......@@ -371,10 +389,59 @@ class Admin_IliasInterfaceController extends AuthenticatedController
// set permissions settings
if (Request::getInstance()->offsetExists('ilias_author_role_name')) {
$this->global_roles = $connected_ilias->soap_client->getRoles('global', -1);
$this->ilias_configs[$index]['author_role_name'] = Request::get('ilias_author_role_name');
$this->ilias_configs[$index]['author_perm'] = Request::get('ilias_author_perm');
$this->ilias_configs[$index]['allow_change_account'] = Request::get('ilias_allow_change_account');
// remove ilias role assignment
if (
Request::submitted('remove_additional_role')
&& Request::option('studip_role')
&& array_key_exists('additional_roles', $this->ilias_configs[$index])
) {
$studip_role = Request::option('studip_role');
$ilias_role = Request::option('remove_additional_role');
if (
in_array($studip_role, $this->studip_roles)
&& array_key_exists($studip_role, $this->ilias_configs[$index]['additional_roles'])
&& array_key_exists($ilias_role, $this->ilias_configs[$index]['additional_roles'][$studip_role])
) {
unset($this->ilias_configs[$index]['additional_roles'][$studip_role][$ilias_role]);
PageLayout::postSuccess(sprintf(_('ILIAS-Rollenzuweisung der Stud.IP-Rechtestufe %s wurde entfernt.'), $studip_role));
}
}
// add ilias role assignment
if (
Request::submitted('add_additional_role')
&& Request::option('add_studip_role')
&& Request::option('add_ilias_role')
) {
$studip_role = Request::option('add_studip_role');
$ilias_role = Request::option('add_ilias_role');
$role_already_assigned = false;
if (!array_key_exists('additional_roles', $this->ilias_configs[$index])) {
$this->ilias_configs[$index]['additional_roles'] = [];
}
if (
in_array($studip_role, $this->studip_roles)
&& (array_key_exists($ilias_role, $this->global_roles))
) {
if (!array_key_exists($studip_role, $this->ilias_configs[$index]['additional_roles'])) {
$this->ilias_configs[$index]['additional_roles'][$studip_role] = [];
}
if (array_key_exists($ilias_role, $this->global_roles)) {
$this->ilias_configs[$index]['additional_roles'][$studip_role][$ilias_role] = [
'id' => $this->global_roles[$ilias_role]['id'],
'name' => $this->global_roles[$ilias_role]['name']];
PageLayout::postSuccess(sprintf(_('ILIAS-Rolle %s wird Stud.IP-Rechtestufe %s zugewiesen.'), $this->global_roles[$ilias_role]['name'], $studip_role));
} else {
PageLayout::postError(_('ILIAS-Rolle nicht gefunden.'));
}
}
}
//store config entry
Config::get()->store('ILIAS_INTERFACE_SETTINGS', $this->ilias_configs);
PageLayout::postSuccess(_('ILIAS-Berechtigungseinstellungen wurden gespeichert.'));
......@@ -438,28 +505,31 @@ class Admin_IliasInterfaceController extends AuthenticatedController
*/
public function soap_methods_action($index)
{
if ($this->ilias_configs[$index]['is_active']) {
$ilias = new ConnectedIlias($index);
$this->soap_methods = $ilias->getSoapMethods();
ksort($this->soap_methods);
$this->ilias_index = $index;
if (Request::get('ilias_soap_method')) {
$this->ilias_soap_method = Request::get('ilias_soap_method');
foreach ($this->soap_methods[Request::get('ilias_soap_method')] as $param) {
switch ($param) {
case "sid" : $this->params[$param] = $ilias->soap_client->getSID();
break;
case "user_id" : $this->params[$param] = $ilias->user->getId();
break;
}
$ilias = new ConnectedIlias($index);
$this->soap_methods = $ilias->getSoapMethods();
ksort($this->soap_methods);
$this->ilias_index = $index;
if (Request::get('ilias_soap_method')) {
$this->ilias_soap_method = Request::get('ilias_soap_method');
foreach ($this->soap_methods[Request::get('ilias_soap_method')] as $param) {
switch ($param) {
case "sid" : $this->params[$param] = $ilias->soap_client->getSID();
break;
case "user_id" : $this->params[$param] = is_object($ilias->user) ? $ilias->user->getId() : '';
break;
}
} elseif (Request::get('ilias_call')) {
$params = [];
foreach ($this->soap_methods[Request::get('ilias_call')] as $param) {
}
} elseif (Request::get('ilias_call')) {
$params = [];
foreach ($this->soap_methods[Request::get('ilias_call')] as $param) {
if ($param === 'user_ids') {
$params[$param] = [Request::get('ilias_soap_param_'.$param)];
} else {
$params[$param] = Request::get('ilias_soap_param_'.$param);
}
$this->result = $ilias->soap_client->call(Request::get('ilias_call'), $params);
}
$this->result = $ilias->soap_client->call(Request::get('ilias_call'), $params);
}
}
}
......@@ -23,16 +23,21 @@ class Admin_LtiController extends AuthenticatedController
$GLOBALS['perm']->check('root');
Navigation::activateItem('/admin/config/lti');
PageLayout::setTitle(_('Konfiguration der LTI-Tools'));
PageLayout::setTitle(_('LTI-Tools'));
$widget = Sidebar::get()->addWidget(new ActionsWidget());
$widget->addLink(
_('Neues LTI-Tool registrieren'),
$this->url_for('admin/lti/edit'),
$this->url_for('lti/tool/add/global'),
Icon::create('add')
)->asDialog();
$widget->addLink(
_('Daten zur LTI-Plattform anzeigen'),
$this->url_for('lti/auth/platform_data'),
Icon::create('info')
)->asDialog();
Helpbar::get()->addPlainText('', _('Hier können Sie Verknüpfungen mit externen Tools konfigurieren, sofern diese den LTI-Standard (Version 1.x) unterstützen.'));
Helpbar::get()->addPlainText('', _('Hier können Sie LTI-Tools konfigurieren. Diese müssen den LTI-Standard in Version 1.0/1.1 oder 1.3A unterstützen.'));
}
/**
......@@ -42,66 +47,4 @@ class Admin_LtiController extends AuthenticatedController
{
$this->tools = LtiTool::findAll();
}
/**
* Display dialog for editing an LTI tool.
*
* @param int $id tool id
*/
public function edit_action($id = null)
{
$this->tool = new LtiTool($id);
}
/**
* Save changes for an LTI tool.
*
* @param int $id tool id
*/
public function save_action($id)
{
CSRFProtection::verifyUnsafeRequest();
$tool = new LtiTool($id ?: null);
$tool->name = trim(Request::get('name'));
$tool->launch_url = trim(Request::get('launch_url'));
$tool->consumer_key = trim(Request::get('consumer_key'));
$tool->consumer_secret = trim(Request::get('consumer_secret'));
$tool->custom_parameters = trim(Request::get('custom_parameters'));
$tool->allow_custom_url = Request::int('allow_custom_url', 0);
$tool->deep_linking = Request::int('deep_linking', 0);
$tool->send_lis_person = Request::int('send_lis_person', 0);
$tool->oauth_signature_method = Request::get('oauth_signature_method', 'sha1');
if ($tool->store()) {
PageLayout::postSuccess(sprintf(
_('Einstellungen für "%s" wurden gespeichert.'),
htmlReady($tool->name)
));
}
$this->redirect('admin/lti');
}
/**
* Delete an LTI tool.
*
* @param int $id tool id
*/
public function delete_action($id)
{
CSRFProtection::verifyUnsafeRequest();
$tool = LtiTool::find($id);
$tool_name = $tool->name;
if ($tool && $tool->delete()) {
PageLayout::postSuccess(sprintf(
_('Das LTI-Tool "%s" wurde gelöscht.'),
htmlReady($tool_name)
));
}
$this->redirect('admin/lti');
}
}
This diff is collapsed.
......@@ -16,7 +16,7 @@
class Admin_PluginController extends AuthenticatedController
{
private $plugin_admin;
private PluginAdministration $plugin_admin;
/**
* Common tasks for all actions.
......@@ -509,7 +509,8 @@ class Admin_PluginController extends AuthenticatedController
public function unregistered_action()
{
$this->unknown_plugins = $this->plugin_admin->scanPluginDirectory();
$plugins = $this->plugin_admin->scanPluginDirectory(true);
$this->unknown_plugins = $plugins;
}
/**
......@@ -521,7 +522,7 @@ class Admin_PluginController extends AuthenticatedController
public function register_action($number)
{
CSRFProtection::verifyUnsafeRequest();
$unknown_plugins = $this->plugin_admin->scanPluginDirectory();
$unknown_plugins = $this->plugin_admin->scanPluginDirectory(true);
$plugin = $unknown_plugins[$number];
try {
......