aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Thienel <thienel@data-quest.de>2025-06-26 16:44:58 +0000
committerDavid Siegfried <david.siegfried@uni-vechta.de>2025-06-26 16:44:58 +0000
commit6f7299342e86431a2ebd3a6197a985d1653b1dd2 (patch)
treecc52bc96e0cad1ca0c0a33c4dcb048746db4ff83
parent176cf83d651b28f1d19895af375cef66292624ef (diff)
Resolve "Erweiterung der Modulverwaltung um Studiengangsspezifische Informationen"
Closes #5383 Merge request studip/studip!4051
-rw-r--r--app/controllers/admin/datafields.php87
-rw-r--r--app/controllers/search/studiengaenge.php2
-rw-r--r--app/controllers/shared/modul.php121
-rw-r--r--app/controllers/studiengaenge/shared_version.php104
-rw-r--r--app/views/admin/datafields/edit.php10
-rw-r--r--app/views/admin/datafields/index.php7
-rw-r--r--app/views/admin/datafields/new.php61
-rw-r--r--app/views/search/module/_modul.php2
-rw-r--r--app/views/search/module/index.php5
-rw-r--r--app/views/search/studiengaenge/verlauf.php18
-rw-r--r--app/views/shared/modul/_modul.php84
-rw-r--r--app/views/shared/modul/_modul_ohne_lv.php41
-rw-r--r--app/views/shared/modul/_modullv.php151
-rw-r--r--app/views/shared/modul/_modullvs.php100
-rw-r--r--app/views/shared/modul/_pruefungen.php43
-rw-r--r--app/views/shared/modul/_regularien.php36
-rw-r--r--app/views/shared/modul/description.php8
-rw-r--r--app/views/shared/modul/overview.php130
-rw-r--r--app/views/studiengaenge/studiengaenge/stgteil_bezeichnungen.php4
-rw-r--r--app/views/studiengaenge/studiengaenge/studiengaenge.php5
-rw-r--r--app/views/studiengaenge/studiengaenge/studiengangteile.php5
-rw-r--r--app/views/studiengaenge/versionen/abschnitte.php4
-rw-r--r--app/views/studiengaenge/versionen/details_abschnitt.php22
-rw-r--r--app/views/studiengaenge/versionen/modul_zuordnung.php17
-rw-r--r--app/views/studiengaenge/versionen/modulteil_semester.php40
-rw-r--r--app/views/studiengaenge/versionen/versionen.php2
-rw-r--r--db/migrations/6.0.51_step5383_new_data_field_types_for_mvv.php29
-rw-r--r--lib/classes/I18NStringDatafield.php2
-rw-r--r--lib/classes/MvvReplaceDataFieldsTrait.php90
-rw-r--r--lib/models/DataField.php22
-rw-r--r--lib/models/DatafieldEntryModel.php30
-rw-r--r--lib/models/Modul.php36
-rw-r--r--lib/models/ModulDeskriptor.php5
-rw-r--r--lib/models/Modulteil.php17
-rw-r--r--lib/models/ModulteilDeskriptor.php5
-rw-r--r--lib/models/ModulteilStgteilabschnitt.php14
-rw-r--r--lib/models/StgteilVersion.php25
-rw-r--r--lib/models/StgteilabschnittModul.php27
-rw-r--r--resources/assets/javascripts/mvv.js6
39 files changed, 1024 insertions, 393 deletions
diff --git a/app/controllers/admin/datafields.php b/app/controllers/admin/datafields.php
index 6188a02..2ec8762 100644
--- a/app/controllers/admin/datafields.php
+++ b/app/controllers/admin/datafields.php
@@ -59,15 +59,17 @@ class Admin_DatafieldsController extends AuthenticatedController
];
} else {
$this->datafields_list = [
- 'sem' => DataField::getDataFields('sem'),
- 'inst' => DataField::getDataFields('inst'),
- 'user' => DataField::getDataFields('user'),
- 'userinstrole' => DataField::getDataFields('userinstrole'),
- 'usersemdata' => DataField::getDataFields('usersemdata'),
- 'roleinstdata' => DataField::getDataFields('roleinstdata'),
- 'moduldeskriptor' => DataField::getDataFields('moduldeskriptor'),
- 'modulteildeskriptor' => DataField::getDataFields('modulteildeskriptor'),
- 'studycourse' => DataField::getDataFields('studycourse'),
+ 'sem' => DataField::getDataFields('sem'),
+ 'inst' => DataField::getDataFields('inst'),
+ 'user' => DataField::getDataFields('user'),
+ 'userinstrole' => DataField::getDataFields('userinstrole'),
+ 'usersemdata' => DataField::getDataFields('usersemdata'),
+ 'roleinstdata' => DataField::getDataFields('roleinstdata'),
+ 'moduldeskriptor' => DataField::getDataFields('moduldeskriptor'),
+ 'modulteildeskriptor' => DataField::getDataFields('modulteildeskriptor'),
+ 'studycourse' => DataField::getDataFields('studycourse'),
+ 'stgteilabschnittmodul' => DataField::getDataFields('stgteilabschnittmodul'),
+ 'modulteilstgteilabschnitt' => DataField::getDataFields('modulteilstgteilabschnitt'),
];
}
@@ -102,7 +104,10 @@ class Admin_DatafieldsController extends AuthenticatedController
$object_class = implode(',', Request::getArray('object_class'));
$datafield->object_class = (trim($object_class) && $object_class != 'NULL') ? $object_class : null;
} elseif ($datafield->object_type === 'studycourse') {
- $datafield->object_class = trim(Request::option('object_class', 'all_settings'));
+ $datafield->object_class = trim(Request::option('object_class', 'all_settings'));
+ } elseif ($datafield->object_type === 'stgteilabschnittmodul'
+ || $datafield->object_type === 'modulteilstgteilabschnitt') {
+ $datafield->object_class = Request::option('object_class');
} else {
$datafield->object_class = array_sum(Request::intArray('object_class')) ?: null;
}
@@ -153,7 +158,12 @@ class Admin_DatafieldsController extends AuthenticatedController
if ($type === 'moduldeskriptor' || $type === 'modulteildeskriptor') {
$object_class = implode(',', Request::getArray('object_class'));
$datafield->object_class = (trim($object_class) && $object_class != 'NULL') ? $object_class : null;
- } elseif ($type === 'studycourse') {
+ } elseif (in_array($type,
+ [
+ 'studycourse',
+ 'stgteilabschnittmodul',
+ 'modulteilstgteilabschnitt',
+ ])) {
$datafield->object_class = Request::option('object_class');
} else {
$object_class = Request::getArray('object_class');
@@ -196,7 +206,6 @@ class Admin_DatafieldsController extends AuthenticatedController
$this->render_action('type_select');
return;
}
-
if (Request::isXhr() && $this->type_name) {
PageLayout::setTitle(sprintf(_('Einen neuen Datentyp für die Kategorie "%s" erstellen'), $this->type_name));
}
@@ -283,4 +292,58 @@ class Admin_DatafieldsController extends AuthenticatedController
$filter->setOptions($this->allclasses, $this->class_filter);
$sidebar->addWidget($filter);
}
+
+ /**
+ * Returns an array of replaceable fields, depending on object type.
+ * Array keys are the field names of the related table.
+ * Array values are a short name and description of the field.
+ *
+ * @param string $type The type of the object.
+ * @return array An array of replace
+ */
+ public static function getReplaceFields(string $type): array
+ {
+ if ($type === 'stgteilabschnittmodul') {
+ return [
+ 'dauer' => _('Dauer'),
+ 'kapazitaet' => _('Kapazität'),
+ 'kp' => _('Kreditpunkte'),
+ 'pruef_ebene' => _('Prüfungsebene'),
+ 'faktor_note' => _('Faktor Note'),
+ 'verantwortlich' => _('Verantwortlich (Freitext)'),
+ 'voraussetzung' => _('Teilnahmevoraussetzung'),
+ 'kompetenzziele' => _('Kompetenzziele'),
+ 'inhalte' => _('Inhalte'),
+ 'literatur' => _('Literatur'),
+ 'links' => _('Links'),
+ 'kommentar' => _('Kommentar'),
+ 'kommentar_kapazitaet' => _('Kommentar Kapazität'),
+ 'kommentar_sws' => _('Kommentar Semesterwochenstunden'),
+ 'kommentar_wl_selbst' => _('Kommentar Workload (selbstgestaltete Arbeitszeit)'),
+ 'kommentar_wl_pruef' => _('Kommentar Workload (Prüfung)'),
+ 'kommentar_note' => _('Kommentar Note'),
+ 'pruef_vorleistung' => _('Prüfungsvorleistung'),
+ 'pruef_leistung' => _('Leistung/Prüfungsform'),
+ 'pruef_wiederholung' => _('Wiederholungsprüfung'),
+ 'ersatztext' => _('Ersatztext'),
+ ];
+ } elseif ($type === 'modulteilstgteilabschnitt') {
+ return [
+ 'kp' => _('Kreditpunkte'),
+ 'bezeichnung' => _('Zusätliche Bezeichnung'),
+ 'voraussetzungen' => _('Teilnahmevoraussetzungen'),
+ 'kommentar' => _('Kommentar Modulteil'),
+ 'kommentar_kapazitaet' => _('Kommentar Kapazität'),
+ 'kommentar_wl_praesenz' => _('Kommentar Workload (Präsenzzeit)'),
+ 'kommentar_wl_bereitung' => _('Kommentar Workload (Vor-/Nachbereitung)'),
+ 'kommentar_wl_selbst' => _('Kommentar Workload (Modulteil selbstgestaltete Arbeitszeit)'),
+ 'kommentar_wl_pruef' => _('Kommentar Workload (Modulteil Prüfung)'),
+ 'pruef_vorleistung' => _('Prüfungsvorleistung'),
+ 'pruef_leistung' => _('Prüfungsleistung Modulteil'),
+ 'kommentar_pflicht' => _('Kommentar Anwesenheitspflicht'),
+ ];
+ } else {
+ return [];
+ }
+ }
}
diff --git a/app/controllers/search/studiengaenge.php b/app/controllers/search/studiengaenge.php
index 7035a63..210f243 100644
--- a/app/controllers/search/studiengaenge.php
+++ b/app/controllers/search/studiengaenge.php
@@ -335,8 +335,6 @@ class Search_StudiengaengeController extends MVVController
ksort($fach_sem_data);
$this->fach_sem_data = $fach_sem_data;
- // Ausgabe des Namens ohne Fach (dieses ist im Zusatz bereits enthalten)
- $this->studiengangTeilName = $this->stg_teil->getDisplayName();
// add option widget to show only modules with courses in the
// selected semester
diff --git a/app/controllers/shared/modul.php b/app/controllers/shared/modul.php
index 2cb9a85..ffcfdb7 100644
--- a/app/controllers/shared/modul.php
+++ b/app/controllers/shared/modul.php
@@ -29,70 +29,40 @@ class Shared_ModulController extends AuthenticatedController
ModuleManagementModel::setContentLanguage($display_language);
$this->modul = Modul::find($modul_id);
+ if (!$this->modul) {
+ PageLayout::postError(_('Unbekanntes Modul'));
+ return;
+ }
if (!$this->modul->hasPublicStatus()) {
throw new AccessDeniedException();
}
- if ($this->modul) {
- $this->details_id = $this->modul->getId();
-
- $type = 1;
- if (count($this->modul->modulteile) == 1) {
- $modulteil = $this->modul->modulteile->first();
- $type = 3;
- if (count($modulteil->lvgruppen) > 0) {
- $type = 2;
- }
- } else if (count($this->modul->modulteile) == 0) {
- $type = 3;
- }
-
- if (!$semester_id) {
- $current_semester = Semester::findDefault();
- } else {
- $current_semester = Semester::find($semester_id);
+ $this->type = 1;
+ if (count($this->modul->modulteile) < 2) {
+ $this->type = 3;
+ $modulteil = $this->modul->modulteile->first();
+ if ($modulteil && count($modulteil->lvgruppen) > 0) {
+ $this->type = 2;
}
+ }
- $sws = 0;
- $institut = new Institute($this->modul->responsible_institute->institut_id);
- $modulteile_data = [];
- foreach ($this->modul->modulteile as $modulteil) {
- $modulteil_deskriptor = $modulteil->getDeskriptor();
- $sws += (int) $modulteil->sws;
- $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulteil->num_bezeichnung]['name'] ?? '';
- $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulteil->nummer);
- $modulteile_data[$modulteil->getId()] = [
- 'name' => $modulteil->getDisplayName(),
- 'name_kurz' => $name_kurz,
- 'voraussetzung' => $modulteil_deskriptor->voraussetzung,
- 'pruef_leistung' => $modulteil_deskriptor->pruef_leistung,
- 'pruef_vorleistung' => $modulteil_deskriptor->pruef_vorleistung,
- 'kommentar' => $modulteil_deskriptor->kommentar,
- 'kapazitaet' => $modulteil->kapazitaet,
- 'lvGruppen' => []
- ];
-
- $lvGruppen = Lvgruppe::findByModulteil($modulteil->getId());
- foreach ($lvGruppen as $lvGruppe) {
- $ids = array_column($lvGruppe->getAssignedCoursesBySemester($current_semester['semester_id'], $GLOBALS['user']->id), 'seminar_id');
- $courses = Course::findMany($ids, 'order by Veranstaltungsnummer, Name');
- $modulteile_data[$modulteil->getId()]['lvGruppen'][$lvGruppe->getId()] = [
- 'courses' => $courses,
- 'alt_texte' => $lvGruppe->alttext
- ];
- }
- }
- $this->modulteile = $modulteile_data;
- $this->deskriptor = $this->modul->getDeskriptor();
- $this->institut = $institut;
- $this->semester = $current_semester;
- $this->sws = $sws;
+ if (!$semester_id) {
+ $this->semester = Semester::findDefault();
+ } else {
+ $this->semester = Semester::find($semester_id);
+ }
- $this->pruef_ebene = $GLOBALS['MVV_MODUL']['PRUEF_EBENE']['values'][$this->modul->pruef_ebene]['name'] ?? null;
- $this->type = $type;
- $this->self_url = $this->url_for('modul/show/' . $modul_id);
- $this->detail_url = $this->url_for('modul/detail/' . $modul_id);
- PageLayout::setTitle($this->modul->getDisplayName() . ' (' . _('Veranstaltungsübersicht') .')');
+ $abschnitt_id = Request::option('abschnitt_id');
+ $this->code = '';
+ $this->title = '';
+ $abschnitt_modul = $this->modul->abschnitte_modul->findOneBy('abschnitt_id', $abschnitt_id);
+ if ($abschnitt_modul) {
+ $this->modul->setReplaceDfAbschnitt($abschnitt_modul->abschnitt);
+ $this->code = trim($abschnitt_modul->modulcode);
+ $this->title = trim($abschnitt_modul->bezeichnung);
}
+
+ $this->pruef_ebene = $GLOBALS['MVV_MODUL']['PRUEF_EBENE']['values'][$this->modul->pruef_ebene]['name'] ?? null;
+ PageLayout::setTitle($this->modul->getDisplayName() . ' (' . _('Veranstaltungsübersicht') .')');
}
public function description_action($id)
@@ -103,20 +73,12 @@ class Shared_ModulController extends AuthenticatedController
throw new AccessDeniedException();
}
$this->type = 1;
- if (count($this->modul->modulteile) == 1) {
- $modulteil = $this->modul->modulteile->first();
+ if (count($this->modul->modulteile) < 2) {
$this->type = 3;
- if (count($modulteil->lvgruppen) > 0) {
+ $modulteil = $this->modul->modulteile->first();
+ if ($modulteil && count($modulteil->lvgruppen) > 0) {
$this->type = 2;
}
- } else if (count($this->modul->modulteile) == 0) {
- $this->type = 3;
- }
-
- if (!Request::get('sem_select')) {
- $currentSemester = Semester::findCurrent();
- } else {
- $currentSemester = Semester::find(Request::get('sem_select'));
}
$this->display_language = Request::get('display_language', $this->modul->original_language);
@@ -124,21 +86,24 @@ class Shared_ModulController extends AuthenticatedController
I18NString::setDefaultLanguage($this->modul->original_language);
I18NString::setContentLanguage($this->display_language);
- $this->semesterSelector = Semester::getSemesterSelector(null, $currentSemester['semester_id'], 'semester_id', false);
- $this->pruefungsEbene = isset($GLOBALS['MVV_MODUL']['PRUEF_EBENE']['values'][$this->modul->pruef_ebene])
- ? $GLOBALS['MVV_MODUL']['PRUEF_EBENE']['values'][$this->modul->pruef_ebene]['name']
- : null;
- $this->modulDeskriptor = $this->modul->getDeskriptor();
- $this->startSemester = Semester::findByTimestamp($this->modul->start);
+ $this->start_semester = Semester::findByTimestamp($this->modul->start);
if (!$this->modul->responsible_institute) {
- $this->instituteName = null;
+ $this->institute_name = null;
} elseif ($this->modul->responsible_institute->institute) {
- $this->instituteName = $this->modul->responsible_institute->institute->name;
+ $this->institute_name = $this->modul->responsible_institute->institute->name;
} else {
- $this->instituteName = _('Unbekannte Einrichtung');
+ $this->institute_name = _('Unbekannte Einrichtung');
+ }
+ $abschnitt_id = Request::option('abschnitt_id');
+ $this->code = '';
+ $this->title = '';
+ $this->abschnitt_modul = $this->modul->abschnitte_modul->findOneBy('abschnitt_id', $abschnitt_id);
+ if ($this->abschnitt_modul) {
+ $this->modul->setReplaceDfAbschnitt($this->abschnitt_modul->abschnitt);
+ $this->code = trim($this->abschnitt_modul->modulcode);
+ $this->title = trim($this->abschnitt_modul->bezeichnung);
}
- $this->semester = $currentSemester;
PageLayout::setTitle($this->modul->getDisplayName() . ' (' . _('Vollständige Modulbeschreibung') .')');
}
diff --git a/app/controllers/studiengaenge/shared_version.php b/app/controllers/studiengaenge/shared_version.php
index 1607ce7..73715a7 100644
--- a/app/controllers/studiengaenge/shared_version.php
+++ b/app/controllers/studiengaenge/shared_version.php
@@ -449,43 +449,70 @@ abstract class SharedVersionController extends MVVController
public function modul_zuordnung_action($abschnitt_modul_id)
{
$this->zuordnung = StgteilabschnittModul::find($abschnitt_modul_id);
- if ($this->zuordnung->isNew()) {
+ if (!$this->zuordnung) {
PageLayout::postError(_('Unbekannte Zuordnung'));
$this->redirect($this->action_url('index'));
return;
} else {
PageLayout::setTitle(_('Modulzuordnung bearbeiten'));
- $success_message = _('Die Modulzuordnung "%s" wurde geändert.');
}
- $success = false;
+ $this->render_template('studiengaenge/versionen/modul_zuordnung', $this->layout);
+ }
+
+ public function modul_zuordnung_store_action($abschnitt_modul_id)
+ {
+ $this->zuordnung = StgteilabschnittModul::find($abschnitt_modul_id);
+ if (!$this->zuordnung) {
+ PageLayout::postError(_('Unbekannte Zuordnung'));
+ $this->redirect($this->action_url('index'));
+ return;
+ }
if (Request::submitted('store')) {
CSRFProtection::verifyUnsafeRequest();
$this->zuordnung->bezeichnung = Request::i18n('bezeichnung')->trim();
$this->zuordnung->flexnow_modul = trim(Request::get('flexnow_modul'));
$this->zuordnung->modulcode = trim(Request::get('modulcode'));
+ // update data fields
+ $data_field_values = Request::getArray('datafields');
+ $invalid_data_fields = [];
+ $data_fields_updated = false;
+ foreach ($this->zuordnung->datafields as $data_field) {
+ $tdf = $data_field->getTypedDatafield();
+ $tdf->setValueFromSubmit($data_field_values[$data_field->datafield_id]);
+ if ($tdf->isValid() && $tdf->store()) {
+ $data_fields_updated = true;
+ } else {
+ $invalid_data_fields[] = $tdf->getName();
+ }
+ }
$stored = $this->zuordnung->store();
if ($stored !== false) {
- $success = true;
- if (!Request::isXhr()) {
- if ($stored) {
- PageLayout::postSuccess(sprintf(
- $success_message,
- htmlReady($this->zuordnung->getDisplayName())
- ));
- } else {
- PageLayout::postInfo(_('Es wurden keine Änderungen vorgenommen.'));
- }
- $this->redirect($this->action_url('details_abschnitt/' . $this->zuordnung->abschnitt_id));
+ if ($stored || $data_fields_updated) {
+ PageLayout::postSuccess(sprintf(
+ _('Die Modulzuordnung "%s" wurde geändert.'),
+ htmlReady($this->zuordnung->getDisplayName())
+ ));
+ } else {
+ PageLayout::postInfo(_('Es wurden keine Änderungen vorgenommen.'));
}
- }
- }
- if (Request::isXhr()) {
- if ($success) {
- $this->details_abschnitt_action($this->zuordnung->abschnitt_id);
+ $this->relocate($this->action_url('details_abschnitt/' . $this->zuordnung->abschnitt_id));
+ return;
} else {
- $this->render_template('studiengaenge/versionen/modul_zuordnung');
+ PageLayout::postError(_('Die Änderungen an der Modulzuordnung konnten nicht gespeichert werden.'));
+ }
+ if (count($invalid_data_fields)) {
+ $message = ngettext(
+ 'Das folgende Datenfeld wurde falsch angegeben:',
+ 'Die folgenden Datenfelder wurden falsch angegeben:',
+ count($invalid_data_fields)
+ );
+ PageLayout::postError(
+ $message,
+ array_map('htmlReady', $invalid_data_fields)
+ );
}
}
+ $this->redirect($this->action_url('modul_zuordnung/' . $this->zuordnung->id));
}
public function delete_modul_action($abschnitt_id, $modul_id)
@@ -548,11 +575,34 @@ abstract class SharedVersionController extends MVVController
if ($this->modulteil) {
$this->abschnitt_modul = StgteilabschnittModul::find($abschnitt_modul_id);
if ($this->abschnitt_modul) {
+ // Store an additional ModulteilStgteilAbschnitt-Object for the relations to the data fields.
+ // Use 0 as value for the field fachsemester.
+ $this->assignment = new ModulteilStgteilabschnitt(
+ [
+ $this->modulteil->id,
+ $this->abschnitt_modul->abschnitt_id,
+ 0
+ ]
+ );
if (Request::submitted('store')) {
CSRFProtection::verifyUnsafeRequest();
$fachsem = $this->abschnitt_modul->getAllFachsemester($this->modulteil->id);
$status = Request::optionArray('status');
$is_modified = false;
+ $this->assignment->store();
+ // update datafields
+ $data_field_values = Request::getArray('datafields');
+ $invalid_data_fields = [];
+ $data_fields_updated = false;
+ foreach ($this->assignment->datafields as $data_field) {
+ $tdf = $data_field->getTypedDatafield();
+ $tdf->setValueFromSubmit($data_field_values[$data_field->datafield_id]);
+ if ($tdf->isValid() && $tdf->store()) {
+ $data_fields_updated = true;
+ } else {
+ $invalid_data_fields[] = $tdf->getName();
+ }
+ }
foreach (array_keys(Request::intArray('fachsemester')) as $i) {
if (isset($fachsem[$i])) {
$fachsem[$i]->differenzierung = $status[$i];
@@ -574,7 +624,7 @@ abstract class SharedVersionController extends MVVController
$is_modified = true;
}
}
- if ($is_modified) {
+ if ($is_modified || $data_fields_updated) {
PageLayout::postSuccess(sprintf(
_('Die Zuordnung der Fachsemester zum Modulteil "%s" des Moduls "%s" im Abschnitt "%s" wurde geändert.'),
htmlReady($this->modulteil->getDisplayName()),
@@ -586,9 +636,21 @@ abstract class SharedVersionController extends MVVController
_('Es wurden keine Änderungen an der Zuordnung der Fachsemester vorgenommen.')
);
}
+ if (count($invalid_data_fields)) {
+ $message = ngettext(
+ 'Das folgende Datenfeld wurde falsch angegeben:',
+ 'Die folgenden Datenfelder wurden falsch angegeben:',
+ count($invalid_data_fields)
+ );
+ PageLayout::postError(
+ $message,
+ array_map('htmlReady', $invalid_data_fields)
+ );
+ }
$this->relocate($this->action_url('details_abschnitt/' . $this->abschnitt_modul->abschnitt_id . '/' . $this->abschnitt_modul->modul_id));
return;
}
+ PageLayout::setTitle(_('Angaben zum verknüpften Modulteil'));
$this->render_template('studiengaenge/versionen/modulteil_semester', $this->layout);
} else {
$this->render_nothing();
diff --git a/app/views/admin/datafields/edit.php b/app/views/admin/datafields/edit.php
index c3f67b4..7958620 100644
--- a/app/views/admin/datafields/edit.php
+++ b/app/views/admin/datafields/edit.php
@@ -6,6 +6,7 @@
* @var string $datafield_id
* @var DataFieldEntry $datafield_entry
* @var array $institutes
+ * @var array $replace_fields
*/
use Studip\Button, Studip\LinkButton;
@@ -99,6 +100,15 @@ use Studip\Button, Studip\LinkButton;
<option value="mehrfach_settings"<?= mb_strpos($item->object_class, 'mehrfach_settings') !== false ? ' selected' : '' ?>><?= _('Mehrfach-Studiengänge (Abschnitt "Einstellungen")') ?></option>
<option value="mehrfach_info"<?= mb_strpos($item->object_class, 'mehrfach_info') !== false ? ' selected' : '' ?>><?= _('Mehrfach-Studiengänge (Abschnitt "Inhalte und Informationen")') ?></option>
</select>
+ <? elseif ($item->object_type === 'stgteilabschnittmodul' || $item->object_type === 'modulteilstgteilabschnitt'): ?>
+ <?= _('Überschreibt') ?>
+
+ <select name="object_class">
+ <option value=""><?= _('Zusätzliches Datenfeld (keine Ersetzung)') ?></option>
+ <? foreach (Admin_DatafieldsController::getReplaceFields($item->object_type) as $key => $name): ?>
+ <option value="<?= $key ?>"<?= $key === $item->object_class ? ' selected' : '' ?>><? printf('%s (%s)', $key, htmlReady($name)) ?></option>
+ <? endforeach; ?>
+ </select>
<? else : ?>
<?= _('Nutzerstatus') ?>:
diff --git a/app/views/admin/datafields/index.php b/app/views/admin/datafields/index.php
index 64d6d6f..5d959d7 100644
--- a/app/views/admin/datafields/index.php
+++ b/app/views/admin/datafields/index.php
@@ -31,7 +31,7 @@
<th><?= _('Feldtyp') ?></th>
<th style="white-space: nowrap">
<?= _('Typ') ?>
- <?= tooltipIcon(_('Veranstaltungskategorie, Einrichtungstyp, Sprache bzw. Nutzerstatus')) ?>
+ <?= tooltipIcon(_('Veranstaltungskategorie, Einrichtungstyp, Sprache, ersetztes Feld bzw. Nutzerstatus')) ?>
</th>
<th>
<?= _('Institution') ?>
@@ -58,7 +58,7 @@
<? else: ?>
<th class="toggle-indicator" colspan="11">
<? endif; ?>
- <? if (empty($datafields_list[$key])): ?>
+ <? if (empty($data)): ?>
<?= sprintf(_('Datenfelder für %s'), $allclasses[$key]) ?>
<? else: ?>
<a name="<?= $key ?>" class="toggler" href="<?= $controller->url_for('admin/datafields/index/' . $key) ?>">
@@ -114,6 +114,9 @@
'mehrfach_info' => _('Mehrfach-Studiengänge (Abschnitt "Inhalte und Informationen")')
];?>
<?= $object_classes[$val->object_class] ?>
+ <? elseif ($key === 'stgteilabschnittmodul' || $key === 'modulteilstgteilabschnitt'): ?>
+ <? $replace_fields = Admin_DatafieldsController::getReplaceFields($key); ?>
+ <? printf('%s (%s)', $val->object_class, $replace_fields[$val->object_class]) ?>
<? else: ?>
<?= $val->object_class !== null ? DataField::getReadableUserClass($val->object_class) : _('alle')?>
<? endif; ?>
diff --git a/app/views/admin/datafields/new.php b/app/views/admin/datafields/new.php
index c749ff9..2826589 100644
--- a/app/views/admin/datafields/new.php
+++ b/app/views/admin/datafields/new.php
@@ -7,6 +7,7 @@
* @var array $institutes
* @var Institute $item
* @var DataField $datafield
+ * @var array $replace_fields
*/
use Studip\Button, Studip\LinkButton;
@@ -45,8 +46,22 @@ use Studip\Button, Studip\LinkButton;
<?= _('Veranstaltungskategorie') ?>
<? elseif ($object_typ === 'inst'): ?>
<?= _('Einrichtungstyp') ?>
- <? elseif ($object_typ === 'moduldeskriptor' || $object_typ === 'modulteildeskriptor') : ?>
+ <? elseif (in_array(
+ $object_typ,
+ [
+ 'moduldeskriptor',
+ 'modulteildeskriptor',
+ ]
+ )) : ?>
<?= _('Sprache') ?>
+ <? elseif (in_array(
+ $object_typ,
+ [
+ 'stgteilabschnittmodul',
+ 'modulteilstgteilabschnitt',
+ ]
+ )): ?>
+ <?= _('Ersetzt Feld') ?>
<? elseif ($object_typ === 'studycourse'): ?>
<?= _('Typ/Abschnitt') ?>
<? else: ?>
@@ -69,17 +84,29 @@ use Studip\Button, Studip\LinkButton;
<?= htmlReady($val['name']) ?>
</option>
<? endforeach; ?>
- <? elseif ($object_typ === 'moduldeskriptor') : ?>
+ <? elseif (in_array(
+ $object_typ,
+ [
+ 'moduldeskriptor',
+ 'modulteildeskriptor',
+ ])
+ ): ?>
<select multiple name="object_class[]" required>
<option value="NULL" selected><?= _('alle (mehrsprachige Eingabe bei Feldtyp textline, textarea, textmarkup)') ?></option>
<? foreach ($GLOBALS['CONTENT_LANGUAGES'] as $key => $value) : ?>
<option value="<?= htmlReady($key) ?>"><?= htmlReady($value['name']) ?></option>
<? endforeach; ?>
- <? elseif ($object_typ === 'modulteildeskriptor') : ?>
- <select multiple name="object_class[]" required>
- <option value="NULL" selected><?= _('alle (mehrsprachige Eingabe bei Feldtyp textline, textarea, textmarkup)') ?></option>
- <? foreach ($GLOBALS['CONTENT_LANGUAGES'] as $key => $value) : ?>
- <option value="<?= htmlReady($key) ?>"><?= htmlReady($value['name']) ?></option>
+ <? elseif (in_array(
+ $object_typ,
+ [
+ 'stgteilabschnittmodul',
+ 'modulteilstgteilabschnitt',
+ ])
+ ): ?>
+ <select name="object_class" required>
+ <option value="NULL" selected><?= _('Zusätzliches Datenfeld (keine Ersetzung)') ?></option>
+ <? foreach (Admin_DatafieldsController::getReplaceFields($object_typ) as $key => $value) : ?>
+ <option value="<?= htmlReady($key) ?>"><? printf('%s (%s)', $key, htmlReady($value)) ?></option>
<? endforeach; ?>
<? elseif ($object_typ === 'studycourse') : ?>
<select name="object_class" required>
@@ -119,6 +146,13 @@ use Studip\Button, Studip\LinkButton;
</select>
</label>
+ <? if (!in_array(
+ $object_typ,
+ [
+ 'stgteilabschnittmodul',
+ 'modulteilstgteilabschnitt',
+ ])
+ ): ?>
<label>
<?= _('Einrichtung') ?>
<select name="institut_id" class="nested-select">
@@ -132,6 +166,7 @@ use Studip\Button, Studip\LinkButton;
<? endforeach; ?>
</select>
</label>
+ <? endif; ?>
<? if ($object_typ === 'user') :?>
<label>
@@ -164,8 +199,20 @@ use Studip\Button, Studip\LinkButton;
<textarea name="description"></textarea>
</label>
+ <? endif; ?>
+ <? if ($object_typ === 'stgteilabschnittmodul' || $object_typ === 'modulteilstgteilabschnitt'): ?>
+ <label>
+ <?= _('Überschreibt') ?>
+ <select name="replace_field">
+ <option value=""><?= _('Zusätzliches Datenfeld (keine Ersetzung)') ?></option>
+ <? foreach ($replace_fields as $key => $name): ?>
+ <option value="<?= $key ?>"><?= htmlReady($name) ?></option>
+ <? endforeach; ?>
+ </select>
+ </label>
<? endif; ?>
+
<? if ($object_typ === 'user'): ?>
<label>
<input type="checkbox" name="is_userfilter" value="1">
diff --git a/app/views/search/module/_modul.php b/app/views/search/module/_modul.php
index 2fdd755..1ac6280 100644
--- a/app/views/search/module/_modul.php
+++ b/app/views/search/module/_modul.php
@@ -8,7 +8,7 @@
?>
<tbody class="<?= (isset($modul_id) && $modul_id == $modul->id) ? 'not-collapsed' : 'collapsed' ?>">
<tr class="table-header header-row" id="modul_<?= htmlReady($modul->id) ?>">
- <td style="vertical-align: middle; text-align: center;">
+ <td>
<a data-dialog="size=auto" title="<?= htmlReady($modul->getDisplayName()) . ' (' . _('Vollständige Modulbeschreibung') . ')' ?>" href="<?= $controller->link_for('shared/modul/description/' . $modul->id) ?>">
<?= Icon::create('log')->asImg(['title' => _('Vollständige Modulbeschreibung')]) ?>
</a>
diff --git a/app/views/search/module/index.php b/app/views/search/module/index.php
index a2d5c19..724ff27 100644
--- a/app/views/search/module/index.php
+++ b/app/views/search/module/index.php
@@ -25,13 +25,12 @@
<col>
<col>
<col>
+ <col>
</colgroup>
<thead>
<tr>
<th>
- <abbr title="<?= _('Moduldeskriptor') ?>">
- <?= Icon::create('log', Icon::ROLE_INFO) ?>
- </abbr>
+ <?= Icon::create('log', Icon::ROLE_INFO, ['title' => _('Modulbeschreibung')]) ?>
</th>
<th class="mvv-search-modules-row"><?= _('Modultitel') ?></th>
<th><?= _('Gültigkeit') ?></th>
diff --git a/app/views/search/studiengaenge/verlauf.php b/app/views/search/studiengaenge/verlauf.php
index d5357bc..3046673 100644
--- a/app/views/search/studiengaenge/verlauf.php
+++ b/app/views/search/studiengaenge/verlauf.php
@@ -85,11 +85,25 @@
<tr>
<td<?= count($modul['modulTeile']) > 1 ? ' style="border: none;"' : '' ?>>
<? $abschnitt_modul = StgteilabschnittModul::findOneBySQL('`abschnitt_id` = ? AND `modul_id` = ?', [$abschnitt_id, $modul_id]) ?>
- <a data-dialog="size=auto" title="<?= htmlReady($modul['name']) . ' (' . _('Vollständige Modulbeschreibung') . ')' ?>" href="<?= $controller->link_for('shared/modul/description/' . $modul_id, ['display_language' => ModuleManagementModel::getLanguage()]) ?>">
+ <a data-dialog="size=auto"
+ title="<?= htmlReady($modul['name']) . ' (' . _('Vollständige Modulbeschreibung') . ')' ?>"
+ href="<?= $controller->link_for('shared/modul/description/' . $modul_id,
+ [
+ 'display_language' => ModuleManagementModel::getLanguage(),
+ 'abschnitt_id' => $abschnitt_id,
+ ]) ?>">
<?= Icon::create('log', Icon::ROLE_CLICKABLE, ['title' => _('Vollständige Modulbeschreibung')]) ?>
</a>
<? if ($modul['courses']) : ?>
- <a data-dialog href="<?= $controller->link_for('shared/modul/overview', $modul_id, $active_sem->getId(), ['display_language' => ModuleManagementModel::getLanguage()]) ?>">
+ <a data-dialog
+ href="<?= $controller->link_for(
+ 'shared/modul/overview',
+ $modul_id,
+ $active_sem->id,
+ [
+ 'display_language' => ModuleManagementModel::getLanguage(),
+ 'abschnitt_id' => $abschnitt_id,
+ ]); ?>">
<?= htmlReady($abschnitt_modul->getDisplayName()) ?>
</a>
<? else: ?>
diff --git a/app/views/shared/modul/_modul.php b/app/views/shared/modul/_modul.php
index f3ebfd7..afff494 100644
--- a/app/views/shared/modul/_modul.php
+++ b/app/views/shared/modul/_modul.php
@@ -1,25 +1,23 @@
<?php
/**
* @var Modul $modul
- * @var ModulDeskriptor $modulDeskriptor
* @var string $affect_id
- * @var array $modulVerantwortung
* @var int $type
- * @var int $nummer_modulteil
- * @var array $note
- * @var string $num_bezeichnung
+ * @var StgteilabschnittModul|null $abschnitt_modul
+ * @var string $code
+ * @var string $title
*/
-$modulDeskriptor = $modul->getDeskriptor($display_language ?? null);
+$deskriptor = $modul->getDeskriptor($display_language ?? null);
?>
-<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modul->getId(); ?>" data-mvv-type="modul">
+<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modul->id ?>" data-mvv-type="modul">
<colgroup>
<col width="30%">
<col width="70%">
</colgroup>
<thead>
<tr>
- <th class="mvv-modul-details-head" data-mvv-field="mvv_modul.code"><?= htmlReady($modul->code) ?></th>
- <th class="mvv-modul-details-head" data-mvv-field="mvv_modul.kp" style="text-align: right;"><?= sprintf("%d CP", $modul->kp) ?></th>
+ <th class="mvv-modul-details-head" data-mvv-field="mvv_modul.code"><?= htmlReady($code ?: $modul->code) ?></th>
+ <th class="mvv-modul-details-head" data-mvv-field="mvv_modul.kp" style="text-align: right;"><?= sprintf("%d CP", $modul->getReplacedValue('kp')) ?></th>
</tr>
<? if ($modul->fassung_nr): ?>
<tr>
@@ -37,20 +35,20 @@ $modulDeskriptor = $modul->getDeskriptor($display_language ?? null);
<tbody>
<tr>
<td><strong><?= _('Modulbezeichnung') ?></strong></td>
- <td data-mvv-field="mvv_modul.bezeichnung"><?= htmlReady($modulDeskriptor->bezeichnung) ?></td>
+ <td data-mvv-field="mvv_modul.bezeichnung"><?= htmlReady($title ?: $deskriptor->bezeichnung) ?></td>
</tr>
<tr>
<td><strong><?= _('Modulcode') ?></strong></td>
- <td data-mvv-field="mvv_modul.code"><?= htmlReady($modul->code) ?></td>
+ <td data-mvv-field="mvv_modul.code"><?= htmlReady($code ?: $modul->code) ?></td>
</tr>
<tr>
<td><strong><?= _('Semester der erstmaligen Durchführung') ?></strong></td>
- <td data-mvv-field="mvv_modul.start"><?= htmlReady($startSemester['name'] ?? '') ?></td>
+ <td data-mvv-field="mvv_modul.start"><?= htmlReady($start_semester['name'] ?? '') ?></td>
</tr>
- <? if (!empty($instituteName)) : ?>
+ <? if (!empty($institute_name)) : ?>
<tr>
<td><strong><?= _('Fachbereich/Institut') ?></strong></td>
- <td data-mvv-field="mvv_modul_inst"><?= htmlReady($instituteName) ?></td>
+ <td data-mvv-field="mvv_modul_inst"><?= htmlReady($institute_name) ?></td>
</tr>
<? endif; ?>
<tr>
@@ -116,25 +114,25 @@ $modulDeskriptor = $modul->getDeskriptor($display_language ?? null);
<? endforeach; ?>
</td>
</tr>
- <? if (trim($modulDeskriptor->verantwortlich)): ?>
+ <? if (trim($deskriptor->getReplacedValue('verantwortlich'))): ?>
<tr>
<td><strong><?= _('Weitere verantwortliche Personen') ?></strong></td>
<td>
- <?= formatReady($modulDeskriptor->verantwortlich) ?>
+ <?= formatReady($deskriptor->getReplacedValue('verantwortlich')) ?>
</td>
</tr>
<? endif; ?>
<tr>
<td><strong><?= _('Teilnahmevoraussetzungen') ?></strong></td>
- <td data-mvv-field="mvv_modul_deskriptor.voraussetzung"><?= formatReady($modulDeskriptor->voraussetzung) ?></td>
+ <td data-mvv-field="mvv_modul_deskriptor.voraussetzung"><?= formatReady($deskriptor->getReplacedValue('voraussetzung')) ?></td>
</tr>
<tr>
<td><strong><?= _('Kompetenzziele') ?></strong></td>
- <td data-mvv-field="mvv_modul_deskriptor.kompetenzziele"><?= formatReady($modulDeskriptor->kompetenzziele) ?></td>
+ <td data-mvv-field="mvv_modul_deskriptor.kompetenzziele"><?= formatReady($deskriptor->getReplacedValue('kompetenzziele')) ?></td>
</tr>
<tr>
<td><strong><?= _('Modulinhalte') ?></strong></td>
- <td data-mvv-field="mvv_modul_deskriptor.inhalte"><?= formatReady($modulDeskriptor->inhalte) ?></td>
+ <td data-mvv-field="mvv_modul_deskriptor.inhalte"><?= formatReady($deskriptor->getReplacedValue('inhalte')) ?></td>
</tr>
<? if (!isset($type) || $type !== 3) : ?>
<tr>
@@ -164,19 +162,26 @@ $modulDeskriptor = $modul->getDeskriptor($display_language ?? null);
</tr>
<tr>
<td><strong><?= _('Angebotsrhythmus Modul') ?></strong></td>
- <td data-mvv-field="mvv_modul_deskriptor.turnus"><?= htmlReady($modulDeskriptor->turnus) ?></td>
+ <td data-mvv-field="mvv_modul_deskriptor.turnus"><?= htmlReady($deskriptor->turnus) ?></td>
</tr>
<tr>
<td><strong><?= _('Aufnahmekapazität Modul') ?></strong></td>
- <td data-mvv-field="mvv_modul.kapazitaet"><?= htmlReady(trim($modul->kapazitaet)) ?: _('unbegrenzt') ?> <?= MVVController::trim($modulDeskriptor->kommentar_kapazitaet) ? sprintf("(%s)", formatReady($modulDeskriptor->kommentar_kapazitaet)) : '' ?></td>
+ <td data-mvv-field="mvv_modul.kapazitaet">
+ <?= htmlReady(trim($modul->getReplacedValue('kapazitaet')) ?: _('unbegrenzt')) ?>
+ <?= MVVController::trim($deskriptor->getReplacedValue('kommentar_kapazitaet'))
+ ? sprintf("(%s)", formatReady($deskriptor->getReplacedValue('kommentar_kapazitaet')))
+ : '' ?>
+ </td>
</tr>
<tr>
<td><strong><?= _('Prüfungsebene') ?></strong></td>
- <td data-mvv-field="mvv_modul.pruef_ebene"><?= htmlReady($pruefungsEbene ?? '') ?></td>
+ <td data-mvv-field="mvv_modul.pruef_ebene">
+ <?= htmlReady($GLOBALS['MVV_MODUL']['PRUEF_EBENE']['values'][$modul->getReplacedValue('pruef_ebene')] ?? '') ?>
+ </td>
</tr>
<tr>
<td><strong><?= _('Credit-Points') ?></strong></td>
- <td data-mvv-field="mvv_modul.kp"><?= sprintf("%d CP", htmlReady($modul->kp)) ?></td>
+ <td data-mvv-field="mvv_modul.kp"><?= sprintf("%d CP", htmlReady($modul->getReplacedValue('kp'))) ?></td>
</tr>
<tr>
<td><strong><?= _('Modulabschlussnote') ?></strong></td>
@@ -212,25 +217,38 @@ $modulDeskriptor = $modul->getDeskriptor($display_language ?? null);
<?= implode('; ', $note) . '. ' ?>
<? endif; ?>
<? endif; ?>
- <?= formatReady(trim($modulDeskriptor->kommentar_note)) ?>
+ <?= formatReady(trim($deskriptor->getReplacedValue('kommentar_note'))) ?>
</td>
</tr>
<tr>
<td><strong><?= _('Faktor der Modulnote für die Endnote des Studiengangs') ?></strong></td>
- <td data-mvv-field="mvv_modul.faktor_note"><?= htmlReady($modul->faktor_note) ?></td>
+ <td data-mvv-field="mvv_modul.faktor_note"><?= htmlReady($modul->getReplacedValue('faktor_note')) ?></td>
</tr>
- <? if (trim($modulDeskriptor->kommentar)) : ?>
+ <? if (trim($deskriptor->getReplacedValue('kommentar'))) : ?>
<tr>
<td><strong><?= _('Hinweise') ?></strong></td>
- <td data-mvv-field="mvv_modul_deskriptor.kommentar"><?= formatReady($modulDeskriptor->kommentar) ?></td>
+ <td data-mvv-field="mvv_modul_deskriptor.kommentar"><?= formatReady($deskriptor->getReplacedValue('kommentar')) ?></td>
</tr>
<? endif; ?>
- <? foreach ($modulDeskriptor->datafields as $entry) : ?>
- <? $df = $entry->getTypedDatafield(); ?>
- <tr>
- <td><strong><?= htmlReady($df->getName()) ?></strong></td>
- <td><?= $df->getDisplayValue(); ?></td>
- </tr>
+ <? foreach ($deskriptor->datafields as $entry) : ?>
+ <? $df = $entry->getTypedDatafield(); ?>
+ <tr>
+ <td><strong><?= htmlReady($df->getName()) ?></strong></td>
+ <td><?= $df->getDisplayValue(); ?></td>
+ </tr>
<? endforeach; ?>
+ <? if ($abschnitt_modul) : ?>
+ <? $data_fields = $abschnitt_modul->datafields->filter(
+ fn(DatafieldEntryModel $d): bool => ($d->datafield->object_class ?? '') === '') ?>
+ <? foreach ($data_fields as $entry) : ?>
+ <? if (trim($entry->content)) : ?>
+ <? $df = $entry->getTypedDatafield(); ?>
+ <tr>
+ <td><strong><?= htmlReady($df->getName()) ?></strong></td>
+ <td><?= $df->getDisplayValue(); ?></td>
+ </tr>
+ <? endif; ?>
+ <? endforeach; ?>
+ <? endif; ?>
</tbody>
</table>
diff --git a/app/views/shared/modul/_modul_ohne_lv.php b/app/views/shared/modul/_modul_ohne_lv.php
index f3c74ec..013f4cb 100644
--- a/app/views/shared/modul/_modul_ohne_lv.php
+++ b/app/views/shared/modul/_modul_ohne_lv.php
@@ -1,14 +1,33 @@
-<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modul->getId(); ?>" data-mvv-type="modul">
+<?php
+/**
+ * @var Modul $modul
+ * @var StgteilabschnittModul|null $abschnitt_modul
+ * @var string $code
+ * @var string $title
+ */
+?>
+<? $deskriptor = $modul->getDeskriptor(); ?>
+<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modul->id; ?>" data-mvv-type="modul">
<tbody>
<? $modulSumme = $modul->wl_selbst + $modul->wl_pruef ?>
<tr>
<td style="width: 30%;"><strong><?= _('Workload selbstgestaltete Arbeit') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul.wl_selbst mvv_modul_deskriptor.kommentar_wl_selbst"><?= htmlReady($modul->wl_selbst) ?> <?= MVVController::trim($modulDeskriptor->kommentar_wl_selbst ?? '') ? sprintf(" (%s)", formatReady($modulDeskriptor->kommentar_wl_selbst)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul.wl_selbst mvv_modul_deskriptor.kommentar_wl_selbst">
+ <?= htmlReady($modul->getReplacedValue('wl_selbst')) ?>
+ <?= MVVController::trim($deskriptor->getReplacedValue('kommentar_wl_selbst'))
+ ? sprintf(" (%s)", formatReady($deskriptor->getReplacedValue('kommentar_wl_selbst')))
+ : '' ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Workload Prüfung incl. Vorbereitung') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul.wl_pruef mvv_modul_deskriptor.kommentar_wl_pruef"><?= htmlReady($modul->wl_pruef) ?> <?= MVVController::trim($modulDeskriptor->kommentar_wl_pruef ?? '') ? sprintf(" (%s)", formatReady($modulDeskriptor->kommentar_wl_pruef)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul.wl_pruef mvv_modul_deskriptor.kommentar_wl_pruef">
+ <?= htmlReady($modul->getReplacedValue('wl_pruef')) ?>
+ <?= MVVController::trim($deskriptor->getReplacedValue('kommentar_wl_pruef'))
+ ? sprintf(" (%s)", formatReady($deskriptor->getReplacedValue('kommentar_wl_pruef')))
+ : '' ?>
+ </td>
</tr>
<tr>
@@ -17,21 +36,27 @@
</tr>
</tbody>
</table>
-<table class="mvv-modul-details" data-mvv-id="<?= isset($modulDeskriptor) ? $modulDeskriptor->getId() : ''; ?>" data-mvv-type="moduldeskriptor">
+<table class="mvv-modul-details" data-mvv-id="<?= $deskriptor->id ?>" data-mvv-type="moduldeskriptor">
<tbody>
- <? if (trim($modulDeskriptor->pruef_vorleistung ?? '')) : ?>
+ <? if (trim($deskriptor->getReplacedValue('pruef_vorleistung'))) : ?>
<tr>
<td style="width: 30%;"><strong><?= _('Prüfungsvorleistung') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul_deskriptor.pruef_vorleistung" ><?= formatReady($modulDeskriptor->pruef_vorleistung ?? '') ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul_deskriptor.pruef_vorleistung" >
+ <?= formatReady($deskriptor->getReplacedValue('pruef_vorleistung')) ?>
+ </td>
</tr>
<? endif; ?>
<tr>
<td style="width: 30%;"><strong><?= _('Prüfungsform') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul_deskriptor.pruef_leistung"><?= formatReady($modulDeskriptor->pruef_leistung ?? '') ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul_deskriptor.pruef_leistung">
+ <?= formatReady($deskriptor->getReplacedValue('pruef_leistung')) ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Wiederholungsprüfung') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul_deskriptor.pruef_wiederholung"><?= formatReady($modulDeskriptor->pruef_wiederholung ?? '') ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul_deskriptor.pruef_wiederholung">
+ <?= formatReady($deskriptor->getReplacedValue('pruef_wiederholung')) ?>
+ </td>
</tr>
</tbody>
</table>
diff --git a/app/views/shared/modul/_modullv.php b/app/views/shared/modul/_modullv.php
index 70ffd64..2675f31 100644
--- a/app/views/shared/modul/_modullv.php
+++ b/app/views/shared/modul/_modullv.php
@@ -1,102 +1,175 @@
-<? $modulTeil = $modul->modulteile->first(); ?>
-<? $modulTeilDeskriptor = $modulTeil->getDeskriptor($display_language ?? null); ?>
-<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulTeil->id; ?>" data-mvv-type="modulteil">
+<?php
+/**
+ * @var Modul $modul
+ * @var StgteilabschnittModul|null $abschnitt_modul
+ */
+?>
+<? $modulteil = $modul->modulteile->first(); ?>
+<? $modulteil_deskriptor = $modulteil->getDeskriptor(); ?>
+<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulteil->id; ?>" data-mvv-type="modulteil">
<tbody>
- <? $modulTeilSumme = $modulTeil->wl_praesenz + $modulTeil->wl_bereitung + $modulTeil->wl_selbst + $modulTeil->wl_pruef ?>
+ <? $modulteil_summe = $modulteil->wl_praesenz + $modulteil->wl_bereitung + $modulteil->wl_selbst + $modulteil->wl_pruef ?>
<tr>
<td style="width: 30%;"><strong><?= _('Lehrveranstaltungsform') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.lernlehrform"><?= $GLOBALS['MVV_MODULTEIL']['LERNLEHRFORM']['values'][$modulTeil->lernlehrform]['name'] ?? '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.lernlehrform"><?= $GLOBALS['MVV_MODULTEIL']['LERNLEHRFORM']['values'][$modulteil->lernlehrform]['name'] ?? '' ?></td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Veranstaltungstitel') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil_deskriptor.bezeichnung"><?= htmlReady($modulTeilDeskriptor->bezeichnung) ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil_deskriptor.bezeichnung">
+ <?= htmlReady($modulteil_deskriptor->getReplacedValue('bezeichnung')) ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('SWS') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.sws mvv_modulteil_deskriptor.sws_alternative"><?= $modulTeil->sws ?: '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.sws mvv_modulteil_deskriptor.sws_alternative">
+ <?= $modulteil->sws ?: '' ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Workload Präsenz') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_praesenz mvv_modulteil_deskriptor.kommentar_wl_praesenz"><?= $modulTeil->wl_praesenz ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_praesenz) ? sprintf(" (%s)", formatReady($modulTeilDeskriptor->kommentar_wl_praesenz)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_praesenz mvv_modulteil_deskriptor.kommentar_wl_praesenz">
+ <?= $modulteil->getReplacedValue('wl_praesenz') ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_praesenz'))
+ ? sprintf(" (%s)", formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_praesenz')))
+ : '' ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Workload Vor- / Nachbereitung') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_bereitung mvv_modulteil_deskriptor.kommentar_wl_bereitung"><?= $modulTeil->wl_bereitung ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_bereitung) ? sprintf(" (%s)", formatReady($modulTeilDeskriptor->kommentar_wl_bereitung)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_bereitung mvv_modulteil_deskriptor.kommentar_wl_bereitung">
+ <?= $modulteil->getReplacedValue('wl_bereitung') ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_bereitung'))
+ ? sprintf(" (%s)", formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_bereitung')))
+ : '' ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Workload selbstgestaltete Arbeit') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_selbst mvv_modulteil_deskriptor.kommentar_wl_selbst"><?= $modulTeil->wl_selbst ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_selbst) ? sprintf(" (%s)", formatReady($modulTeilDeskriptor->kommentar_wl_selbst)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_selbst mvv_modulteil_deskriptor.kommentar_wl_selbst">
+ <?= $modulteil->getReplacedValue('wl_selbst') ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_selbst'))
+ ? sprintf(" (%s)", formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_selbst')))
+ : '' ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Workload Prüfung incl. Vorbereitung') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_pruef mvv_modulteil_deskriptor.kommentar_wl_pruef"><?= $modulTeil->wl_pruef ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_pruef) ? sprintf(" (%s)", formatReady($modulTeilDeskriptor->kommentar_wl_pruef)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.wl_pruef mvv_modulteil_deskriptor.kommentar_wl_pruef">
+ <?= $modulteil->getReplacedValue('wl_pruef') ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_pruef'))
+ ? sprintf(" (%s)", formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_pruef')))
+ : '' ?>
+ </td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Workload insgesamt') ?></strong></td>
- <td style="width: 70%;"><?= $modulTeilSumme ?></td>
+ <td style="width: 70%;"><?= $modulteil_summe ?></td>
</tr>
- <? if ((int) $modul->wl_selbst) : ?>
+ <? if ((int) $modul->getReplacedValue('wl_selbst')) : ?>
<tr>
<td style="width: 30%;"><strong><?= _('Workload selbstgestaltete Arbeit (modulbezogen') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul.wl_selbst mvv_modul_deskriptor.kommentar_wl_selbst"><?= $modul->wl_selbst ?> <?= MVVController::trim($modulDeskriptor->kommentar_wl_selbst) ? sprintf(" (%s)", formatReady($modulDeskriptor->kommentar_wl_selbst)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul.wl_selbst mvv_modul_deskriptor.kommentar_wl_selbst">
+ <?= $modul->getReplacedValue('wl_selbst') ?>
+ <?= MVVController::trim($modul->deskriptoren->getReplacedValue('kommentar_wl_selbst'))
+ ? sprintf(" (%s)", formatReady($modul->deskriptoren->getReplacedValue('kommentar_wl_selbst')))
+ : '' ?>
+ </td>
</tr>
<? endif; ?>
- <? if ((int) $modul->wl_pruef) : ?>
+ <? if ((int) $modul->getReplacedValue('wl_pruef')) : ?>
<tr>
<td style="width: 30%;"><strong><?= _('Workload Prüfung incl. Vorbereitung (modulbezogen)') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modul.wl_pruef mvv_modul_deskriptor.kommentar_wl_pruef"><?= $modul->wl_pruef ?> <?= MVVController::trim($modulDeskriptor->kommentar_wl_pruef) ? sprintf(" (%s)", formatReady($modulDeskriptor->kommentar_wl_pruef)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modul.wl_pruef mvv_modul_deskriptor.kommentar_wl_pruef">
+ <?= $modul->getReplacedValue('wl_pruef') ?>
+ <?= MVVController::trim($modul->deskriptoren->getReplacedValue('kommentar_wl_pruef'))
+ ? sprintf(" (%s)", formatReady($modul->deskriptoren->getReplacedValue('kommentar_wl_pruef')))
+ : '' ?>
+ </td>
</tr>
<? endif; ?>
- <? if ($modul->wl_selbst + $modul->wl_pruef) : ?>
+ <? if (intval($modul->getReplacedValue('wl_selbst')) + intval($modul->getReplacedValue('wl_pruef'))) : ?>
<tr>
<td style="width: 30%;"><strong><?= _('Workload Modul insgesamt') ?></strong></td>
- <td style="width: 70%;"><?= $modulTeilSumme + $modul->wl_selbst + $modul->wl_pruef ?></td>
+ <td style="width: 70%;"><?=
+ $modulteil_summe
+ + intval($modul->getReplacedValue('wl_selbst'))
+ + intval($modul->getReplacedValue('wl_pruef')) ?></td>
</tr>
<? endif; ?>
</tbody>
</table>
-<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulTeilDeskriptor->id; ?>" data-mvv-type="modulteil_deskriptor">
+<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulteil_deskriptor->id; ?>" data-mvv-type="modulteil_deskriptor">
<tbody>
- <? if (trim($modulTeilDeskriptor->pruef_vorleistung)) : ?>
+ <? if (trim($modulteil_deskriptor->pruef_vorleistung)) : ?>
<tr>
<td style="width: 30%;"><strong><?= _('Prüfungsvorleistung') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil_deskriptor.pruef_vorleistung"><?= formatReady($modulTeilDeskriptor->pruef_vorleistung) ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil_deskriptor.pruef_vorleistung">
+ <?= formatReady($modulteil_deskriptor->getReplacedValue('pruef_vorleistung')) ?>
+ </td>
</tr>
<? endif; ?>
<tr>
<td style="width: 30%;"><strong><?= _('Prüfungsform') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil_deskriptor.pruef_leistung"><?= formatReady($modulTeilDeskriptor->pruef_leistung) ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil_deskriptor.pruef_leistung">
+ <?= formatReady($modulteil_deskriptor->getReplacedValue('pruef_leistung')) ?>
+ </td>
</tr>
</tbody>
</table>
-<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulTeil->id; ?>" data-mvv-type="modulteil">
+<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulteil->id; ?>" data-mvv-type="modulteil">
<tbody>
<tr>
<td style="width: 30%;"><strong><?= _('Angebotsrhythmus') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.semester"><?= $GLOBALS['MVV_NAME_SEMESTER']['values'][$modulTeil->semester]['name'] ?? '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.semester"><?= $GLOBALS['MVV_NAME_SEMESTER']['values'][$modulteil->semester]['name'] ?? '' ?></td>
</tr>
<tr>
<td style="width: 30%;"><strong><?= _('Aufnahmekapazität') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.kapazitaet mvv_modulteil_deskriptor.kommentar_kapazitaet"><?= trim($modulTeil->kapazitaet) ?: _('unbegrenzt') ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_kapazitaet) ? sprintf("(%s)", formatReady($modulTeilDeskriptor->kommentar_kapazitaet)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.kapazitaet mvv_modulteil_deskriptor.kommentar_kapazitaet">
+ <?= trim($modulteil->kapazitaet) ?: _('unbegrenzt') ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_kapazitaet'))
+ ? sprintf("(%s)", formatReady($modulteil_deskriptor->getReplacedValue('kommentar_kapazitaet')))
+ : '' ?>
+ </td>
</tr>
- <? if ($modulTeil->pflicht) : ?>
+ <? if ($modulteil->pflicht) : ?>
<tr>
<td style="width: 30%;"><strong><?= _('Anwesenheitspflicht') ?></strong></td>
- <td style="width: 70%;" data-mvv-field="mvv_modulteil.pflicht mvv_modulteil_deskriptor.kommentar_pflicht"><?= $modulTeil->pflicht ? _('Ja') : _('Nein') ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_pflicht) ? sprintf("(%s)", formatReady($modulTeilDeskriptor->kommentar_pflicht)) : '' ?></td>
+ <td style="width: 70%;" data-mvv-field="mvv_modulteil.pflicht mvv_modulteil_deskriptor.kommentar_pflicht">
+ <?= $modulteil->pflicht ? _('Ja') : _('Nein') ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_pflicht'))
+ ? sprintf("(%s)", formatReady($modulteil_deskriptor->getReplacedValue('kommentar_pflicht')))
+ : '' ?>
+ </td>
</tr>
<? endif; ?>
</tbody>
</table>
-<? if (count($modulTeilDeskriptor->datafields)) : ?>
-<table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulTeilDeskriptor->id; ?>" data-mvv-type="modulteil_deskriptor">
- <tbody>
- <? foreach ($modulTeilDeskriptor->datafields as $entry) : ?>
- <? $df = $entry->getTypedDatafield(); ?>
- <tr>
- <td style="width: 30%;"><strong><?= htmlReady($df->getName()) ?></strong></td>
- <td style="width: 70%;"><?= $df->getDisplayValue(); ?></td>
- </tr>
- <? endforeach; ?>
- </tbody>
-</table>
+<? $data_fields = []; ?>
+<? if ($abschnitt_modul) : ?>
+ <? $data_fields = $abschnitt_modul->datafields->filter(
+ fn(DatafieldEntryModel $d): bool => ($d->datafield->object_class ?? '') === '') ?>
+<? endif; ?>
+<? if (count($modulteil_deskriptor->datafields)) : ?>
+ <table class="mvv-modul-details default nohover" data-mvv-id="<?= $modulteil_deskriptor->id; ?>" data-mvv-type="modulteil_deskriptor">
+ <tbody>
+ <? foreach ($modulteil_deskriptor->datafields as $entry) : ?>
+ <? if (trim($entry->content)) : ?>
+ <? $df = $entry->getTypedDatafield(); ?>
+ <tr>
+ <td style="width: 30%;"><strong><?= htmlReady($df->getName()) ?></strong></td>
+ <td style="width: 70%;"><?= $df->getDisplayValue(); ?></td>
+ </tr>
+ <? endif; ?>
+ <? endforeach; ?>
+ <? foreach ($data_fields as $entry) : ?>
+ <? if (trim($entry->content)) : ?>
+ <? $df = $entry->getTypedDatafield(); ?>
+ <tr>
+ <td style="width: 30%;"><strong><?= htmlReady($df->getName()) ?></strong></td>
+ <td style="width: 70%;"><?= $df->getDisplayValue(); ?></td>
+ </tr>
+ <? endif; ?>
+ <? endforeach; ?>
+ </tbody>
+ </table>
<? endif; ?>
diff --git a/app/views/shared/modul/_modullvs.php b/app/views/shared/modul/_modullvs.php
index c2fc775..2b45eb1 100644
--- a/app/views/shared/modul/_modullvs.php
+++ b/app/views/shared/modul/_modullvs.php
@@ -1,3 +1,9 @@
+<?php
+/**
+ * @var Modul $modul
+ * @var StgteilabschnittModul|null $abschnitt_modul
+ */
+?>
<table class="mvv-modul-details default nohover">
<thead>
<tr>
@@ -17,48 +23,88 @@
<? $wlPruef = 0; ?>
<? $modulSumme = 0; ?>
<? $nummer_modulteil = 1; ?>
- <? foreach ($modul->modulteile as $modulTeil): ?>
- <? $modulTeilDeskriptor = $modulTeil->getDeskriptor($display_language ?? null);
+ <? foreach ($modul->modulteile as $modulteil): ?>
+ <? $modulteil_deskriptor = $modulteil->getDeskriptor();
// Für die Kenntlichmachung der Modulteile in Listen die Nummer des
// Modulteils und den ausgewählten Namen verwenden.
// Ist keine Nummer vorhanden, dann Durchnummerieren und Standard-
// Bezeichnung verwenden.
- if (trim($modulTeil->nummer)) {
- $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulTeil->num_bezeichnung]['name'];
- $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulTeil->nummer);
+ if (trim($modulteil->nummer)) {
+ $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulteil->num_bezeichnung]['name'];
+ $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulteil->nummer);
} else {
$num_bezeichnung_default = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['default'];
$name_kurz = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$num_bezeichnung_default]['name']
. ' ' . $nummer_modulteil;
$nummer_modulteil++;
} ?>
- <? $wlSelbst += $modulTeil->wl_selbst; ?>
- <? $wlPruef += $modulTeil->wl_pruef; ?>
- <? $modulTeilSumme = $modulTeil->wl_praesenz + $modulTeil->wl_bereitung + $modulTeil->wl_selbst + $modulTeil->wl_pruef; ?>
- <? $modulSumme += $modulTeilSumme; ?>
+ <? $wlSelbst += $modulteil->wl_selbst; ?>
+ <? $wlPruef += $modulteil->wl_pruef; ?>
+ <? $modulteil_summe = $modulteil->wl_praesenz + $modulteil->wl_bereitung + $modulteil->wl_selbst + $modulteil->wl_pruef; ?>
+ <? $modulSumme += $modulteil_summe; ?>
<? if (!empty($show_synopse)) : ?>
- <tr data-mvv-id="<?= $modulTeil->getId(); ?>" data-mvv-type="modulteil">
+ <tr data-mvv-id="<?= $modulteil->id; ?>" data-mvv-type="modulteil">
<td data-mvv-field="mvv_modulteil.nummer mvv_modulteil.num_bezeichnung"><strong><?= htmlReady($name_kurz) ?></strong></td>
- <td data-mvv-field="mvv_modulteil.lernlehrform"><?= $GLOBALS['MVV_MODULTEIL']['LERNLEHRFORM']['values'][$modulTeil->lernlehrform]['name'] ?? '' ?></td>
- <td data-mvv-field="mvv_modulteil_deskriptor.bezeichnung"><?= htmlReady($modulTeilDeskriptor->bezeichnung) ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.sws"><?= htmlReady($modulTeil->sws) ?: '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_praesenz mvv_modulteil_deskriptor.kommentar_wl_praesenz"><?= $modulTeil->wl_praesenz ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_praesenz) ? sprintf(' (%s)', formatReady($modulTeilDeskriptor->kommentar_wl_praesenz)) : '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_bereitung mvv_modulteil_deskriptor.kommentar_wl_bereitung"><?= $modulTeil->wl_bereitung ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_bereitung) ? sprintf(' (%s)', formatReady($modulTeilDeskriptor->kommentar_wl_bereitung)) : '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_selbst mvv_modulteil_deskriptor.kommentar_wl_selbst"><?= $modulTeil->wl_selbst ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_selbst) ? sprintf(' (%s)', formatReady($modulTeilDeskriptor->kommentar_wl_selbst)) : '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_pruef mvv_modulteil_deskriptor.kommentar_wl_pruef"><?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_pruef) ? sprintf(' (%s)',formatReady($modulTeilDeskriptor->kommentar_wl_pruef)) : '' ?><?= $modulTeil->wl_pruef ?></td>
- <td style="text-align: right;"><?= $modulTeilSumme ?></td>
+ <td data-mvv-field="mvv_modulteil.lernlehrform"><?= $GLOBALS['MVV_MODULTEIL']['LERNLEHRFORM']['values'][$modulteil->lernlehrform]['name'] ?? '' ?></td>
+ <td data-mvv-field="mvv_modulteil_deskriptor.bezeichnung"><?= htmlReady($modulteil_deskriptor->bezeichnung) ?></td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.sws"><?= htmlReady($modulteil->sws) ?: '' ?></td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_praesenz mvv_modulteil_deskriptor.kommentar_wl_praesenz">
+ <?= $modulteil->wl_praesenz ?>
+ <?= MVVController::trim($modulteil_deskriptor->kommentar_wl_praesenz)
+ ? sprintf(' (%s)', formatReady($modulteil_deskriptor->kommentar_wl_praesenz))
+ : '' ?>
+ </td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_bereitung mvv_modulteil_deskriptor.kommentar_wl_bereitung">
+ <?= $modulteil->wl_bereitung ?>
+ <?= MVVController::trim($modulteil_deskriptor->kommentar_wl_bereitung)
+ ? sprintf(' (%s)', formatReady($modulteil_deskriptor->kommentar_wl_bereitung))
+ : '' ?>
+ </td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_selbst mvv_modulteil_deskriptor.kommentar_wl_selbst">
+ <?= $modulteil->wl_selbst ?>
+ <?= MVVController::trim($modulteil_deskriptor->kommentar_wl_selbst)
+ ? sprintf(' (%s)', formatReady($modulteil_deskriptor->kommentar_wl_selbst))
+ : '' ?>
+ </td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_pruef mvv_modulteil_deskriptor.kommentar_wl_pruef">
+ <?= $modulteil->wl_pruef ?>
+ <?= MVVController::trim($modulteil_deskriptor->kommentar_wl_pruef)
+ ? sprintf(' (%s)',formatReady($modulteil_deskriptor->kommentar_wl_pruef))
+ : '' ?>
+ </td>
+ <td style="text-align: right;"><?= $modulteil_summe ?></td>
</tr>
<? else : ?>
- <tr data-mvv-id="<?= $modulTeil->getId(); ?>" data-mvv-type="modulteil">
+ <tr data-mvv-id="<?= $modulteil->id; ?>" data-mvv-type="modulteil">
<td data-mvv-field="mvv_modulteil.nummer mvv_modulteil.num_bezeichnung"><strong><?= htmlReady($name_kurz) ?></strong></td>
- <td data-mvv-field="mvv_modulteil.lernlehrform"><?= $GLOBALS['MVV_MODULTEIL']['LERNLEHRFORM']['values'][$modulTeil->lernlehrform]['name'] ?? '' ?></td>
- <td data-mvv-field="mvv_modulteil_deskriptor.bezeichnung"><?= htmlReady($modulTeilDeskriptor->bezeichnung) ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.sws"><?= htmlReady($modulTeil->sws) ?: '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_praesenz mvv_modulteil_deskriptor.kommentar_wl_praesenz"><?= $modulTeil->wl_praesenz ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_praesenz) ? tooltipIcon(formatReady($modulTeilDeskriptor->kommentar_wl_praesenz)) : '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_bereitung mvv_modulteil_deskriptor.kommentar_wl_bereitung"><?= $modulTeil->wl_bereitung ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_bereitung) ? tooltipIcon(formatReady($modulTeilDeskriptor->kommentar_wl_bereitung)) : '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_selbst mvv_modulteil_deskriptor.kommentar_wl_selbst"><?= $modulTeil->wl_selbst ?> <?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_selbst) ? tooltipIcon(formatReady($modulTeilDeskriptor->kommentar_wl_selbst)) : '' ?></td>
- <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_pruef mvv_modulteil_deskriptor.kommentar_wl_pruef"><?= MVVController::trim($modulTeilDeskriptor->kommentar_wl_pruef) ? tooltipIcon(formatReady($modulTeilDeskriptor->kommentar_wl_pruef)) : '' ?><?= $modulTeil->wl_pruef ?></td>
- <td style="text-align: right;"><?= $modulTeilSumme ?></td>
+ <td data-mvv-field="mvv_modulteil.lernlehrform"><?= $GLOBALS['MVV_MODULTEIL']['LERNLEHRFORM']['values'][$modulteil->lernlehrform]['name'] ?? '' ?></td>
+ <td data-mvv-field="mvv_modulteil_deskriptor.bezeichnung"><?= htmlReady($modulteil_deskriptor->getReplacedValue('bezeichnung')) ?></td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.sws"><?= htmlReady($modulteil->sws) ?: '' ?></td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_praesenz mvv_modulteil_deskriptor.kommentar_wl_praesenz">
+ <?= $modulteil->wl_praesenz ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_praesenz'))
+ ? tooltipIcon(formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_praesenz')))
+ : '' ?>
+ </td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_bereitung mvv_modulteil_deskriptor.kommentar_wl_bereitung">
+ <?= $modulteil->wl_bereitung ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_bereitung'))
+ ? tooltipIcon(formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_bereitung')))
+ : '' ?>
+ </td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_selbst mvv_modulteil_deskriptor.kommentar_wl_selbst">
+ <?= $modulteil->wl_selbst ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_selbst'))
+ ? tooltipIcon(formatReady($modulteil_deskriptor->getReplacedValue('kommentar_wl_selbst')))
+ : '' ?>
+ </td>
+ <td style="text-align: right;" data-mvv-field="mvv_modulteil.wl_pruef mvv_modulteil_deskriptor.kommentar_wl_pruef">
+ <?= $modulteil->wl_pruef ?>
+ <?= MVVController::trim($modulteil_deskriptor->getReplacedValue('kommentar_wl_pruef'))
+ ? tooltipIcon(formatReady($modulteil_deskriptor->kommentar_wl_pruef))
+ : '' ?>
+ </td>
+ <td style="text-align: right;"><?= $modulteil_summe ?></td>
</tr>
<? endif; ?>
<? endforeach; ?>
diff --git a/app/views/shared/modul/_pruefungen.php b/app/views/shared/modul/_pruefungen.php
index b5b43cd..47174e7 100644
--- a/app/views/shared/modul/_pruefungen.php
+++ b/app/views/shared/modul/_pruefungen.php
@@ -1,3 +1,8 @@
+<?php
+/**
+ * @var Modul $modul
+ */
+?>
<table class="mvv-modul-details default nohover">
<thead>
<tr>
@@ -7,16 +12,16 @@
</tr>
</thead>
<tbody>
- <? foreach ($modul->modulteile as $modulTeil): ?>
+ <? foreach ($modul->modulteile as $modulteil): ?>
<?
- $modulTeilDeskriptor = $modulTeil->getDeskriptor($display_language ?? null);
+ $modulteil_deskriptor = $modulteil->getDeskriptor();
// Für die Kenntlichmachung der Modulteile in Listen die Nummer des
// Modulteils und den ausgewählten Namen verwenden.
- // Ist keine Nummer vorhanden, dann Durchnummerieren und Standard-
+ // Ist keine Nummer vorhanden, dann durchnummerieren und Standard-
// Bezeichnung verwenden.
- if (trim($modulTeil->nummer)) {
- $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulTeil->num_bezeichnung]['name'];
- $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulTeil->nummer);
+ if (trim($modulteil->nummer)) {
+ $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulteil->num_bezeichnung]['name'];
+ $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulteil->nummer);
} else {
$num_bezeichnung_default = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['default'];
$name_kurz = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$num_bezeichnung_default]['name']
@@ -24,26 +29,34 @@
$nummer_modulteil++;
}
?>
- <tr data-mvv-id="<?= $modulTeil->getId(); ?>" data-mvv-type="modulteil">
+ <tr data-mvv-id="<?= $modulteil->id; ?>" data-mvv-type="modulteil">
<td style="vertical-align: top; font-weight: bold;" data-mvv-field="mvv_modulteil.num_bezeichnung mvv_modulteil.nummer"><?= htmlReady($name_kurz) ?></td>
- <td data-mvv-field="mvv_modulteil_deskriptor.pruef_vorleistung"><?= formatReady($modulTeilDeskriptor->pruef_vorleistung) ?></td>
- <td data-mvv-field="mvv_modulteil_deskriptor.pruef_leistung"><?= formatReady($modulTeilDeskriptor->pruef_leistung) ?></td>
- </tr>
+ <td data-mvv-field="mvv_modulteil_deskriptor.pruef_vorleistung">
+ <?= formatReady($modulteil_deskriptor->getReplacedValue('pruef_vorleistung')) ?>
+ </td>
+ <td data-mvv-field="mvv_modulteil_deskriptor.pruef_leistung">
+ <?= formatReady($modulteil_deskriptor->getReplacedValue('pruef_leistung')) ?>
+ </td>
+ </tr>
<? endforeach; ?>
- <tr data-mvv-id="<?= $modul->getId(); ?>" data-mvv-type="modul">
- <? $modulDeskriptor = $modul->getDeskriptor($display_language) ?>
+ <tr data-mvv-id="<?= $modul->id; ?>" data-mvv-type="modul">
+ <? $deskriptor = $modul->getDeskriptor() ?>
<td style="vertical-align: top; font-weight: bold;">
<?= _('Gesamtmodul') ?>
</td>
- <td data-mvv-field="mvv_modul_deskriptor.pruef_vorleistung"><?= formatReady($modulDeskriptor->pruef_vorleistung) ?></td>
- <td data-mvv-field="mvv_modul_deskriptor.pruef_leistung"><?= formatReady($modulDeskriptor->pruef_leistung) ?></td>
+ <td data-mvv-field="mvv_modul_deskriptor.pruef_vorleistung">
+ <?= formatReady($deskriptor->getReplacedValue('pruef_vorleistung')) ?>
+ </td>
+ <td data-mvv-field="mvv_modul_deskriptor.pruef_leistung">
+ <?= formatReady($deskriptor->getReplacedValue('pruef_leistung')) ?>
+ </td>
</tr>
<tr>
<td style="vertical-align: top; font-weight: bold;">
<?= _('Wiederholungsprüfung') ?>
</td>
<td colspan="3">
- <?= formatReady($modulDeskriptor->pruef_wiederholung) ?>
+ <?= formatReady($deskriptor->getReplacedValue('pruef_wiederholung')) ?>
</td>
</tr>
</tbody>
diff --git a/app/views/shared/modul/_regularien.php b/app/views/shared/modul/_regularien.php
index 26196b0..0589d0c 100644
--- a/app/views/shared/modul/_regularien.php
+++ b/app/views/shared/modul/_regularien.php
@@ -1,3 +1,8 @@
+<?php
+/**
+ * @var Modul $modul
+ */
+?>
<table class="mvv-modul-details default nohover">
<thead>
<tr>
@@ -9,16 +14,16 @@
</tr>
</thead>
<tbody>
- <? foreach ($modul->modulteile as $modulTeil): ?>
+ <? foreach ($modul->modulteile as $modulteil): ?>
<?
- $modulTeilDeskriptor = $modulTeil->getDeskriptor($display_language);
+ $modulteil_deskriptor = $modulteil->getDeskriptor();
// Für die Kenntlichmachung der Modulteile in Listen die Nummer des
// Modulteils und den ausgewählten Namen verwenden.
// Ist keine Nummer vorhanden, dann Durchnummerieren und Standard-
// Bezeichnung verwenden.
- if (trim($modulTeil->nummer)) {
- $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulTeil->num_bezeichnung]['name'];
- $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulTeil->nummer);
+ if (trim($modulteil->nummer)) {
+ $num_bezeichnung = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$modulteil->num_bezeichnung]['name'];
+ $name_kurz = sprintf('%s %d', $num_bezeichnung, $modulteil->nummer);
} else {
$num_bezeichnung_default = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['default'];
$name_kurz = $GLOBALS['MVV_MODULTEIL']['NUM_BEZEICHNUNG']['values'][$num_bezeichnung_default]['name']
@@ -26,13 +31,20 @@
$nummer_modulteil++;
}
?>
- <tr data-mvv-id="<?= $modulTeil->getId(); ?>" data-mvv-type="modulteil">
+ <tr data-mvv-id="<?= $modulteil->id; ?>" data-mvv-type="modulteil">
<td style="vertical-align: top; font-weight: bold;" data-mvv-field="mvv_modulteil.nummer mvv_modulteil.num_bezeichnung"><?= $name_kurz ?></td>
- <td data-mvv-field="mvv_modulteil_deskriptor.voraussetzung"><?= formatReady($modulTeilDeskriptor->voraussetzung) ?></td>
- <td data-mvv-field="mvv_modulteil.semester"><?= $GLOBALS['MVV_NAME_SEMESTER']['values'][$modulTeil->semester]['name'] ?></td>
- <td data-mvv-field="mvv_modulteil.pflicht"><?= ($modulTeil->pflicht ? _('Ja') : _('Nein')) ?> <?= $modulTeilDeskriptor->kommentar_pflicht ? formatReady($modulTeilDeskriptor->kommentar_pflicht) : '' ?></td>
- <td data-mvv-field="mvv_modulteil.anteil_note"><?= $modulTeil->anteil_note ?>%</td>
- </tr>
+ <td data-mvv-field="mvv_modulteil_deskriptor.voraussetzung">
+ <?= formatReady($modulteil_deskriptor->getReplacedValue('voraussetzung')) ?>
+ </td>
+ <td data-mvv-field="mvv_modulteil.semester">
+ <?= $GLOBALS['MVV_NAME_SEMESTER']['values'][$modulteil->semester]['name'] ?>
+ </td>
+ <td data-mvv-field="mvv_modulteil.pflicht">
+ <?= ($modulteil->pflicht ? _('Ja') : _('Nein')) ?>
+ <?= formatReady($modulteil_deskriptor->getReplacedValue('kommentar_pflicht')) ?>
+ </td>
+ <td data-mvv-field="mvv_modulteil.anteil_note"><?= $modulteil->anteil_note ?>%</td>
+ </tr>
<? endforeach; ?>
</tbody>
-</table> \ No newline at end of file
+</table>
diff --git a/app/views/shared/modul/description.php b/app/views/shared/modul/description.php
index 758760d..05eddbf 100644
--- a/app/views/shared/modul/description.php
+++ b/app/views/shared/modul/description.php
@@ -3,6 +3,7 @@
* @var Modul $modul
* @var int $type
* @var Shared_ModulController $controller
+ * @var StgteilabschnittModul|null $abschnitt_modul
*/
?>
@@ -10,7 +11,12 @@
<div style="width: 100%; text-align: right;">
<? foreach ($modul->deskriptoren->getAvailableTranslations($modul->original_language) as $language) : ?>
<? $lang = $GLOBALS['CONTENT_LANGUAGES'][$language]; ?>
- <a data-dialog="size=auto;title='<?= htmlReady($modul->getDisplayName()) ?>'" href="<?= $controller->action_link('description/' . $modul->id . '/', ['display_language' => $language]) ?>">
+ <a data-dialog="size=auto;title='<?= htmlReady($modul->getDisplayName()) ?>'"
+ href="<?= $controller->action_link('description/' . $modul->id . '/',
+ [
+ 'display_language' => $language,
+ 'abschnitt_id' => $abschnitt_modul->abschnitt_id,
+ ]) ?>">
<?= Assets::img(MVV::getContentLanguageImagePath($language), ['alt' => $lang['name'], 'size' => 24]) ?>
</a>
<? endforeach; ?>
diff --git a/app/views/shared/modul/overview.php b/app/views/shared/modul/overview.php
index be91c7a..16695bd 100644
--- a/app/views/shared/modul/overview.php
+++ b/app/views/shared/modul/overview.php
@@ -1,26 +1,32 @@
<?php
/**
* @var Modul $modul
- * @var Institute $institut
- * @var ModulDeskriptor $deskriptor
- * @var array $modulteile
* @var Semester $semester
* @var string $pruef_ebene
* @var int $type
+ * @var string $code
+ * @var string $title
*/
?>
+<? $deskriptor = $modul->getDeskriptor() ?>
<table class="default mvv-modul-details nohover">
<tr>
- <th class="mvv-modul-details-head" style="width: 30%"><?= htmlReady($modul->code) ?></th>
- <th class="mvv-modul-details-head" style="width: 30%"><?= htmlReady($institut->name) ?></th>
- <th class="mvv-modul-details-head" style="width: 40%"><?= sprintf("%d CP", $modul->kp) ?> </th>
- <th class="mvv-modul-details-head"></th>
+ <th class="mvv-modul-details-head" style="width: 30%">
+ <?= htmlReady($code ?: $modul->code) ?>
+ </th>
+ <th class="mvv-modul-details-head" style="width: 30%">
+ <?= $modul->responsible_institute ? htmlReady($modul->responsible_institute->institute->name) : '' ?>
+ </th>
+ <th class="mvv-modul-details-head" style="width: 40%"></th>
+ <th class="mvv-modul-details-head" style="white-space: nowrap;">
+ <?= sprintf("%d CP", $modul->getReplacedValue('kp')) ?>
+ </th>
</tr>
<tr>
<td colspan="2">
- <h3><?= htmlReady($deskriptor->bezeichnung) ?></h3>
- <?= _('Lehrveranstaltungen') ?> <?= htmlReady($semester['name']) ?>
+ <h3><?= htmlReady($title ?: $deskriptor->bezeichnung) ?></h3>
+ <?= _('Lehrveranstaltungen') ?> <?= htmlReady($semester->name) ?>
</td>
<td>
<dl>
@@ -37,8 +43,8 @@
</td>
<td>
<? if ($GLOBALS['perm']->have_perm('admin')) : ?>
- <a href="<?= URLHelper::getLink("dispatch.php/shared/modul/mail/{$modul->id}/{$semester['semester_id']}")?>" data-dialog>
- <?= Icon::create('mail', Icon::ROLE_CLICKABLE, tooltip2(_('Nachricht an alle Veranstaltungteilnehmer die diesem Modul zugeordnet sind.')))?>
+ <a href="<?= URLHelper::getLink("dispatch.php/shared/modul/mail/{$modul->id}/{$semester->id}")?>" data-dialog>
+ <?= Icon::create('mail', Icon::ROLE_CLICKABLE, tooltip2(_('Nachricht an alle Teilnehmenden der Veranstaltungen, die diesem Modul zugeordnet sind.')))?>
</a>
<? endif; ?>
</td>
@@ -46,22 +52,22 @@
<tr>
<td colspan="4" style="padding: 0;">
<table class="default nohover">
- <? if (mb_strlen($deskriptor->voraussetzung) > 0): ?>
+ <? if (mb_strlen($deskriptor->getReplacedValue('voraussetzung')) > 0): ?>
<tr>
<td style="width: 20%; font-weight: bold;"><?= _('Teilnahmevoraussetzungen') ?></td>
- <td ><?= formatReady($deskriptor->voraussetzung) ?></td>
+ <td ><?= formatReady($deskriptor->getReplacedValue('voraussetzung')) ?></td>
</tr>
<? endif; ?>
- <? if (mb_strlen($deskriptor->kommentar)) : ?>
+ <? if (mb_strlen($deskriptor->getReplacedValue('kommentar'))) : ?>
<tr>
<td style="width: 20%; font-weight: bold;"><?= _('Hinweise') ?></td>
- <td><?= formatReady($deskriptor->kommentar) ?></td>
+ <td><?= formatReady($deskriptor->getReplacedValue('kommentar')) ?></td>
</tr>
<? endif; ?>
<? if (mb_strlen($deskriptor->ersatztext) > 0): ?>
<tr>
<td style="width: 20%; font-weight: bold;"> </td>
- <td><?= formatReady($deskriptor->ersatztext) ?></td>
+ <td><?= formatReady($deskriptor->getReplacedValue('ersatztext')) ?></td>
</tr>
<? else: ?>
@@ -70,8 +76,8 @@
<td style="width: 20%; font-weight: bold;"><?= _('Kapazität Modul') ?></td>
<td>
<?= htmlReady($modul->kapazitaet) ?>
- <? if (mb_strlen($deskriptor->kommentar_kapazitaet) > 0): ?>
- (<?= formatReady($deskriptor->kommentar_kapazitaet) ?>)
+ <? if (mb_strlen($deskriptor->getReplacedValue('kommentar_kapazitaet')) > 0): ?>
+ (<?= formatReady($deskriptor->getReplacedValue('kommentar_kapazitaet')) ?>)
<? endif; ?>
</td>
@@ -83,22 +89,22 @@
<td><?= htmlReady($pruef_ebene) ?></td>
</tr>
<? endif; ?>
- <? if (mb_strlen($deskriptor->pruef_vorleistung)) : ?>
+ <? if (mb_strlen($deskriptor->getReplacedValue('pruef_vorleistung'))) : ?>
<tr>
<td style="width: 20%; font-weight: bold;"><?= _('Prüfungsvorleistung Modul') ?></td>
- <td><?= formatReady($deskriptor->pruef_vorleistung) ?></td>
+ <td><?= formatReady($deskriptor->getReplacedValue('pruef_vorleistung')) ?></td>
</tr>
<? endif; ?>
<? if (mb_strlen($deskriptor->pruef_leistung)) : ?>
<tr>
<td style="width: 20%; font-weight: bold;"><?= _('Prüfungsleistung Modul') ?></td>
- <td><?= formatReady($deskriptor->pruef_leistung) ?></td>
+ <td><?= formatReady($deskriptor->getReplacedValue('pruef_leistung')) ?></td>
</tr>
<? endif; ?>
<? if (mb_strlen($deskriptor->kompetenzziele)): ?>
<tr>
<td style="width: 20%; font-weight: bold;"><?= _('Kompetenzziele') ?></td>
- <td><?= formatReady($deskriptor->kompetenzziele) ?></td>
+ <td><?= formatReady($deskriptor->getReplacedValue('kompetenzziele')) ?></td>
</tr>
<? endif; ?>
@@ -111,66 +117,62 @@
<? if ($type === 1): ?>
<th><?= _('Modulteile') ?></th>
<? endif; ?>
- <th <? if ($type === 2): ?> colspan="3" <? endif; ?> ><?= _('Semesterveranstaltungen') ?></th>
+ <th <? if ($type === 2): ?> colspan="4" <? endif; ?> ><?= _('Semesterveranstaltungen') ?></th>
<? if ($type === 1): ?>
- <th><?= _('Prüfungsleistung') ?></th>
+ <th colspan="2"><?= _('Prüfungsleistung') ?></th>
<? endif; ?>
</tr>
- <? foreach ($modulteile as $modul_teil): ?>
+ <? foreach ($modul->modulteile as $modulteil): ?>
+ <? $modulteil_deskriptor = $modulteil->getDeskriptor() ?>
<tr>
<? if ($type === 1): ?>
<td>
- <b> <?= htmlReady($modul_teil['name']) ?> </b>
- <? if (mb_strlen($modul_teil['kommentar']) > 0): ?>
- <?= $modul_teil['kommentar'] ? '<br>(' . formatReady($modul_teil['kommentar']) . ')' : '' ?>
+ <b> <?= htmlReady($modulteil_deskriptor->getReplacedValue('bezeichnung')) ?> </b>
+ <? if (mb_strlen($modulteil_deskriptor->getReplacedValue('kommentar')) > 0): ?>
+ <?= trim($modulteil_deskriptor->getReplacedValue('kommentar')) ? '<br>(' . formatReady($modulteil_deskriptor->getReplacedValue('kommentar')) . ')' : '' ?>
<? endif; ?>
- <? if (mb_strlen($modul_teil['voraussetzung']) > 0): ?>
+ <? if (mb_strlen($modulteil_deskriptor->getReplacedValue('voraussetzung')) > 0): ?>
<br>
- <b><?= _('Teilnahmevoraussetzungen') ?>:</b> <?= formatReady($modul_teil['voraussetzung']) ?>
+ <b><?= _('Teilnahmevoraussetzungen') ?>:</b> <?= formatReady($modulteil_deskriptor->getReplacedValue('voraussetzung')) ?>
<? endif; ?>
</td>
<? endif; ?>
<td <? if ($type === 2): ?> colspan="3" <? endif; ?>>
- <? foreach ($modul_teil['lvGruppen'] as $gruppe): ?>
- <? if (mb_strlen($gruppe['alt_texte']) > 0): ?>
- <?= formatReady($gruppe['alt_texte']) ?>
+ <? foreach ($modulteil->lvgruppen as $gruppe): ?>
+ <? if (mb_strlen($gruppe->alttext) > 0): ?>
+ <?= formatReady($gruppe->alttext) ?>
<? endif; ?>
- <? if (count($gruppe['courses'])) : ?>
+ <? if (count($gruppe->courses)) : ?>
<ul>
- <? foreach ($gruppe['courses'] as $course): ?>
+ <? foreach ($gruppe->courses as $course): ?>
<li>
<a href="<?= URLHelper::getLink('dispatch.php/course/details', ['sem_id' => $course->id]) ?>">
- <?= htmlReady(($course['VeranstaltungsNummer'] ? $course['VeranstaltungsNummer'] . ' - ' : '') . $course['Name']) ?>
+ <?= htmlReady(($course->veranstaltungsnummer ? $course->veranstaltungsnummer . ' - ' : '') . $course->name) ?>
</a>
- <? if ($course['visible'] != 1) : ?>
+ <? if (!$course->visible) : ?>
<em><?= _('[versteckt]') ?></em>
<? endif; ?>
<? if (Config::get()->COURSE_SEARCH_SHOW_ADMISSION_STATE) : ?>
<?
$admission_status = GlobalSearchCourses::getStatusCourseAdmission($course->id, $course->admission_prelim);
?>
- <? switch ($admission_status) :
- case 1:
- echo Icon::create('span-2quarter', Icon::ROLE_STATUS_YELLOW, [
- 'alt' => _('Eingeschränkter Zugang'),
- 'title' => _('Eingeschränkter Zugang'),
- 'style' => 'vertical-align: text-bottom',
- ]);
- break;
- case 2:
- echo Icon::create('span-empty', Icon::ROLE_STATUS_RED, [
- 'alt' => _('Kein Zugang'),
- 'title' => _('Kein Zugang'),
- 'style' => 'vertical-align: text-bottom',
- ]);
- break;
- default:
- echo Icon::create('span-full', Icon::ROLE_STATUS_GREEN, [
- 'alt' => _('Uneingeschränkter Zugang'),
- 'title' => _('Uneingeschränkter Zugang'),
- 'style' => 'vertical-align: text-bottom',
- ]);
- endswitch; ?>
+ <? echo match ($admission_status) {
+ 1 => Icon::create('span-2quarter', Icon::ROLE_STATUS_YELLOW, [
+ 'alt' => _('Eingeschränkter Zugang'),
+ 'title' => _('Eingeschränkter Zugang'),
+ 'style' => 'vertical-align: text-bottom',
+ ]),
+ 2 => Icon::create('span-empty', Icon::ROLE_STATUS_RED, [
+ 'alt' => _('Kein Zugang'),
+ 'title' => _('Kein Zugang'),
+ 'style' => 'vertical-align: text-bottom',
+ ]),
+ default => Icon::create('span-full', Icon::ROLE_STATUS_GREEN, [
+ 'alt' => _('Uneingeschränkter Zugang'),
+ 'title' => _('Uneingeschränkter Zugang'),
+ 'style' => 'vertical-align: text-bottom',
+ ]),
+ }; ?>
<? endif; ?>
</li>
<? endforeach; ?>
@@ -179,13 +181,13 @@
<? endforeach; ?>
</td>
<? if ($type === 1) : ?>
- <td>
- <? if (mb_strlen($modul_teil['pruef_vorleistung']) > 0) : ?>
- <b><?= _('Prüfungsvorleistung') ?>:</b> <?= htmlReady($modul_teil['pruef_vorleistung']) ?>
+ <td colspan="2">
+ <? if (mb_strlen($modulteil_deskriptor->getReplacedValue('pruef_vorleistung')) > 0) : ?>
+ <b><?= _('Prüfungsvorleistung') ?>:</b> <?= htmlReady($modulteil_deskriptor->getReplacedValue('pruef_vorleistung')) ?>
<? endif; ?>
- <? if (mb_strlen($modul_teil['pruef_leistung']) > 0) : ?>
- <b><?= _('Prüfungsform') ?>:</b> <br/><?= htmlReady($modul_teil['pruef_leistung']) ?> (<?= ($modul_teil['anteil_note'] ? '(' . htmlReady($modul_teil['anteil_note']) . '%)' : '') ?>
+ <? if (mb_strlen($modulteil_deskriptor->pruef_leistung) > 0) : ?>
+ <b><?= _('Prüfungsform') ?>:</b> <br/><?= htmlReady($modulteil_deskriptor->getReplacedValue('pruef_leistung')) ?> (<?= ($modulteil->anteil_note ? '(' . htmlReady($modulteil->anteil_note) . '%)' : '') ?>
<? endif; ?>
</td>
<? endif; ?>
diff --git a/app/views/studiengaenge/studiengaenge/stgteil_bezeichnungen.php b/app/views/studiengaenge/studiengaenge/stgteil_bezeichnungen.php
index cd4cd77..a58d09c 100644
--- a/app/views/studiengaenge/studiengaenge/stgteil_bezeichnungen.php
+++ b/app/views/studiengaenge/studiengaenge/stgteil_bezeichnungen.php
@@ -54,7 +54,7 @@
'name' => 'search_stgteil', 'data-qs_name' => $search_stgteil->getId(),
'data-qs_id' => $qs_search_stgteil_id,
'data-qs_submit' => 'no',
- 'class' => 'mvv-qs-button'
+ 'class' => 'middle mvv-qs-button'
])->asInput(); ?>
</div>
<label><?= _('als') ?>
@@ -66,7 +66,7 @@
</select>
</label>
<input type="hidden" name="level" value="stg">
- <input name="add_stgteil" class="text-top mvv-submit" type="image"
+ <input name="add_stgteil" class="middle mvv-submit" type="image"
title="<?= _('Studiengangteil hinzufügen') ?>"
src="<?= Icon::create('accept')->asImagePath(); ?>">
</form>
diff --git a/app/views/studiengaenge/studiengaenge/studiengaenge.php b/app/views/studiengaenge/studiengaenge/studiengaenge.php
index cbfc2cc..0aafb2a 100644
--- a/app/views/studiengaenge/studiengaenge/studiengaenge.php
+++ b/app/views/studiengaenge/studiengaenge/studiengaenge.php
@@ -22,7 +22,7 @@
<? $ampel_icon = $GLOBALS['MVV_STUDIENGANG']['STATUS']['values'][$studiengang->stat]['icon'] ?? null; ?>
<? $ampelstatus = $GLOBALS['MVV_STUDIENGANG']['STATUS']['values'][$studiengang->stat]['name'] ?? null; ?>
<? if ($ampel_icon) : ?>
- <?= $ampel_icon->asImg(['title' => $ampelstatus, 'style' => 'vertical-align: text-top;']) ?>
+ <?= $ampel_icon->asImg(['title' => $ampelstatus]) ?>
<? endif; ?>
<?= htmlReady($studiengang->name) ?> <?= (mb_strlen($studiengang->name_kurz) ? '(' . htmlReady($studiengang->name_kurz) . ')' : '') ?>
<? if ($studiengang->count_dokumente) : ?>
@@ -33,8 +33,7 @@
'title' => sprintf(
ngettext('%s Dokument zugeordnet', '%s Dokumente zugeordnet', $studiengang->count_dokumente),
$studiengang->count_dokumente
- ),
- 'style' => 'vertical-align: text-top;'
+ )
]) ?>
<? endif; ?>
</a>
diff --git a/app/views/studiengaenge/studiengaenge/studiengangteile.php b/app/views/studiengaenge/studiengaenge/studiengangteile.php
index 7c3cf92..8efd302 100644
--- a/app/views/studiengaenge/studiengaenge/studiengangteile.php
+++ b/app/views/studiengaenge/studiengaenge/studiengangteile.php
@@ -76,13 +76,14 @@
'data-qs_name' => $search->getId(),
'data-qs_id' => $qs_search_id,
'data-qs_submit' => '1',
- 'class' => 'mvv-qs-button'
+ 'class' => 'middle mvv-qs-button'
])->asInput(); ?>
<?= Icon::create(
'accept',
Icon::ROLE_CLICKABLE ,
[
- 'title' => _('Studiengangteil zuordnen')
+ 'title' => _('Studiengangteil zuordnen'),
+ 'class' => 'middle'
])->asInput(['class' => 'mvv-submit', 'name' => 'add_stgteil']); ?>
<? if ($stg_bez) : ?>
<input type="hidden" name="stgteil_bez_id" value="<?= $stg_bez->id ?>">
diff --git a/app/views/studiengaenge/versionen/abschnitte.php b/app/views/studiengaenge/versionen/abschnitte.php
index 79d3b5a..2d555c7 100644
--- a/app/views/studiengaenge/versionen/abschnitte.php
+++ b/app/views/studiengaenge/versionen/abschnitte.php
@@ -76,7 +76,7 @@
'data-qs_name' => $search_modul_version->getId(),
'data-qs_id' => $qs_search_modul_version_id,
'data-qs_submit' => 'no',
- 'class' => 'mvv-qs-button'
+ 'class' => 'middle mvv-qs-button'
]) ?>
<label>
<?= _('zu Abschnitt') ?>
@@ -86,7 +86,7 @@
<? endforeach; ?>
</select>
</label>
- <input name="add_modul" class="text-top mvv-submit" type="image"
+ <input name="add_modul" class="middle mvv-submit" type="image"
title="<?= _('Studiengangteil-Abschnitt hinzufügen') ?>"
src="<?= Icon::create('accept')->asImagePath(); ?>">
</form>
diff --git a/app/views/studiengaenge/versionen/details_abschnitt.php b/app/views/studiengaenge/versionen/details_abschnitt.php
index ed2f293..63abfee 100644
--- a/app/views/studiengaenge/versionen/details_abschnitt.php
+++ b/app/views/studiengaenge/versionen/details_abschnitt.php
@@ -39,6 +39,9 @@
<?= Icon::create('edit', Icon::ROLE_CLICKABLE , tooltip2(_('Modulzuordnung bearbeiten')))->asImg(); ?>
</a>
<? endif; ?>
+ <a data-dialog="size=auto" href="<?= $controller->link_for('module/module/description', $assignment->modul_id, ['abschnitt_id' => $assignment->abschnitt_id]) ?>">
+ <?= Icon::create('log', Icon::ROLE_CLICKABLE, tooltip2(_('Lokale Modulbeschreibung')))->asImg(); ?>
+ </a>
<? if (MvvPerm::havePermCreate($assignment)) : ?>
<?= Icon::create('trash', Icon::ROLE_CLICKABLE , tooltip2(_('Modulzuordnung löschen')))
->asInput([
@@ -55,7 +58,11 @@
</tr>
<? if (!empty($modul_id) && ($modul_id == $assignment->modul->id)) : ?>
<tr class="loaded-details nohover">
- <?= $this->render_partial('studiengaenge/versionen/modulteile', ['modul' => $assignment->modul, 'abschnitt_id' => $assignment->abschnitt_id, 'assignment' => $assignment]) ?>
+ <?= $this->render_partial('studiengaenge/versionen/modulteile',
+ [
+ 'modul' => $assignment->modul,
+ 'abschnitt_id' => $assignment->abschnitt_id,
+ 'assignment' => $assignment]) ?>
</tr>
<? endif; ?>
</tbody>
@@ -67,14 +74,23 @@
<?= _('Modul hinzufügen') ?>
<?= CSRFProtection::tokenTag() ?>
<?= $search_modul_abschnitt->render(); ?>
- <?= Icon::create('search', Icon::ROLE_CLICKABLE, ['title' => _('Modul suchen'), 'name' => 'search_stgteil', 'data-qs_name' => $search_modul_abschnitt->getId(), 'data-qs_id' => $qs_search_modul_abschnitt_id, 'data-qs_submit' => 'no', 'class' => 'mvv-qs-button'])->asInput(); ?>
+ <?= Icon::create('search', Icon::ROLE_CLICKABLE,
+ [
+ 'title' => _('Modul suchen'),
+ 'name' => 'search_stgteil',
+ 'data-qs_name' => $search_modul_abschnitt->getId(),
+ 'data-qs_id' => $qs_search_modul_abschnitt_id,
+ 'data-qs_submit' => 'no',
+ 'class' => 'middle mvv-qs-button'
+ ]
+ )->asInput(); ?>
<input type="hidden" name="abschnitt_id" value="<?= $abschnitt->id ?>">
<?= Icon::create('accept', Icon::ROLE_CLICKABLE , tooltip2(_('Modul hinzufügen')))
->asInput(
[
'formaction' => $controller->action_url('add_modul', $version->id),
'name' => 'add_modul',
- 'class' => 'text-top mvv-submit'
+ 'class' => 'middle mvv-submit'
]
); ?>
</td>
diff --git a/app/views/studiengaenge/versionen/modul_zuordnung.php b/app/views/studiengaenge/versionen/modul_zuordnung.php
index c2ea20b..bfc4f48 100644
--- a/app/views/studiengaenge/versionen/modul_zuordnung.php
+++ b/app/views/studiengaenge/versionen/modul_zuordnung.php
@@ -6,7 +6,7 @@
use Studip\Button, Studip\LinkButton;
?>
<? $perm = new MvvPerm($zuordnung) ?>
-<form class="default" action="<?= $controller->action_link('modul_zuordnung/' . $zuordnung->id) ?>" method="post">
+<form data-dialog="" class="default" action="<?= $controller->action_link('modul_zuordnung_store/' . $zuordnung->id) ?>" method="post">
<?= CSRFProtection::tokenTag() ?>
<fieldset>
<legend><?= _('Grunddaten') ?></legend>
@@ -32,6 +32,21 @@ use Studip\Button, Studip\LinkButton;
maxlength="250" value="<?= htmlReady($zuordnung->modulcode) ?>">
</label>
</fieldset>
+ <? if (count($zuordnung->datafields)) : ?>
+ <fieldset>
+ <legend><?= _('Angaben zum Modul am Studiengangteilabschnitt') ?></legend>
+ <? $default_language = array_keys($GLOBALS['CONTENT_LANGUAGES'])[0] ?>
+ <? foreach ($zuordnung->datafields as $entry) : ?>
+ <? $tdf = $entry->getTypedDatafield(); ?>
+ <? if ($perm->haveDfEntryPerm($entry->datafield_id, MvvPerm::PERM_WRITE)) : ?>
+ <?= $tdf->getHTML('datafields') ?>
+ <? else : ?>
+ <em><?= htmlReady($tdf->getName()) ?>:</em><br>
+ <?= $tdf->getDisplayValue() ?>
+ <? endif; ?>
+ <? endforeach; ?>
+ </fieldset>
+ <? endif; ?>
<footer data-dialog-button>
<?= Button::createAccept(
_('Übernehmen'),
diff --git a/app/views/studiengaenge/versionen/modulteil_semester.php b/app/views/studiengaenge/versionen/modulteil_semester.php
index 86648f5..383b76c 100644
--- a/app/views/studiengaenge/versionen/modulteil_semester.php
+++ b/app/views/studiengaenge/versionen/modulteil_semester.php
@@ -2,21 +2,19 @@
/**
* @var Studiengaenge_VersionenController $controller
* @var StgteilabschnittModul $abschnitt_modul
+ * @var Modulteil $modulteil
+ * @var ModulteilStgteilabschnitt $assignment
*/
use Studip\Button, Studip\LinkButton;
$perm_abschnitt = MvvPerm::getFieldPermModulteil_abschnitte($abschnitt_modul->abschnitt);
?>
-
-<h3>
- <?= _('Zuordnung der Modulteile zu Fachsemestern') ?>
-</h3>
<form class="default" data-dialog="" action="<?= $controller->action_link('modulteil_semester', $abschnitt_modul->id, $modulteil->id) ?>" method="post">
<?= CSRFProtection::tokenTag() ?>
- <fieldset>
+ <? $perm = MvvPerm::get($assignment) ?>
+ <fieldset class="collapsable">
<legend><?= _('Belegung in folgenden Fachsemestern') ?></legend>
<? for ($i = 1; $i <= $GLOBALS['MVV_MODULTEIL_FACHSEMESTER']; $i++) : ?>
<? $fachsemester = $abschnitt_modul->getFachsemester($modulteil->id, $i) ?>
- <? $perm = $fachsemester ? MvvPerm::get($fachsemester) : null ?>
<div class="mvv-fachsemester" style="flex:1;">
<label>
<? if ($fachsemester) : ?>
@@ -39,21 +37,31 @@ $perm_abschnitt = MvvPerm::getFieldPermModulteil_abschnitte($abschnitt_modul->ab
<?= $GLOBALS['MVV_MODULTEIL_STGABSCHNITT']['STATUS']['values'][$fachsemester->differenzierung]['name'] ?>
<input type="hidden" name="status[<?= $i ?>]" value="<?= $fachsemester->differenzierung ?>">
<? else: ?>
- <select name="status[<?= $i ?>]">
- <option value="">-- <?= _('Bitte wählen') ?> --</option>
- <? foreach ($GLOBALS['MVV_MODULTEIL_STGABSCHNITT']['STATUS']['values'] as $status_key => $status) : ?>
- <? if ($status['visible']) : ?>
- <option value="<?= $status_key ?>"<?= ($fachsemester && $fachsemester->differenzierung == $status_key ? ' selected' : '') ?>><?= $status['name'] ?></option>
- <? endif; ?>
- <? endforeach; ?>
- </select>
-
-
+ <select name="status[<?= $i ?>]">
+ <option value="">-- <?= _('Bitte wählen') ?> --</option>
+ <? foreach ($GLOBALS['MVV_MODULTEIL_STGABSCHNITT']['STATUS']['values'] as $status_key => $status) : ?>
+ <? if ($status['visible']) : ?>
+ <option value="<?= $status_key ?>"<?= ($fachsemester && $fachsemester->differenzierung == $status_key ? ' selected' : '') ?>><?= $status['name'] ?></option>
+ <? endif; ?>
+ <? endforeach; ?>
+ </select>
<? endif; ?>
</label>
</div>
<? endfor; ?>
</fieldset>
+ <fieldset class="collapsable">
+ <legend><?= _('Angaben zum Modulteil am Studiengangteilabschnitt') ?></legend>
+ <? foreach ($assignment->datafields as $entry) : ?>
+ <? $tdf = $entry->getTypedDatafield(); ?>
+ <? if ($perm->haveDfEntryPerm($entry->datafield_id, MvvPerm::PERM_WRITE)) : ?>
+ <?= $tdf->getHTML('datafields') ?>
+ <? else : ?>
+ <em><?= htmlReady($tdf->getName()) ?>:</em><br>
+ <?= $tdf->getDisplayValue() ?>
+ <? endif; ?>
+ <? endforeach; ?>
+ </fieldset>
<div data-dialog-button >
<? if ($perm_abschnitt >= MvvPerm::PERM_WRITE) : ?>
<?= Button::createAccept(_('Übernehmen'), 'store', ['title' => _('Änderungen übernehmen')]) ?>
diff --git a/app/views/studiengaenge/versionen/versionen.php b/app/views/studiengaenge/versionen/versionen.php
index aff5d5f..27a75ae 100644
--- a/app/views/studiengaenge/versionen/versionen.php
+++ b/app/views/studiengaenge/versionen/versionen.php
@@ -9,7 +9,7 @@
<? $ampel_icon = $GLOBALS['MVV_STGTEILVERSION']['STATUS']['values'][$version->stat]['icon'] ?>
<? $ampelstatus = $GLOBALS['MVV_STGTEILVERSION']['STATUS']['values'][$version->stat]['name'] ?>
<? if ($ampel_icon) : ?>
- <?= $ampel_icon->asImg(['title' => $ampelstatus, 'style' => 'vertical-align: text-top;']) ?>
+ <?= $ampel_icon->asImg(['title' => $ampelstatus]) ?>
<? endif; ?>
<?= htmlReady($version->getDisplayName()) ?>
<? if ($version->count_abschnitte) : ?>
diff --git a/db/migrations/6.0.51_step5383_new_data_field_types_for_mvv.php b/db/migrations/6.0.51_step5383_new_data_field_types_for_mvv.php
new file mode 100644
index 0000000..537b71c
--- /dev/null
+++ b/db/migrations/6.0.51_step5383_new_data_field_types_for_mvv.php
@@ -0,0 +1,29 @@
+<?php
+final class Step5383NewDataFieldTypesForMvv extends Migration
+{
+ public function description()
+ {
+ return 'Adds new data field types related to StgteilAbschnitModul and ModulteilStgteilAbschnitt objects';
+ }
+
+ public function up()
+ {
+ $query = "ALTER TABLE `datafields`
+ CHANGE `object_type` `object_type` ENUM('sem','inst','user',
+ 'userinstrole','usersemdata','roleinstdata','moduldeskriptor',
+ 'modulteildeskriptor','studycourse',
+ 'stgteilabschnittmodul','modulteilstgteilabschnitt')
+ NULL DEFAULT NULL";
+ DBManager::get()->exec($query);
+ }
+
+ public function down()
+ {
+ $query = "ALTER TABLE `datafields`
+ CHANGE `object_type` `object_type` ENUM('sem','inst','user',
+ 'userinstrole','usersemdata','roleinstdata','moduldeskriptor',
+ 'modulteildeskriptor','studycourse')
+ NULL DEFAULT NULL";
+ DBManager::get()->exec($query);
+ }
+}
diff --git a/lib/classes/I18NStringDatafield.php b/lib/classes/I18NStringDatafield.php
index 6007872..942064d 100644
--- a/lib/classes/I18NStringDatafield.php
+++ b/lib/classes/I18NStringDatafield.php
@@ -77,7 +77,7 @@ class I18NStringDatafield extends I18NString
/**
* Returns an I18NString object by given object_id, table and field.
*
- * @param string $object_id The id of the object with i18n fields.
+ * @param string|array $object_id The id of the object with i18n fields.
* @param string $table The name of the table with the original values.
* @param string $field The name of the i18n field.
* @param string $base Sets the original value or retrieve it from database
diff --git a/lib/classes/MvvReplaceDataFieldsTrait.php b/lib/classes/MvvReplaceDataFieldsTrait.php
new file mode 100644
index 0000000..fe0d5e6
--- /dev/null
+++ b/lib/classes/MvvReplaceDataFieldsTrait.php
@@ -0,0 +1,90 @@
+<?php
+trait MvvReplaceDataFieldsTrait
+{
+ /**
+ * The id of the section (Studiengangteil-Abschnitt) with replaced or
+ * added fields (defined as data fields) in all related objects.
+ *
+ * @var string|null $replace_df_abschnitt_id
+ */
+ private string|null $replace_df_abschnitt_id = null;
+
+ /**
+ * Set the section (Studiengangteil-Abschnitt) with replaced or
+ * added fields (defined as data fields) for all related objects.
+ *
+ * @param Stgteilabschnitt $abschnitt The section.
+ * @return int The number of objects related to the given section.
+ */
+ public function setReplaceDfAbschnitt(Stgteilabschnitt $abschnitt): int
+ {
+ $this->replace_df_abschnitt_id = $abschnitt->id;
+ return 1;
+ }
+
+ /**
+ * Returns the replaced value for the given field and section id.
+ *
+ * @param string $field
+ * @param string|null $abschnitt_id
+ * @return string
+ */
+ public function getReplacedValue(
+ string $field,
+ string $abschnitt_id = null
+ ): string
+ {
+ $abschnitt_id = $abschnitt_id ?? $this->replace_df_abschnitt_id;
+ if (is_null($abschnitt_id)) {
+ return $this->getValue($field) ?? '';
+ }
+
+ if (!in_array($field, array_keys(static::db_fields()))) {
+ throw new InvalidArgumentException(static::class . '::' . $field . ' not found.');
+ }
+ // find data field that replaces the given local field
+ $data_field_id = static::getReplaceDataFieldsId($field, $this->abschnitt_assignments->getClassName());
+ if ($data_field_id) {
+ $abschnitt = $this->abschnitt_assignments->findOneBy('abschnitt_id', $abschnitt_id);
+ if (!$abschnitt) {
+ return $this->getValue($field) ?? '';
+ }
+ $data_field = $abschnitt->datafields->findOneBy('datafield_id', $data_field_id);
+ if (mb_strlen($data_field->getValue('content'))) {
+ $tdf = $data_field->getTypedDatafield();
+ return $tdf->getDisplayValue();
+ }
+ }
+ return $this->getValue($field) ?? '';
+ }
+
+ /**
+ * Retrieves the id of the related data field.
+ *
+ * @param string $field The field to search for a related data field.
+ * @param string $related_class The name of the related class.
+ * @return string|null The id of the data field. Null if no related data field.
+ */
+ private static function getReplaceDataFieldsId(
+ string $field,
+ string $related_class
+ ): string|null
+ {
+ static $data_fields = null;
+
+ if (is_null($data_fields)) {
+ DataField::findEachBySQL(
+ function (DataField $f) use (&$data_fields) {
+ $data_fields[$f->object_class] = $f->datafield_id;
+ },
+ "`object_type` = ? AND `object_class` IN(?)",
+ [
+ strtolower($related_class),
+ array_keys(static::db_fields())
+ ]
+ );
+ $data_fields = $data_fields ?: [];
+ }
+ return $data_fields[$field] ?? null;
+ }
+}
diff --git a/lib/models/DataField.php b/lib/models/DataField.php
index fa2ba0b..a4b6f95 100644
--- a/lib/models/DataField.php
+++ b/lib/models/DataField.php
@@ -126,15 +126,17 @@ class DataField extends SimpleORMap implements PrivacyObject
public static function getDataClass()
{
return [
- 'sem' => _('Veranstaltungen'),
- 'inst' => _('Einrichtungen'),
- 'user' => _('Benutzer'),
- 'userinstrole' => _('Benutzerrollen in Einrichtungen'),
- 'usersemdata' => _('Benutzer-Zusatzangaben in VA'),
- 'roleinstdata' => _('Rollen in Einrichtungen'),
- 'moduldeskriptor' => _('Moduldeskriptoren'),
- 'modulteildeskriptor' => _('Modulteildeskriptoren'),
- 'studycourse' => _('Studiengänge')
+ 'sem' => _('Veranstaltungen'),
+ 'inst' => _('Einrichtungen'),
+ 'user' => _('Benutzer'),
+ 'userinstrole' => _('Benutzerrollen in Einrichtungen'),
+ 'usersemdata' => _('Benutzer-Zusatzangaben in VA'),
+ 'roleinstdata' => _('Rollen in Einrichtungen'),
+ 'moduldeskriptor' => _('Moduldeskriptoren'),
+ 'modulteildeskriptor' => _('Modulteildeskriptoren'),
+ 'studycourse' => _('Studiengänge'),
+ 'stgteilabschnittmodul' => _('Module an Studiengangteilabschnitten'),
+ 'modulteilstgteilabschnitt' => _('Modulteile an Studiengangteilabschnitten'),
];
}
@@ -285,4 +287,6 @@ class DataField extends SimpleORMap implements PrivacyObject
}
}
}
+
+
}
diff --git a/lib/models/DatafieldEntryModel.php b/lib/models/DatafieldEntryModel.php
index 408fe33..c19d9f9 100644
--- a/lib/models/DatafieldEntryModel.php
+++ b/lib/models/DatafieldEntryModel.php
@@ -117,6 +117,17 @@ class DatafieldEntryModel extends SimpleORMap implements PrivacyObject
$object_class = $model->getVariant();
$object_type = 'studycourse';
$range_id = $model->studiengang_id;
+ } elseif ($model instanceof StgteilabschnittModul) {
+ $params[':institution_ids'] = [];
+ $object_class = '';
+ $object_type = 'stgteilabschnittmodul';
+ $range_id = $model->abschnitt_modul_id;
+ } elseif ($model instanceof ModulteilStgteilabschnitt) {
+ $params[':institution_ids'] = [];
+ $object_class = '';
+ $object_type = 'modulteilstgteilabschnitt';
+ $range_id = $model->modulteil_id;
+ $sec_range_id = $model->abschnitt_id;
} else {
throw new InvalidArgumentException('Wrong type of model: ' . get_class($model));
}
@@ -155,11 +166,20 @@ class DatafieldEntryModel extends SimpleORMap implements PrivacyObject
|| $object_type === 'modulteildeskriptor') {
// find datafields by language (string)
$query .= " AND (LOCATE(:object_class, object_class) OR object_class IS NULL) ORDER BY priority";
- $params = array_merge($params,[
- ':range_id' => (string) $range_id,
- ':sec_range_id' => (string) $sec_range_id,
- ':object_type' => $object_type,
- ':object_class' => (string) $object_class,
+ $params = array_merge($params, [
+ ':range_id' => (string)$range_id,
+ ':sec_range_id' => (string)$sec_range_id,
+ ':object_type' => $object_type,
+ ':object_class' => (string)$object_class,
+ ]);
+ } elseif ($object_type === 'stgteilabschnittmodul'
+ || $object_type === 'modulteilstgteilabschnitt') {
+ // field object_class holds the name of the overwritten field or is null
+ $query .= " ORDER BY priority";
+ $params = array_merge($params, [
+ ':range_id' => (string)$range_id,
+ ':sec_range_id' => (string)$sec_range_id,
+ ':object_type' => $object_type,
]);
} else {
// find datafields by perms or status (int)
diff --git a/lib/models/Modul.php b/lib/models/Modul.php
index 8c90e18..3c79ef9 100644
--- a/lib/models/Modul.php
+++ b/lib/models/Modul.php
@@ -60,6 +60,8 @@
class Modul extends ModuleManagementModelTreeItem
{
+ use MvvReplaceDataFieldsTrait;
+
protected static function configure($config = [])
{
$config['db_table'] = 'mvv_modul';
@@ -141,15 +143,14 @@ class Modul extends ModuleManagementModelTreeItem
'on_store' => 'store'
];
- $config['additional_fields']['count_modulteile']['get'] = function ($modul) {
- return $modul->count_modulteile;
- };
- $config['additional_fields']['languagesofinstruction']['get'] = function ($modul) {
- return $modul->languages;
- };
- $config['additional_fields']['display_name']['get'] = function ($modul) {
- return $modul->getDisplayName();
- };
+ $config['additional_fields']['count_modulteile']['get'] =
+ fn(Modul $modul): int => $modul->count_modulteile;
+ $config['additional_fields']['languagesofinstruction']['get'] =
+ fn(Modul $modul): SimpleORMapCollection => $modul->languages;
+ $config['additional_fields']['display_name']['get'] =
+ fn(Modul $modul): string => $modul->getDisplayName();
+ $config['additional_fields']['abschnitt_assignments']['get'] =
+ fn(Modul $modul): SimpleORMapCollection => $modul->abschnitte_modul;
$config['alias_fields']['flexnow_id'] = 'flexnow_modul';
@@ -1034,4 +1035,21 @@ class Modul extends ModuleManagementModelTreeItem
}
return $courses;
}
+
+ /**
+ * Set the section (Studiengangteil-Abschnitt) with replaced or
+ * added fields (defined as data fields) for all related objects.
+ *
+ * @param Stgteilabschnitt $abschnitt The section.
+ * @return int The number of objects related to the given section.
+ * @see MvvReplaceDataFieldsTrait::setReplaceDfAbschnitt()
+ */
+ public function setReplaceDfAbschnitt(Stgteilabschnitt $abschnitt): int
+ {
+ $this->replace_df_abschnitt_id = $abschnitt->id;
+ $ret = $this->modulteile->each(fn(Modulteil $mt): int => $mt->setReplaceDfAbschnitt($abschnitt));
+ $ret += $this->deskriptoren->setReplaceDfAbschnitt($abschnitt);
+ return $ret + 1;
+ }
+
}
diff --git a/lib/models/ModulDeskriptor.php b/lib/models/ModulDeskriptor.php
index d9da0bb..fe41200 100644
--- a/lib/models/ModulDeskriptor.php
+++ b/lib/models/ModulDeskriptor.php
@@ -44,6 +44,8 @@
class ModulDeskriptor extends ModuleManagementModel
{
+ use MvvReplaceDataFieldsTrait;
+
protected static function configure($config = [])
{
$config['db_table'] = 'mvv_modul_deskriptor';
@@ -69,6 +71,9 @@ class ModulDeskriptor extends ModuleManagementModel
}
];
+ $config['additional_fields']['abschnitt_assignments']['get'] =
+ fn(ModulDeskriptor $m): SimpleORMapCollection => $m->modul->abschnitte_modul;
+
$config['i18n_fields']['verantwortlich'] = true;
$config['i18n_fields']['bezeichnung'] = true;
$config['i18n_fields']['voraussetzung'] = true;
diff --git a/lib/models/Modulteil.php b/lib/models/Modulteil.php
index 541d301..07ba2cc 100644
--- a/lib/models/Modulteil.php
+++ b/lib/models/Modulteil.php
@@ -48,6 +48,8 @@
class Modulteil extends ModuleManagementModelTreeItem
{
+ use MvvReplaceDataFieldsTrait;
+
protected static function configure($config = [])
{
$config['db_table'] = 'mvv_modulteil';
@@ -321,7 +323,7 @@ class Modulteil extends ModuleManagementModelTreeItem
/**
* Assignes languages of instruction to this part-module.
*
- * @param type $languages An array of language keys defined in mvv_config.php.
+ * @param string[] $languages An array of language keys defined in mvv_config.php.
*/
public function assignLanguagesOfInstruction($languages)
{
@@ -396,4 +398,17 @@ class Modulteil extends ModuleManagementModelTreeItem
return $courses;
}
+ /**
+ * Set the section (Studiengangteil-Abschnitt) with replaced or
+ * added fields (defined as data fields) for all related objects.
+ *
+ * @param Stgteilabschnitt $abschnitt The section.
+ * @return int The number of objects related to the given section.
+ * @see MvvReplaceDataFieldsTrait::setReplaceDfAbschnitt()
+ */
+ public function setReplaceDfAbschnitt(StgteilAbschnitt $abschnitt): int
+ {
+ $this->replace_df_abschnitt_id = $abschnitt->id;
+ return $this->deskriptoren->setReplaceDfAbschnitt($abschnitt) + 1;
+ }
}
diff --git a/lib/models/ModulteilDeskriptor.php b/lib/models/ModulteilDeskriptor.php
index eaf41a5..221ef73 100644
--- a/lib/models/ModulteilDeskriptor.php
+++ b/lib/models/ModulteilDeskriptor.php
@@ -37,6 +37,8 @@
class ModulteilDeskriptor extends ModuleManagementModel
{
+ use MvvReplaceDataFieldsTrait;
+
protected static function configure($config = [])
{
$config['db_table'] = 'mvv_modulteil_deskriptor';
@@ -62,6 +64,9 @@ class ModulteilDeskriptor extends ModuleManagementModel
}
];
+ $config['additional_fields']['abschnitt_assignments']['get'] =
+ fn(ModulteilDeskriptor $md): SimpleORMapCollection => $md->modulteil->abschnitt_assignments;
+
$config['i18n_fields']['bezeichnung'] = true;
$config['i18n_fields']['voraussetzung'] = true;
$config['i18n_fields']['kommentar'] = true;
diff --git a/lib/models/ModulteilStgteilabschnitt.php b/lib/models/ModulteilStgteilabschnitt.php
index d16c3a0..0b34468 100644
--- a/lib/models/ModulteilStgteilabschnitt.php
+++ b/lib/models/ModulteilStgteilabschnitt.php
@@ -43,6 +43,20 @@ class ModulteilStgteilabschnitt extends ModuleManagementModel
'foreign_key' => 'abschnitt_id',
'assoc_func' => 'findCached',
];
+ $config['has_many']['datafields'] = [
+ 'class_name' => DatafieldEntryModel::class,
+ 'assoc_foreign_key' =>
+ function($model, $params) {
+ $model->setValue('range_id', $params[0]->id);
+ },
+ 'assoc_func' => 'findByModel',
+ 'on_delete' => 'delete',
+ 'on_store' => 'store',
+ 'foreign_key' =>
+ function($m) {
+ return [$m];
+ }
+ ];
parent::configure($config);
}
diff --git a/lib/models/StgteilVersion.php b/lib/models/StgteilVersion.php
index 017b590..9cb4b00 100644
--- a/lib/models/StgteilVersion.php
+++ b/lib/models/StgteilVersion.php
@@ -355,26 +355,39 @@ class StgteilVersion extends ModuleManagementModelTreeItem
// TODO set default value
$new_version->stat = 'planung';
$new_mvv_objects[] = $new_version;
- foreach (StgteilAbschnitt::findByStgteilVersion($this->getId()) as $abschnitt) {
+ foreach ($this->abschnitte as $abschnitt) {
$new_abschnitt = clone $abschnitt;
$new_abschnitt->setNew(true);
$new_abschnitt->setNewId();
$new_abschnitt->version_id = $new_version->version_id;
$new_mvv_objects[] = $new_abschnitt;
- $modul_assignments = $abschnitt->getModulAssignments();
- foreach ($modul_assignments as $assignment) {
+ foreach ($abschnitt->modul_zuordnungen as $assignment) {
$new_modul_assignment = clone $assignment;
$new_modul_assignment->setNew(true);
$new_modul_assignment->setNewId();
$new_modul_assignment->abschnitt_id = $new_abschnitt->abschnitt_id;
+ // copy data fields
+ foreach ($assignment->datafields as $datafield) {
+ $new_data_field = clone $datafield;
+ $new_data_field->setNew(true);
+ $new_data_field->range_id = $new_modul_assignment->abschnitt_modul_id;
+ $new_mvv_objects[] = $new_data_field;
+ }
$new_mvv_objects[] = $new_modul_assignment;
}
- $modulteil_assignments = ModulteilStgteilabschnitt::findBySql(
- 'abschnitt_id = ' . DBManager::get()->quote($abschnitt->getId()));
- foreach ($modulteil_assignments as $assignment) {
+ foreach ($abschnitt->modulteil_abschnitte as $assignment) {
$new_modulteil_assignment = clone $assignment;
$new_modulteil_assignment->setNew(true);
$new_modulteil_assignment->abschnitt_id = $new_abschnitt->abschnitt_id;
+ // copy data fields
+ if (empty($assignment->fachsemester)) {
+ foreach ($assignment->datafields as $datafield) {
+ $new_data_field = clone $datafield;
+ $new_data_field->setNew(true);
+ $new_data_field->sec_range_id = $new_abschnitt->abschnitt_id;
+ $new_mvv_objects[] = $new_data_field;
+ }
+ }
$new_mvv_objects[] = $new_modulteil_assignment;
}
}
diff --git a/lib/models/StgteilabschnittModul.php b/lib/models/StgteilabschnittModul.php
index d871df6..aa0eba7 100644
--- a/lib/models/StgteilabschnittModul.php
+++ b/lib/models/StgteilabschnittModul.php
@@ -28,6 +28,7 @@
* @property int $chdate database column
* @property Modul $modul belongs_to Modul
* @property StgteilAbschnitt $abschnitt belongs_to StgteilAbschnitt
+ * @property DataField $datafield has_many DataField
*/
class StgteilabschnittModul extends ModuleManagementModelTreeItem
@@ -46,6 +47,20 @@ class StgteilabschnittModul extends ModuleManagementModelTreeItem
'foreign_key' => 'abschnitt_id',
'assoc_func' => 'findCached',
];
+ $config['has_many']['datafields'] = [
+ 'class_name' => DatafieldEntryModel::class,
+ 'assoc_foreign_key' =>
+ function($model, $params) {
+ $model->setValue('range_id', $params[0]->id);
+ },
+ 'assoc_func' => 'findByModel',
+ 'on_delete' => 'delete',
+ 'on_store' => 'store',
+ 'foreign_key' =>
+ function($m) {
+ return [$m];
+ }
+ ];
$config['i18n_fields']['bezeichnung'] = true;
@@ -135,9 +150,15 @@ class StgteilabschnittModul extends ModuleManagementModelTreeItem
{
$ret = [];
$modulteil_abschnitte = ModulteilStgteilabschnitt::findBySql(
- 'modulteil_id = ' . DBManager::get()->quote($modulteil_id)
- . ' AND abschnitt_id = '
- . DBManager::get()->quote($this->abschnitt_id));
+ '`modulteil_id` = ?
+ AND `abschnitt_id` = ?
+ AND `fachsemester` > 0
+ ORDER BY `fachsemester` ASC',
+ [
+ $modulteil_id,
+ $this->abschnitt_id,
+ ]
+ );
foreach ($modulteil_abschnitte as $modulteil_abschnitt) {
$ret[$modulteil_abschnitt->fachsemester] = $modulteil_abschnitt;
}
diff --git a/resources/assets/javascripts/mvv.js b/resources/assets/javascripts/mvv.js
index c00567d..9191ad7 100644
--- a/resources/assets/javascripts/mvv.js
+++ b/resources/assets/javascripts/mvv.js
@@ -227,14 +227,16 @@ STUDIP.MVV.Search = {
qs_real = qs_input.prev('input'),
qs_name = qs_input.attr('id'),
qs_select = jQuery('<select/>').attr('id', 'select_' + qs_name)
- .addClass('mvv-search-select-list'),
+ .addClass('mvv-search-select-list')
+ .css({display: 'inline'}),
qs_id = qs_item.data('qs_id'),
do_submit = qs_item.data('qs_submit');
var reset_button = jQuery('<input type="image" />');
reset_button.attr({
src: STUDIP.ASSETS_URL+'images/icons/blue/decline.svg',
title: $gettext("Suche zurücksetzen")
- }).addClass('mvv-search-reset');
+ }).addClass('mvv-search-reset middle')
+ .css({display: 'inline'});
if (!_.isUndefined(do_submit)) {
qs_select.change(function() {
var selected = qs_select.children('option:selected');