From 00dd77ab6d5763d93999f00250cb5e6f4de12e9c Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms Date: Tue, 26 Aug 2025 08:53:09 +0200 Subject: fix filters for select and boolean, fix filtering for deleted datafields, use default as well, some cleanup --- app/controllers/admin/courses.php | 11 +++++++-- lib/classes/AdminCourseFilter.php | 44 +++++++++++++++++++++++++++------ lib/classes/DataFieldSelectboxEntry.php | 5 ++-- lib/models/DataField.php | 21 ++++++++++++++-- templates/datafields/selectbox.php | 24 +++++++++++++++--- 5 files changed, 87 insertions(+), 18 deletions(-) diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php index 426f25a..32081e3 100644 --- a/app/controllers/admin/courses.php +++ b/app/controllers/admin/courses.php @@ -59,7 +59,7 @@ class Admin_CoursesController extends AuthenticatedController URLHelper::getURL( 'dispatch.php/admin/courses/index' ), - ['onclick' => "$(this).toggleClass(['options-checked', 'options-unchecked']); STUDIP.AdminCourses.App.changeFilter({'df_".$datafield->id."': $(this).hasClass('options-checked') ? 1 : 0}); return false;"] + ['onclick' => "$(this).toggleClass(['options-checked', 'options-unchecked']); STUDIP.AdminCourses.App.changeFilter({'df_".$datafield->id."': $(this).hasClass('options-checked') ? 1 : ''}); return false;"] ); return $checkboxWidget; } elseif ($entry instanceof DataFieldSelectboxEntry) { @@ -333,11 +333,17 @@ class Admin_CoursesController extends AuthenticatedController 'teacher_filter' => $configuration->ADMIN_COURSES_TEACHERFILTER, ] ); + $filters = array_filter( + $filters, + function ($value): bool { + return isset($value) && $value !== ''; + } + ); return [ 'setActivatedFields' => $this->getFilterConfig(), 'setActionArea' => $configuration->MY_COURSES_ACTION_AREA ?? '1', - 'setFilter' => array_filter($filters), + 'setFilter' => $filters, ]; } @@ -602,6 +608,7 @@ class Admin_CoursesController extends AuthenticatedController isset($filters[$key]) && $filters[$key] !== '' && in_array($datafield->id, $activeSidebarElements['datafields']) + && $filters[$key] != $datafield->default_value ) { $datafields_filters[$datafield->id] = $filters[$key]; } else { diff --git a/lib/classes/AdminCourseFilter.php b/lib/classes/AdminCourseFilter.php index bdb84d2..04d7d17 100644 --- a/lib/classes/AdminCourseFilter.php +++ b/lib/classes/AdminCourseFilter.php @@ -157,14 +157,42 @@ class AdminCourseFilter if (!$reset_settings) { $datafields_filters = $GLOBALS['user']->cfg->ADMIN_COURSES_DATAFIELDS_FILTERS; - foreach ($datafields_filters as $datafield_id => $value) { - $this->query->join('de_'.$datafield_id, 'datafields_entries', 'de_'.$datafield_id.'.range_id = seminare.Seminar_id AND `de_'.$datafield_id.'`.datafield_id = :de_'.$datafield_id.'_id'); - $this->query->where('de_' . $datafield_id . '_contents', 'de_' . $datafield_id . '.`content` LIKE :de_' . $datafield_id . '_content', - [ - 'de_' . $datafield_id . '_id' => $datafield_id, - 'de_' . $datafield_id . '_content' => '%' . $value . '%' - ]); - } + + DataField::findEachMany( + function (DataField $datafield) use (&$datafields_filters) { + $this->query->join( + "de_{$datafield->id}", + 'datafields_entries', + "de_{$datafield->id}.range_id = seminare.Seminar_id AND `de_{$datafield->id}`.datafield_id = :de_{$datafield->id}_id" + ); + $this->query->join( + "dd_{$datafield->id}", + 'datafields', + "dd_{$datafield->id}.datafield_id = de_{$datafield->id}.datafield_id" + ); + + if ($datafield->isNumericType()) { + $this->query->where( + "de_{$datafield->id}_contents", + "IFNULL(de_{$datafield->id}.`content`, dd_{$datafield->id}.`default_value`) = :de_{$datafield->id}_content", + [ + "de_{$datafield->id}_id" => $datafield->id, + "de_{$datafield->id}_content" => $datafields_filters[$datafield->id] + ] + ); + } else { + $this->query->where( + "de_{$datafield->id}_contents", + "IFNULL(de_{$datafield->id}.`content`, dd_{$datafield->id}.`default_value`) LIKE :de_{$datafield->id}_content", + [ + "de_{$datafield->id}_id" => $datafield->id, + "de_{$datafield->id}_content" => '%' . $datafields_filters[$datafield->id] . '%' + ] + ); + } + }, + array_keys($datafields_filters) + ); } } diff --git a/lib/classes/DataFieldSelectboxEntry.php b/lib/classes/DataFieldSelectboxEntry.php index 4c9c890..4a1cc02 100644 --- a/lib/classes/DataFieldSelectboxEntry.php +++ b/lib/classes/DataFieldSelectboxEntry.php @@ -92,8 +92,9 @@ class DataFieldSelectboxEntry extends DataFieldEntry public function getDisplayValue($entities = true) { $value = $this->is_assoc_param - ? $this->type_param[$this->getValue()] - : $this->getValue(); + ? $this->type_param[$this->getValue()] ?? '' + : $this->getValue(); + return $entities ? htmlReady($value) : $value; } } diff --git a/lib/models/DataField.php b/lib/models/DataField.php index a4b6f95..4f8ca36 100644 --- a/lib/models/DataField.php +++ b/lib/models/DataField.php @@ -264,6 +264,25 @@ class DataField extends SimpleORMap implements PrivacyObject } /** + * Returns whether this datafield is of a numeric type. + */ + public function isNumericType(): bool + { + if ($this->type === 'bool') { + return true; + } + + $entry = DataFieldEntry::createDataFieldEntry($this); + if (!$entry instanceof DataFieldSelectboxEntry) { + return false; + } + + [, $is_assoc] = $entry->getParameters(); + + return $is_assoc; + } + + /** * Export available data of a given user into a storage object * (an instance of the StoredUserData class) for that user. * @@ -287,6 +306,4 @@ class DataField extends SimpleORMap implements PrivacyObject } } } - - } diff --git a/templates/datafields/selectbox.php b/templates/datafields/selectbox.php index 0cc263e..177cc59 100644 --- a/templates/datafields/selectbox.php +++ b/templates/datafields/selectbox.php @@ -1,3 +1,14 @@ +