diff --git a/components/ILIAS/Test/src/Questions/Presentation/QuestionsBrowserTable.php b/components/ILIAS/Test/src/Questions/Presentation/QuestionsBrowserTable.php index 80cb7409eb49..8c86d902417f 100644 --- a/components/ILIAS/Test/src/Questions/Presentation/QuestionsBrowserTable.php +++ b/components/ILIAS/Test/src/Questions/Presentation/QuestionsBrowserTable.php @@ -80,7 +80,7 @@ public function getColumns(): array 'description' => $column_factory->text( $this->lng->txt('description') )->withIsOptional(true, true), - 'type_tag' => $column_factory->text( + 'question_type' => $column_factory->text( $this->lng->txt('tst_question_type') )->withIsOptional(false, true), 'points' => $column_factory->number( @@ -152,7 +152,7 @@ public function getRows( foreach ($this->loadRecords($filter_data ?? [], $order, $range) as $record) { $question_id = $record['question_id']; - $record['type_tag'] = $this->lng->txt($record['type_tag']); + $record['question_type'] = $record['question_type']; $record['complete'] = (bool) $record['complete']; $record['lifecycle'] = \ilAssQuestionLifecycle::getInstance($record['lifecycle'])->getTranslation($this->lng) ?? ''; diff --git a/components/ILIAS/TestQuestionPool/classes/class.ilAssQuestionList.php b/components/ILIAS/TestQuestionPool/classes/class.ilAssQuestionList.php index 31c6edfb9bae..026789f86f6a 100755 --- a/components/ILIAS/TestQuestionPool/classes/class.ilAssQuestionList.php +++ b/components/ILIAS/TestQuestionPool/classes/class.ilAssQuestionList.php @@ -72,6 +72,8 @@ class ilAssQuestionList implements ilTaxAssignedItemInfo protected array $questions = []; private ?Order $order = null; + private ?string $order_field = null; + private ?string $order_direction = null; private ?Range $range = null; public function __construct( @@ -86,6 +88,9 @@ public function __construct( public function setOrder(?Order $order = null): void { $this->order = $order; + ['order_field' => $order_field, 'order_direction' => $order_direction] = $this->getOrderFieldAndDirection(); + $this->order_field = $order_field; + $this->order_direction = $order_direction; } public function setRange(?Range $range = null): void @@ -368,10 +373,7 @@ private function getAnswerStatusFilterExpressions(): array private function getTableJoinExpression(): string { - $tableJoin = ' - INNER JOIN qpl_qst_type - ON qpl_qst_type.question_type_id = qpl_questions.question_type_fi - '; + $tableJoin = "INNER JOIN qpl_qst_type ON qpl_qst_type.question_type_id = qpl_questions.question_type_fi "; if ($this->join_obj_data) { $tableJoin .= ' @@ -428,7 +430,7 @@ private function getSelectFieldsExpression(): string { $select_fields = [ 'qpl_questions.*', - 'qpl_qst_type.type_tag', + 'qpl_qst_type.type_tag AS question_type', 'qpl_qst_type.plugin', 'qpl_qst_type.plugin_name', 'qpl_questions.points max_points' @@ -512,12 +514,37 @@ private function getHavingFilterExpression(): string } private function buildOrderQueryExpression(): string + { + return $this->order_field === null || $this->order_direction === null || $this->order_field === 'question_type' + ? '' + : " ORDER BY `$this->order_field` $this->order_direction"; + } + + private function buildLimitQueryExpression(): string { $order = $this->order; - if ($order === null) { + if ($order instanceof Order && $this->order_field === 'question_type') { return ''; } + $range = $this->range; + if ($range === null) { + return ''; + } + + $limit = max($range->getLength(), 0); + $offset = max($range->getStart(), 0); + + return " LIMIT $limit OFFSET $offset"; + } + + private function getOrderFieldAndDirection(): ?array + { + $order = $this->order; + if ($order === null) { + return ['order_field' => null, 'order_direction' => null]; + } + [$order_field, $order_direction] = $order->join( '', static fn(string $index, string $key, string $value): array => [$key, $value] @@ -528,20 +555,7 @@ private function buildOrderQueryExpression(): string $order_direction = Order::ASC; } - return " ORDER BY `$order_field` $order_direction"; - } - - private function buildLimitQueryExpression(): string - { - $range = $this->range; - if ($range === null) { - return ''; - } - - $limit = max($range->getLength(), 0); - $offset = max($range->getStart(), 0); - - return " LIMIT $limit OFFSET $offset"; + return ['order_field' => $order_field, 'order_direction' => $order_direction]; } private function buildQuery(): string @@ -573,7 +587,7 @@ public function load(): void $row['description'] = $tags_trafo->transform($row['description'] ?? ''); $row['author'] = $tags_trafo->transform($row['author']); $row['taxonomies'] = $this->loadTaxonomyAssignmentData($row['obj_fi'], $row['question_id']); - $row['ttype'] = $this->lng->txt($row['type_tag']); + $row['question_type'] = $this->lng->txt($row['question_type']); $row['feedback'] = $row['feedback'] === 1; $row['comments'] = $this->getNumberOfCommentsForQuestion($row['question_id']); @@ -586,6 +600,25 @@ public function load(): void $this->questions[$row['question_id']] = $row; } + + if ($this->order_field === 'question_type') { + $this->questions = $this->postLimit($this->postOrder($this->questions)); + } + } + + private function postOrder(array $questions): array + { + if ($this->order_field === 'question_type') { + usort($questions, fn(array $a, array $b): int => strcmp($a[$this->order_field], $b[$this->order_field])); + } + return $this->order_direction === Order::DESC ? array_reverse($questions) : $questions; + } + + private function postLimit(array $questions): array + { + return $this->range instanceof Range + ? array_slice($questions, $this->range->getStart(), $this->range->getLength()) + : $questions; } public function getTotalRowCount( diff --git a/components/ILIAS/TestQuestionPool/src/Questions/Presentation/QuestionTable.php b/components/ILIAS/TestQuestionPool/src/Questions/Presentation/QuestionTable.php index a7018262d284..40cbd4e17453 100755 --- a/components/ILIAS/TestQuestionPool/src/Questions/Presentation/QuestionTable.php +++ b/components/ILIAS/TestQuestionPool/src/Questions/Presentation/QuestionTable.php @@ -157,7 +157,7 @@ public function getColumns(): array return [ 'title' => $f->link($this->lng->txt('title')), 'description' => $f->text($this->lng->txt('description'))->withIsOptional(true, true), - 'ttype' => $f->text($this->lng->txt('question_type'))->withIsOptional(true, true), + 'question_type' => $f->text($this->lng->txt('question_type'))->withIsOptional(true, true), 'points' => $f->number($this->lng->txt('points'))->withDecimals(2)->withIsOptional(true, true), 'author' => $f->text($this->lng->txt('author'))->withIsOptional(true, true), 'lifecycle' => $f->text($this->lng->txt('qst_lifecycle'))->withIsOptional(true, true),