aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Thienel <thienel@data-quest.de>2026-01-08 18:43:19 +0100
committerPeter Thienel <thienel@data-quest.de>2026-01-08 18:43:19 +0100
commit9fa00a819475ded9cf21859f1f9aa446293d2add (patch)
tree5a8caced5ecd1048bfb4538946775ba9f31cb61e
parent59ad17e3ff68384a719daa96bb9f5f3106fed061 (diff)
Fach, Fachbereich and views reworkedissue-4262
-rw-r--r--app/controllers/fachabschluss/faecher.php72
-rw-r--r--app/views/fachabschluss/abschluesse/details.php9
-rw-r--r--app/views/fachabschluss/faecher/details.php8
-rw-r--r--app/views/fachabschluss/faecher/fachbereiche.php24
-rw-r--r--app/views/fachabschluss/faecher/index.php23
-rw-r--r--lib/classes/MvvPerm.php9
-rw-r--r--lib/models/Abschluss.php16
-rw-r--r--lib/models/Fach.php51
-rw-r--r--lib/models/Fachbereich.php14
9 files changed, 164 insertions, 62 deletions
diff --git a/app/controllers/fachabschluss/faecher.php b/app/controllers/fachabschluss/faecher.php
index e5c1184..fef6042 100644
--- a/app/controllers/fachabschluss/faecher.php
+++ b/app/controllers/fachabschluss/faecher.php
@@ -14,6 +14,7 @@ class Fachabschluss_FaecherController extends MVVController
$this->action = $action;
}
+
/**
* Shows all Faecher
*/
@@ -22,34 +23,52 @@ class Fachabschluss_FaecherController extends MVVController
PageLayout::setTitle(_('Verwaltung der Fächer'));
$this->initPageParams();
- // Nur Fächer mit verantwortlichen Einrichtungen an denen der User
- // eine Rolle hat
- $filter = ['mvv_fach_inst.institut_id' => MvvPerm::getOwnInstitutes()];
-
- $this->count = Fach::getCount($filter);
+ $this->count = Fach::countBySql(
+ 'LEFT JOIN `mvv_fach_inst` USING (`fach_id`)
+ WHERE IF(:institute_ids, `mvv_fach_inst`.`institut_id` IN (:institute_ids), 1)',
+ [
+ 'institute_ids' => MvvPerm::getOwnInstitutes()
+ ]);
if ($this->count < self::$items_per_page * ($this->page - 1)) {
$this->page = 1;
}
- $this->sortby = $this->sortby ?: 'name';
- $this->order = $this->order ?: 'ASC';
- //get data
- $this->faecher = Fach::getAllEnriched(
- $this->sortby,
- $this->order,
- self::$items_per_page,
- self::$items_per_page * ($this->page - 1),
- $filter
+
+ $db = DBManager::get();
+ $stmt = $db->prepare('
+ SELECT
+ `fach`.*,
+ COUNT(DISTINCT `abschluss_id`) AS `count_abschluesse`
+ FROM `fach`
+ LEFT JOIN `mvv_fach_inst` USING (`fach_id`)
+ LEFT JOIN `mvv_stgteil` USING (`fach_id`)
+ LEFT JOIN `mvv_stg_stgteil` USING (`stgteil_id`)
+ LEFT JOIN `mvv_studiengang` USING (`studiengang_id`)
+ WHERE IF(:institute_ids, `mvv_fach_inst`.`institut_id` IN (:institute_ids), 1)
+ GROUP BY `fach_id`
+ ORDER BY :sortby :order
+ LIMIT :row_count
+ OFFSET :offset'
);
+ $stmt->bindValue(':sortby', '`' . ($this->sortby ?: 'name') . '`', StudipPDO::PARAM_COLUMN);
+ $stmt->bindValue(':order', $this->order ?: 'ASC', StudipPDO::PARAM_COLUMN);
+ $stmt->execute(
+ [
+ 'institute_ids' => MvvPerm::getOwnInstitutes(),
+ 'row_count' => self::$items_per_page,
+ 'offset' => self::$items_per_page * ($this->page - 1)
+ ]
+ );
+ $this->faecher = $stmt->fetchAll();
+
if (!isset($this->fach_id)) {
$this->fach_id = null;
}
- if (count($this->faecher) === 0) {
+ if ($this->count === 0) {
PageLayout::postInfo(_('Es wurden noch keine Fächer angelegt.'));
}
$this->setSidebar();
-
$helpbar = Helpbar::get();
$widget = new HelpbarWidget();
$widget->addElement(new WidgetElement(_('Auf diesen Seiten können Sie Fächer verwalten und neue Fächer anlegen.').'</br>'));
@@ -157,6 +176,25 @@ class Fachabschluss_FaecherController extends MVVController
*/
public function fachbereiche_action()
{
+ $db = DBManager::get();
+ $stmt = $db->prepare('
+ SELECT DISTINCT `Institute`.*, 2 AS `test`
+ FROM `Institute`
+ JOIN `mvv_fach_inst` USING(`institut_id`)
+ WHERE IF(:institute_ids, `mvv_fach_inst`.`institut_id` IN (:institute_ids), 1)
+ ORDER BY :sortby :order'
+ );
+ $stmt->bindValue(':sortby', '`' . ($this->sortby ?: 'name') . '`', StudipPDO::PARAM_COLUMN);
+ $stmt->bindValue(':order', $this->order ?: 'ASC', StudipPDO::PARAM_COLUMN);
+ $stmt->execute(
+ [
+ 'institute_ids' => MvvPerm::getOwnInstitutes()
+ ]
+ );
+ $this->fachbereiche = $stmt->fetchAll();
+
+
+/*
$filter = ['mvv_fach_inst.institut_id' => MvvPerm::getOwnInstitutes()];
$this->initPageParams('fachbereiche');
@@ -168,7 +206,7 @@ class Fachabschluss_FaecherController extends MVVController
$filter
);
PageLayout::setTitle(_('Fächer nach Fachbereichen gruppiert'));
-
+*/
$this->setSidebar();
$helpbar = Helpbar::get();
diff --git a/app/views/fachabschluss/abschluesse/details.php b/app/views/fachabschluss/abschluesse/details.php
index b475f40..aced360 100644
--- a/app/views/fachabschluss/abschluesse/details.php
+++ b/app/views/fachabschluss/abschluesse/details.php
@@ -1,10 +1,17 @@
+<?php
+/**
+ * @var Abschluss $abschluss
+ * @var string[] $perm_institutes
+ * @var Fachabschluss_AbschluesseController $controller
+ */
+?>
<td colspan="4">
<table class="default">
<colgroup>
<col>
<col style="width: 1%;">
</colgroup>
- <? foreach ($abschluss->getFaecher() as $fach) : ?>
+ <? foreach ($abschluss->faecher as $fach) : ?>
<? if (count($perm_institutes) === 0
|| count(array_intersect($perm_institutes, $fach->getFachbereiche()->pluck('institut_id')))) : ?>
<tr>
diff --git a/app/views/fachabschluss/faecher/details.php b/app/views/fachabschluss/faecher/details.php
index b8abf4e..8271581 100644
--- a/app/views/fachabschluss/faecher/details.php
+++ b/app/views/fachabschluss/faecher/details.php
@@ -1,3 +1,8 @@
+<?php
+/**
+ * @var Fach $fach
+ */
+?>
<td colspan="3">
<table class="default">
<colgroup>
@@ -5,8 +10,7 @@
<col style="width: 40%">
<col style="width: 1%">
</colgroup>
- <?php $abschluesse = $fach->getAbschluesse()?>
- <? foreach ($abschluesse as $abschluss) : ?>
+ <? foreach ($fach->abschluesse as $abschluss) : ?>
<tr>
<td><?= htmlReady($abschluss->getDisplayName()) ?></td>
<td><?= htmlReady($abschluss->category->getDisplayName()) ?></td>
diff --git a/app/views/fachabschluss/faecher/fachbereiche.php b/app/views/fachabschluss/faecher/fachbereiche.php
index 844440c..6a99719 100644
--- a/app/views/fachabschluss/faecher/fachbereiche.php
+++ b/app/views/fachabschluss/faecher/fachbereiche.php
@@ -1,3 +1,10 @@
+<?php
+/**
+ * @var MVVController $controller
+ * @var Fachbereich[] $fachbereiche
+ * @var string $fachbereich_id
+ */
+?>
<table class="default collapsable">
<colgroup>
<col>
@@ -8,22 +15,23 @@
<?= $controller->renderSortLink('fachabschluss/faecher/fachbereiche/', _('Fächer'), 'faecher', ['style' => 'text-align: center;']) ?>
</tr>
</thead>
- <? foreach ($fachbereiche as $fachbereich): ?>
- <? if ($fachbereich['faecher']) : ?>
- <tbody class="<?= isset($fachbereich_id) && $fachbereich_id === $fachbereich['institut_id'] ? 'not-collapsed' : 'collapsed' ?>">
+ <? foreach ($fachbereiche as $fachbereich_data): ?>
+ <? $fachbereich = Fachbereich::buildExisting($fachbereich_data); ?>
+ <? if ($fachbereich->faecher) : ?>
+ <tbody class="<?= isset($fachbereich_id) && $fachbereich_id === $fachbereich->id ? 'not-collapsed' : 'collapsed' ?>">
<tr class="header-row">
<td class="toggle-indicator">
<a class="mvv-load-in-new-row"
- href="<?= $controller->action_link('details_fachbereich/' . $fachbereich['institut_id']) ?>"><?= htmlReady($fachbereich['name']) ?></a>
+ href="<?= $controller->action_link('details_fachbereich/' . $fachbereich->id) ?>"><?= htmlReady($fachbereich->getDisplayName()) ?></a>
</td>
- <td style="text-align: center;" class="dont-hide"><?= htmlReady($fachbereich['faecher']) ?> </td>
+ <td style="text-align: center;" class="dont-hide"><?= $fachbereich->faecher->count() ?> </td>
</tr>
- <? if (isset($fachbereich_id) && $fachbereich_id === $fachbereich['institut_id']): ?>
+ <? if (isset($fachbereich_id) && $fachbereich_id === $fachbereich->id): ?>
<tr class="loaded-details nohover">
- <?= $this->render_partial('fachabschluss/faecher/details_fachbereich', compact('fach')) ?>
+ <?= $this->render_partial('fachabschluss/faecher/details_fachbereich', compact('fachbereich')) ?>
</tr>
<? endif; ?>
</tbody>
<? endif; ?>
- <? endforeach ?>
+ <? endforeach; ?>
</table>
diff --git a/app/views/fachabschluss/faecher/index.php b/app/views/fachabschluss/faecher/index.php
index b42761e..39c720d 100644
--- a/app/views/fachabschluss/faecher/index.php
+++ b/app/views/fachabschluss/faecher/index.php
@@ -1,3 +1,12 @@
+<?php
+/**
+ * @var int $count
+ * @var MVVController $controller
+ * @var Fach[] $faecher
+ * @var string $fach_id
+ * @var int $page
+ */
+?>
<form method="post">
<?= CSRFProtection::tokenTag(); ?>
<table class="default collapsable">
@@ -12,18 +21,19 @@
<th style="width: 5%; text-align: right;"><?= _('Aktionen') ?></th>
</tr>
</thead>
- <? foreach ($faecher as $fach): ?>
- <tbody class="<?= $fach->count_abschluesse ? '' : 'empty' ?> <?= ($fach_id === $fach->id ? 'not-collapsed' : 'collapsed') ?>">
+ <? foreach ($faecher as $fach_data) : ?>
+ <? $fach = Fach::buildExisting($fach_data); ?>
+ <tbody class="<?= $fach->abschluesse->count() ? '' : 'empty' ?> <?= ($fach_id === $fach->id ? 'not-collapsed' : 'collapsed') ?>">
<tr class="header-row">
<td class="toggle-indicator">
- <? if ($fach->count_abschluesse) : ?>
+ <? if ($fach->abschluesse->count()) : ?>
<a class="mvv-load-in-new-row"
href="<?= $controller->action_link('details/' . $fach->id) ?>"><?= htmlReady($fach->name) ?></a>
<? else: ?>
<?= htmlReady($fach->name) ?>
<? endif; ?>
</td>
- <td class="dont-hide" style="text-align: center;"><?= $fach->count_abschluesse ?> </td>
+ <td class="dont-hide" style="text-align: center;"><?= $fach->abschluesse->count() ?> </td>
<td class="dont-hide actions" style="white-space: nowrap;">
<? if (MvvPerm::havePermWrite($fach)) : ?>
<a href="<?= $controller->action_link('fach/' . $fach->id) ?>">
@@ -31,7 +41,7 @@
</a>
<? endif; ?>
<? if (MvvPerm::havePermCreate($fach)) : ?>
- <? if ($fach->count_abschluesse == 0): ?>
+ <? if ($fach->abschluesse->count() == 0): ?>
<?= Icon::create('trash', Icon::ROLE_CLICKABLE, tooltip2(_('Fach löschen')))->asInput(
[
'formaction' => $controller->action_url('delete/' . $fach->id),
@@ -39,7 +49,7 @@
'name' => 'delete'
]); ?>
<? else : ?>
- <?= Icon::create('trash', Icon::ROLE_INACTIVE, tooltip2(_('Fach kann nicht glöscht werden')))->asSvg(); ?>
+ <?= Icon::create('trash', Icon::ROLE_INACTIVE, tooltip2(_('Fach kann nicht gelöscht werden')))->asSvg(); ?>
<? endif; ?>
<? endif; ?>
</td>
@@ -65,7 +75,6 @@
$pagination->set_attribute('pagelink', $page_link);
echo $pagination->render();
?>
-
</td>
</tr>
</tfoot>
diff --git a/lib/classes/MvvPerm.php b/lib/classes/MvvPerm.php
index 693b7b7..d75a35d 100644
--- a/lib/classes/MvvPerm.php
+++ b/lib/classes/MvvPerm.php
@@ -638,9 +638,12 @@ class MvvPerm {
}
if (count($institutes)) {
- $stmt = DBManager::get()->prepare('SELECT DISTINCT(Institut_id) '
- . 'FROM Institute WHERE Institut_id IN (:inst_ids) '
- . 'OR fakultaets_id IN (:inst_ids)');
+ $stmt = DBManager::get()->prepare('
+ SELECT DISTINCT(`Institut_id`)
+ FROM `Institute`
+ WHERE `Institut_id` IN (:inst_ids)
+ OR `fakultaets_id` IN (:inst_ids)
+ ');
$stmt->execute(['inst_ids' => $institutes]);
self::$user_role_institutes[$user_id] = $stmt->fetchAll(PDO::FETCH_COLUMN);
} else {
diff --git a/lib/models/Abschluss.php b/lib/models/Abschluss.php
index 4f26563..7bab324 100644
--- a/lib/models/Abschluss.php
+++ b/lib/models/Abschluss.php
@@ -152,14 +152,13 @@ class Abschluss extends ModuleManagementModelTreeItem implements PrivacyObject
/**
* Returns all Abschluesse assigned to a given Fach.
- * An Abschluss is assigned to a Fach if a Studiengangteil (that holds th Fach)
+ * An Abschluss is assigned to a Fach if a Studiengangteil (that holds the Fach)
* is assigned to a Studiengang (as the home of the Abschluss).
*
* @param string $fach_id The id of the fach.
- * @return array An array of abschluss objects.
+ * @return static[] An array of abschluss objects.
* REMOVED
*/
- /*
public static function findByFach($fach_id)
{
return self::findBySQL(
@@ -169,10 +168,11 @@ class Abschluss extends ModuleManagementModelTreeItem implements PrivacyObject
WHERE `mvv_stgteil`.`fach_id` = ?
GROUP BY `abschluss`.`abschluss_id`
ORDER BY `abschluss`.`name`',
- [$fach_id]
+ [
+ $fach_id
+ ]
);
}
- */
/**
* Returns all Abschluesse assigned to Studiengaenge.
@@ -304,16 +304,20 @@ class Abschluss extends ModuleManagementModelTreeItem implements PrivacyObject
* Returns all Faecher this Abschluss is assigned to.
*
* @return array All Faecher this Abschluss is assigned to.
+ * REMOVED
*/
+ /*
public function getFaecher()
{
return Fach::findByAbschluss($this->getId());
}
+ */
/**
- * Returns all assigned institutes of this Abschluss.
+ * Returns all institutes implicitly assigned by study courses (responsible institute).
*
* @return array An array of institutes.
+ * TODO (remove)
*/
public function getAssignedInstitutes()
{
diff --git a/lib/models/Fach.php b/lib/models/Fach.php
index 802fcd4..73e6377 100644
--- a/lib/models/Fach.php
+++ b/lib/models/Fach.php
@@ -70,10 +70,11 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
'on_store' => 'store',
'on_delete' => 'delete'
];
-
+/*
$config['additional_fields']['count_abschluesse']['get'] = function ($fach) {
return $fach->count_abschluesse;
};
+*/
$config['additional_fields']['count_user']['get'] = function ($fach) {
return $fach->count_user;
};
@@ -151,7 +152,9 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
* @param array $filter Key-value pairs of filed names and values
* to filter the result set.
* @return int The number of Fächer
+ * REMOVED
*/
+ /*
public static function getCount($filter = null)
{
$query = '
@@ -163,6 +166,7 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
$db->execute();
return $db->fetchColumn(0);
}
+ */
/**
* Returns all Faecher which are assigned to Studiengangteile. Sorted and
@@ -240,35 +244,46 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
* Retrieves all Faecher implicitly assigned to the given Abschluss.
*
* @param string $abschluss_id The id of the Abschluss.
- * @return object Collection of Faecher assigned to the given Abschluss.
+ * @return static[] An array of Faecher assigned to the given Abschluss.
*/
public static function findByAbschluss($abschluss_id)
{
- return parent::getEnrichedByQuery('
- SELECT mf.*
- FROM fach mf
- LEFT JOIN mvv_stgteil USING (fach_id)
- LEFT JOIN mvv_stg_stgteil USING (stgteil_id)
- LEFT JOIN mvv_studiengang ms USING (studiengang_id)
- WHERE ms.abschluss_id = ?
- ORDER BY name',
- [$abschluss_id]
+ return self::findBySQL(
+ 'JOIN `mvv_stgteil` USING (`fach_id`)
+ JOIN `mvv_stg_stgteil` USING (`stgteil_id`)
+ JOIN `mvv_studiengang` USING (`studiengang_id`)
+ WHERE `mvv_studiengang`.`abschluss_id` = ?
+ GROUP BY `fach`.`fach_id`
+ ORDER BY `name`',
+ [
+ $abschluss_id
+ ]
);
}
/**
- * Retrieves all Faecher the giveb Fachbereich is assigned to. If the 2nd
+ * Retrieves all Faecher the given Fachbereich is assigned to. If the 2nd
* parameter is true, only Faecher assigned to Studiengangteile will be
* returned.
*
* @param string $abschluss_id The id of the Abschluss.
- * @return object Collection of Faecher assigned to the given Abschluss.
+ * @return static[] Collection of Faecher assigned to the given Abschluss.
*/
public static function findByFachbereich($fachbereich_id, $has_stgteile = false)
{
$has_stgteile_sql = $has_stgteile
- ? 'INNER JOIN mvv_stgteil USING (fach_id) '
+ ? 'INNER JOIN `mvv_stgteil` USING (`fach_id`) '
: '';
+ return self::findBySQL(
+ $has_stgteile_sql .
+ 'LEFT JOIN `mvv_fach_inst` USING(`fach_id`)
+ WHERE `mvv_fach_inst`.`institut_id` = ?
+ ORDER BY `name`',
+ [
+ $fachbereich_id
+ ]
+ );
+ /*
return parent::getEnrichedByQuery('
SELECT mf.*
FROM fach mf
@@ -278,6 +293,7 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
ORDER BY name',
[$fachbereich_id]
);
+ */
}
/**
@@ -485,7 +501,7 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
/**
- * Returns names ans ids of all Fachbereiche (institutes) with number of
+ * Returns names and ids of all Fachbereiche (institutes) with number of
* related Faecher. Sorted and filtered by optional parameters.
*
* @param string $sortby Column names to sort by.
@@ -493,7 +509,9 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
* @param array $filter Array of filter parameters (name of column as key,
* see ModulManagementModel::getFilterSql()).
* @return array Associative array of Fachbereiche (id as key).
+ * REMOVED
*/
+ /*
public static function getAllFachbereiche($sortby = 'name', $order = 'ASC',
$filter = null)
{
@@ -516,6 +534,7 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
}
return $fachbereiche;
}
+ */
/**
* Returns an array with all faecher which are used by given Fachbereich
@@ -553,7 +572,7 @@ class Fach extends ModuleManagementModelTreeItem implements PrivacyObject
}
/**
- * Assignes fachbereiche to this fach.
+ * Assigns fachbereiche to this fach.
* Returns true only if all given fachbereich ids are valid.
*
* @param string[]|object[] Array of $fachbereich_ids or
diff --git a/lib/models/Fachbereich.php b/lib/models/Fachbereich.php
index 1a8fe0a..e9d64a5 100644
--- a/lib/models/Fachbereich.php
+++ b/lib/models/Fachbereich.php
@@ -39,6 +39,13 @@ class Fachbereich extends ModuleManagementModelTreeItem
{
$config['db_table'] = 'Institute';
+ $config['has_and_belongs_to_many']['faecher'] = [
+ 'class_name' => Fach::class,
+ 'thru_table' => 'mvv_fach_inst',
+ 'thru_key' => 'institut_id',
+ 'thru_assoc_key' => 'fach_id'
+ ];
+
$config['additional_fields']['count_objects']['get'] =
function($fb) { return $fb->count_objects; };
$config['additional_fields']['count_module']['get'] =
@@ -69,7 +76,7 @@ class Fachbereich extends ModuleManagementModelTreeItem
/**
* Retrieves all Fachbereiche which are implicitly related to the given
* modules. The relation is done through the hole MVV structure. If an
- * object has a status field, the status has to be public. Otherwise the
+ * object has a status field, the status has to be public. Otherwise, the
* related Fachbereich will not be retrieved.
*
* @param array $module_ids An array of module ids.
@@ -215,7 +222,7 @@ class Fachbereich extends ModuleManagementModelTreeItem
];
$replacements = [
$this->name,
- static::findCached($this->fakultaets_id)->getShortName()
+ static::findCached($this->fakultaets_id)->name
];
return self::formatDisplayName($template, $placeholders, $replacements);
}
@@ -282,7 +289,9 @@ class Fachbereich extends ModuleManagementModelTreeItem
* the display name.
*
* @return string The (short) name of the faculty.
+ * REMOVED
*/
+ /*
public function getShortName()
{
// Gießen
@@ -290,5 +299,6 @@ class Fachbereich extends ModuleManagementModelTreeItem
return $this->getDisplayName();
}
+ */
}