aboutsummaryrefslogtreecommitdiff
path: root/app/controllers/shared/contacts.php
diff options
context:
space:
mode:
authorPeter Thienel <thienel@data-quest.de>2024-01-03 10:19:29 +0000
committerPeter Thienel <thienel@data-quest.de>2024-01-03 10:19:29 +0000
commitb015aa61b1fb3d5abe647748f223820e76141e99 (patch)
tree183134e5985a5a7b3db3cb366e07a4bf51e9f5e2 /app/controllers/shared/contacts.php
parent0f7a86d1d23ba171a796ba75b5beff26cc8e46cd (diff)
Resolve "MVV: Suche (Filter) nach Abschlüssen und Fächern im Backend"
Closes #3387 Merge request studip/studip!2306
Diffstat (limited to 'app/controllers/shared/contacts.php')
-rw-r--r--app/controllers/shared/contacts.php273
1 files changed, 271 insertions, 2 deletions
diff --git a/app/controllers/shared/contacts.php b/app/controllers/shared/contacts.php
index a3da1a7..98670f4 100644
--- a/app/controllers/shared/contacts.php
+++ b/app/controllers/shared/contacts.php
@@ -64,8 +64,28 @@ class Shared_ContactsController extends MVVController
if (empty($this->filter['mvv_modul_inst.institut_id'])) {
unset($this->filter['mvv_modul_inst.institut_id']);
}
- if ($search_result) {
- $this->filter['mvv_contacts.contact_id'] = $search_result;
+
+ $contact_ids = [];
+ if (count($search_result) > 0) {
+ $contact_ids = $search_result;
+ } else {
+ if (!empty($_SESSION['mvv_filter_contacts_fach_id'])) {
+ $contact_ids = $this->findContactIdsByFach($_SESSION['mvv_filter_contacts_fach_id']);
+ }
+ if (!empty($_SESSION['mvv_filter_contacts_abschluss_id'])) {
+ if (count($contact_ids) > 0) {
+ $contact_ids = array_intersect(
+ $contact_ids,
+ $this->findContactIdsByAbschluss($_SESSION['mvv_filter_contacts_abschluss_id'])
+ );
+ } else {
+ $contact_ids = $this->findContactIdsByAbschluss($_SESSION['mvv_filter_contacts_abschluss_id']);
+ }
+ }
+ }
+
+ if (count($contact_ids) > 0) {
+ $this->filter['mvv_contacts.contact_id'] = $contact_ids;
}
$own_institutes = MvvPerm::getOwnInstitutes();
@@ -241,6 +261,12 @@ class Shared_ContactsController extends MVVController
$this->filter['mvv_contacts_ranges.range_type'] = Request::option('zuordnung_filter');
}
+ // Fach
+ $_SESSION['mvv_filter_contacts_fach_id'] = Request::option('fach_filter', '');
+
+ // Abschluss
+ $_SESSION['mvv_filter_contacts_abschluss_id'] = Request::option('abschluss_filter', '');
+
// store filter
$this->reset_page();
$this->sessSet('filter', $this->filter);
@@ -249,6 +275,9 @@ class Shared_ContactsController extends MVVController
public function reset_filter_action()
{
+ $_SESSION['mvv_filter_contacts_fach_id'] = '';
+ $_SESSION['mvv_filter_contacts_abschluss_id'] = '';
+
$this->filter = [];
$this->reset_search();
$this->sessRemove('filter');
@@ -346,6 +375,9 @@ class Shared_ContactsController extends MVVController
$this->filter
);
+ $contact_ids = MvvContact::getIdsFiltered($this->filter);
+ $count_faecher = $this->countFaecher($contact_ids, $_SESSION['mvv_filter_contacts_fach_id'] ?? '');
+ $count_abschluesse = $this->countAbschluesse($contact_ids, $_SESSION['mvv_filter_contacts_abschluss_id'] ?? '');
$semesters = new SimpleCollection(array_reverse(Semester::getAll()));
$filter_template = $template_factory->render('shared/filter', [
'semester' => $semesters,
@@ -365,6 +397,16 @@ class Shared_ContactsController extends MVVController
'status' => $this->findStatusByIds(),
'selected_status' => $this->filter['mvv_contacts.contact_status'] ?? '',
'status_array' => ['intern' => ['name' => _('Intern')], 'extern' => ['name' =>_('Extern')]],
+ 'faecher' => SimpleORMapCollection::createFromArray(
+ Fach::findMany(array_keys($count_faecher))
+ )->orderBy('name'),
+ 'count_faecher' => $count_faecher,
+ 'selected_fach' => $_SESSION['mvv_filter_contacts_fach_id'] ?? '',
+ 'abschluesse' => SimpleORMapCollection::createFromArray(
+ Abschluss::findMany(array_keys($count_abschluesse))
+ )->orderBy('name'),
+ 'count_abschluesse' => $count_abschluesse,
+ 'selected_abschluss' => $_SESSION['mvv_filter_contacts_abschluss_id'] ?? '',
'action' => $this->action_url('set_filter'),
'action_reset' => $this->action_url('reset_filter')
]);
@@ -991,4 +1033,231 @@ class Shared_ContactsController extends MVVController
}
return $result;
}
+
+ /**
+ * Returns the number of contacts grouped by subjects for given contact ids.
+ *
+ * @param array $contact_ids The ids of the contacts.
+ * @param string $fach_id The id of the selected subject.
+ * @return array Number of contacts grouped by subjects.
+ */
+ private function countFaecher(array $contact_ids, string $fach_id): array
+ {
+ if ($fach_id === '') {
+ $params = [':contact_ids' => $contact_ids];
+ $where = "`mvv_contacts_ranges`.`contact_id` IN (:contact_ids)";
+ } else {
+ $params = [
+ ':fach_id' => $fach_id,
+ ':contact_ids' => $contact_ids
+ ];
+ $where = "`fach`.`fach_id` = :fach_id
+ AND `mvv_contacts_ranges`.`contact_id` IN (:contact_ids)";
+ }
+ $query = "SELECT `counting`.`fach_id`, COUNT(DISTINCT `counting`.`contact_id`)
+ FROM (
+ SELECT `fach_id`, `contact_id`
+ FROM `fach`
+ JOIN `mvv_stgteil` USING (`fach_id`)
+ JOIN `mvv_contacts_ranges`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_stgteil`.`stgteil_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'StudiengangTeil'
+ )
+ WHERE {$where}
+
+ UNION ALL
+
+ SELECT `fach_id`, `contact_id`
+ FROM `fach`
+ JOIN `mvv_stgteil` USING (`fach_id`)
+ JOIN `mvv_stg_stgteil` USING (`stgteil_id`)
+ JOIN `mvv_studiengang` USING (`studiengang_id`)
+ JOIN `mvv_contacts_ranges`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_studiengang`.`studiengang_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Studiengang'
+ )
+ WHERE {$where}
+
+ UNION ALL
+
+ SELECT `fach_id`, `contact_id`
+ FROM `fach`
+ JOIN `mvv_stgteil` USING (`fach_id`)
+ JOIN `mvv_stgteilversion` USING (`stgteil_id`)
+ JOIN `mvv_stgteilabschnitt` USING (`version_id`)
+ JOIN `mvv_stgteilabschnitt_modul` USING (`abschnitt_id`)
+ JOIN `mvv_contacts_ranges`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_stgteilabschnitt_modul`.`modul_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Modul'
+ )
+ WHERE {$where}
+ ) AS `counting`
+ GROUP BY `counting`.`fach_id`";
+ return DBManager::get()->fetchPairs($query, $params);
+ }
+
+ /**
+ * Returns the ids of the contacts related to the given subject id.
+ *
+ * @param string $fach_id The id of the selected subject.
+ * @return array The ids of the contacts related to the subject.
+ */
+ private function findContactIdsByFach(string $fach_id): array
+ {
+ $query = "SELECT `mvv_contacts_ranges`.`contact_id`
+ FROM `mvv_contacts_ranges`
+ JOIN `mvv_stgteilabschnitt_modul`
+ ON (
+ `mvv_stgteilabschnitt_modul`.`modul_id` = `mvv_contacts_ranges`.`range_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Modul'
+ )
+ JOIN `mvv_stgteilabschnitt` USING (`abschnitt_id`)
+ JOIN `mvv_stgteilversion` USING (`version_id`)
+ JOIN `mvv_stgteil` USING (`stgteil_id`)
+ WHERE `mvv_stgteil`.`fach_id` = :fach_id
+
+ UNION
+
+ SELECT `mvv_contacts_ranges`.`contact_id`
+ FROM `mvv_contacts_ranges`
+ JOIN `mvv_studiengang`
+ ON (
+ `mvv_studiengang`.`studiengang_id` = `mvv_contacts_ranges`.`range_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Studiengang'
+ )
+ JOIN `mvv_stg_stgteil` USING (`studiengang_id`)
+ JOIN `mvv_stgteil` USING (`stgteil_id`)
+ WHERE `mvv_stgteil`.`fach_id` = :fach_id
+
+ UNION
+
+ SELECT `mvv_contacts_ranges`.`contact_id`
+ FROM `mvv_contacts_ranges`
+ JOIN `mvv_stgteil`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_stgteil`.`stgteil_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'StudiengangTeil'
+ )
+ WHERE `mvv_stgteil`.`fach_id` = :fach_id";
+
+ return DBManager::get()->fetchFirst($query, [':fach_id' => $fach_id]);
+ }
+
+ /**
+ * Returns the number of contacts grouped by degrees for given contact ids.
+ *
+ * @param array $contact_ids The ids of the contacts.
+ * @param string $abschluss_id The id of the selected degree.
+ * @return array Number of contacts grouped by degrees.
+ */
+ private function countAbschluesse(array $contact_ids, string $abschluss_id): array
+ {
+ if ($abschluss_id === '') {
+ $params = [':contact_ids' => $contact_ids];
+ $where = "`mvv_contacts_ranges`.`contact_id` IN (:contact_ids)";
+ } else {
+ $params = [
+ ':abschluss_id' => $abschluss_id,
+ ':contact_ids' => $contact_ids
+ ];
+ $where = "`abschluss`.`abschluss_id` = :abschluss_id
+ AND `mvv_contacts_ranges`.`contact_id` IN (:contact_ids)";
+ }
+ $query = "SELECT `counting`.`abschluss_id`, COUNT(DISTINCT `counting`.`contact_id`)
+ FROM (
+ SELECT `abschluss_id`, `contact_id`
+ FROM `abschluss`
+ JOIN `mvv_studiengang` USING (`abschluss_id`)
+ JOIN `mvv_stg_stgteil` USING (`studiengang_id`)
+ JOIN `mvv_stgteil` USING (`stgteil_id`)
+ JOIN `mvv_contacts_ranges`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_stgteil`.`stgteil_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'StudiengangTeil'
+ )
+ WHERE {$where}
+
+ UNION ALL
+
+ SELECT `abschluss_id`, `contact_id`
+ FROM `abschluss`
+ JOIN `mvv_studiengang` USING (`abschluss_id`)
+ JOIN `mvv_contacts_ranges`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_studiengang`.`studiengang_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Studiengang'
+ )
+ WHERE {$where}
+
+ UNION ALL
+
+ SELECT `abschluss_id`, `contact_id`
+ FROM `abschluss`
+ JOIN `mvv_studiengang` USING (`abschluss_id`)
+ JOIN `mvv_stg_stgteil` USING (`studiengang_id`)
+ JOIN `mvv_stgteilversion` USING (`stgteil_id`)
+ JOIN `mvv_stgteilabschnitt` USING (`version_id`)
+ JOIN `mvv_stgteilabschnitt_modul` USING (`abschnitt_id`)
+ JOIN `mvv_contacts_ranges`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_stgteilabschnitt_modul`.`modul_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Modul'
+ )
+ WHERE {$where}
+ ) AS `counting`
+ GROUP BY `counting`.`abschluss_id`";
+
+ return DBManager::get()->fetchPairs($query, $params);
+ }
+
+ /**
+ * Returns the ids of the contacts related to the given degree id.
+ *
+ * @param string $abschluss_id The id of the selected degree.
+ * @return array The ids of the contacts related to the degree.
+ */
+ private function findContactIdsByAbschluss(string $abschluss_id): array
+ {
+ $query = "SELECT `mvv_contacts_ranges`.`contact_id`
+ FROM `mvv_contacts_ranges`
+ JOIN `mvv_stgteilabschnitt_modul`
+ ON (
+ `mvv_stgteilabschnitt_modul`.`modul_id` = `mvv_contacts_ranges`.`range_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Modul'
+ )
+ JOIN `mvv_stgteilabschnitt` USING (`abschnitt_id`)
+ JOIN `mvv_stgteilversion` USING (`version_id`)
+ JOIN `mvv_stg_stgteil` USING (`stgteil_id`)
+ JOIN `mvv_studiengang` USING (`studiengang_id`)
+ WHERE `mvv_studiengang`.`abschluss_id` = :abschluss_id
+
+ UNION
+
+ SELECT `mvv_contacts_ranges`.`contact_id`
+ FROM `mvv_contacts_ranges`
+ JOIN `mvv_studiengang`
+ ON (
+ `mvv_studiengang`.`studiengang_id` = `mvv_contacts_ranges`.`range_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'Studiengang'
+ )
+ WHERE `mvv_studiengang`.`abschluss_id` = :abschluss_id
+
+ UNION
+
+ SELECT `mvv_contacts_ranges`.`contact_id`
+ FROM `mvv_contacts_ranges`
+ JOIN `mvv_stgteil`
+ ON (
+ `mvv_contacts_ranges`.`range_id` = `mvv_stgteil`.`stgteil_id`
+ AND `mvv_contacts_ranges`.`range_type` = 'StudiengangTeil'
+ )
+ JOIN `mvv_stg_stgteil` USING (`stgteil_id`)
+ JOIN `mvv_studiengang` USING (`studiengang_id`)
+ WHERE `mvv_studiengang`.`abschluss_id` = :abschluss_id";
+
+ return DBManager::get()->fetchFirst($query, [':abschluss_id' => $abschluss_id]);
+ }
}