ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
QuestionsBrowserTable.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use ILIAS\Taxonomy\DomainService as TaxonomyService;
24use GuzzleHttp\Psr7\ServerRequest;
25use ILIAS\Data\Factory as DataFactory;
32use ILIAS\UI\Factory as UIFactory;
33use ILIAS\UI\Renderer as UIRenderer;
36use Psr\Http\Message\ServerRequestInterface;
38
40{
41 public const ACTION_INSERT = 'insert';
42
43 public function __construct(
44 private readonly string $table_id,
45 private readonly \ilObjUser $current_user,
46 private readonly UIFactory $ui_factory,
47 private readonly UIRenderer $ui_renderer,
48 private readonly \ilLanguage $lng,
49 private readonly \ilCtrl $ctrl,
50 private readonly DataFactory $data_factory,
51 private readonly \ilAssQuestionList $question_list,
52 private readonly TaxonomyService $taxonomy,
53 private readonly string $parent_title
54 ) {
55 }
56
57 public function getComponent(ServerRequestInterface $request, ?array $filter): Data
58 {
59 return $this->ui_factory->table()->data(
60 $this,
61 $this->lng->txt('list_of_questions'),
62 $this->getColumns(),
63 )->withId($this->table_id)
64 ->withActions($this->getActions())
65 ->withRequest($request)
66 ->withFilter($filter);
67 }
68
69 public function getColumns(): array
70 {
71 $column_factory = $this->ui_factory->table()->column();
72 $icon_factory = $this->ui_factory->symbol()->icon();
73 $iconYes = $icon_factory->custom('assets/images/standard/icon_checked.svg', 'yes');
74 $iconNo = $icon_factory->custom('assets/images/standard/icon_unchecked.svg', 'no');
75
76 $columns = [
77 'title' => $column_factory->text(
78 $this->lng->txt('tst_question_title')
79 )->withIsOptional(false, true),
80 'description' => $column_factory->text(
81 $this->lng->txt('description')
82 )->withIsOptional(true, true),
83 'type_tag' => $column_factory->text(
84 $this->lng->txt('tst_question_type')
85 )->withIsOptional(false, true),
86 'points' => $column_factory->number(
87 $this->lng->txt('points')
88 )->withIsOptional(false, true),
89 'author' => $column_factory->text(
90 $this->lng->txt('author')
91 )->withIsOptional(true, false),
92 'lifecycle' => $column_factory->text(
93 $this->lng->txt('qst_lifecycle')
94 )->withIsOptional(true, false),
95 'parent_title' => $column_factory->text(
96 $this->lng->txt($this->parent_title)
97 )->withIsOptional(false, true),
98 'taxonomies' => $column_factory->text(
99 $this->lng->txt('qpl_settings_subtab_taxonomies')
100 )->withIsOptional(false, true),
101 'feedback' => $column_factory->boolean(
102 $this->lng->txt('feedback'),
103 $iconYes,
104 $iconNo
105 )->withIsOptional(true, false),
106 'created' => $column_factory->date(
107 $this->lng->txt('created'),
108 $this->current_user->getDateTimeFormat()
109 )->withIsOptional(true, false),
110 'tstamp' => $column_factory->date(
111 $this->lng->txt('updated'),
112 $this->current_user->getDateTimeFormat()
113 )->withIsOptional(true, false)
114 ];
115
116 return array_map(static fn(Column $column): Column => $column->withIsSortable(true), $columns);
117 }
118
119 public function getActions(): array
120 {
121 return [self::ACTION_INSERT => $this->getInsertAction()];
122 }
123
124 private function getInsertAction(): TableAction
125 {
126 $url_builder = new URLBuilder($this->data_factory->uri(
127 ServerRequest::getUriFromGlobals() . $this->ctrl->getLinkTargetByClass(
128 ilTestQuestionBrowserTableGUI::class,
130 )
131 ));
132
133 [$url_builder, $row_id_token] = $url_builder->acquireParameters(['qlist'], 'q_id');
134
135 return $this->ui_factory->table()->action()->standard(
136 $this->lng->txt('tst_insert_in_test'),
137 $url_builder,
138 $row_id_token
139 );
140 }
141
142 public function getRows(
143 DataRowBuilder $row_builder,
144 array $visible_column_ids,
146 Order $order,
147 ?array $filter_data,
148 ?array $additional_parameters
149 ): \Generator {
150 $timezone = new \DateTimeZone($this->current_user->getTimeZone());
151 foreach ($this->loadRecords($filter_data ?? [], $order, $range) as $record) {
152 $question_id = $record['question_id'];
153
154 $record['type_tag'] = $this->lng->txt($record['type_tag']);
155 $record['complete'] = (bool) $record['complete'];
156 $record['lifecycle'] = \ilAssQuestionLifecycle::getInstance($record['lifecycle'])->getTranslation($this->lng) ?? '';
157
158 $record['created'] = (new \DateTimeImmutable("@{$record['created']}"))->setTimezone($timezone);
159 $record['tstamp'] = (new \DateTimeImmutable("@{$record['tstamp']}"))->setTimezone($timezone);
160 $record['taxonomies'] = $this->resolveTaxonomiesRowData($record['obj_fi'], $question_id);
161
162 yield $row_builder->buildDataRow((string) $question_id, $record);
163 }
164 }
165
166 public function getTotalRowCount(?array $filter_data, ?array $additional_parameters): int
167 {
168 $filter_data ??= [];
169 $this->addFiltersToQuestionList($filter_data);
170 return $this->question_list->getTotalRowCount($filter_data, $additional_parameters);
171 }
172
173 public function loadRecords(array $filters = [], ?Order $order = null, ?Range $range = null): array
174 {
175 $this->addFiltersToQuestionList($filters);
176
177 $this->question_list->setOrder($order);
178 $this->question_list->setRange($range);
179 $this->question_list->load();
180
181 return $this->question_list->getQuestionDataArray();
182 }
183
184 private function addFiltersToQuestionList(array $filters): void
185 {
186 foreach (array_filter($filters) as $key => $filter) {
187 if ($key === 'commented') {
188 $this->question_list->setCommentFilter((int) $filter);
189 continue;
190 }
191
192 $this->question_list->addFieldFilter($key, $filter);
193 }
194 }
195
196 private function resolveTaxonomiesRowData(int $obj_fi, int $questionId): string
197 {
198 $available_taxonomy_ids = $this->taxonomy->getUsageOfObject($obj_fi);
199 $data = $this->loadTaxonomyAssignmentData($obj_fi, $questionId, $available_taxonomy_ids);
200
201 $taxonomies = [];
202
203 foreach ($data as $taxonomyId => $taxData) {
204 $taxonomies[] = \ilObject::_lookupTitle($taxonomyId);
205 $taxonomies[] = $this->ui_renderer->render(
206 $this->ui_factory->listing()->unordered(
207 array_map(static function ($node) {
208 return \ilTaxonomyNode::_lookupTitle($node['node_id']);
209 }, $taxData)
210 )
211 );
212 }
213
214 return implode('', $taxonomies);
215 }
216
217 private function loadTaxonomyAssignmentData(int $parentObjId, int $questionId, array $available_taxonomy_ids): array
218 {
219 $taxonomyAssignmentData = [];
220
221 foreach ($available_taxonomy_ids as $taxId) {
222 $taxTree = new \ilTaxonomyTree($taxId);
223 $assignments = (new \ilTaxNodeAssignment(
224 'qpl',
225 $parentObjId,
226 'quest',
227 $taxId
228 ))->getAssignmentsOfItem($questionId);
229
230 foreach ($assignments as $assData) {
231 $taxId = $assData['tax_id'];
232 if (!isset($taxonomyAssignmentData[$taxId])) {
233 $taxonomyAssignmentData[$taxId] = [];
234 }
235
236 $nodeId = $assData['node_id'];
237 $assData['node_lft'] = $taxTree->getNodeData($nodeId)['lft'];
238 $taxonomyAssignmentData[$taxId][$nodeId] = $assData;
239 }
240 }
241
242 return $taxonomyAssignmentData;
243 }
244}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
Both the subject and the direction need to be specified when expressing an order.
Definition: Order.php:29
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:29
loadTaxonomyAssignmentData(int $parentObjId, int $questionId, array $available_taxonomy_ids)
getTotalRowCount(?array $filter_data, ?array $additional_parameters)
Mainly for the purpose of pagination-support, it is important to know about the total number of recor...
__construct(private readonly string $table_id, private readonly \ilObjUser $current_user, private readonly UIFactory $ui_factory, private readonly UIRenderer $ui_renderer, private readonly \ilLanguage $lng, private readonly \ilCtrl $ctrl, private readonly DataFactory $data_factory, private readonly \ilAssQuestionList $question_list, private readonly TaxonomyService $taxonomy, private readonly string $parent_title)
loadRecords(array $filters=[], ?Order $order=null, ?Range $range=null)
getRows(DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, ?array $filter_data, ?array $additional_parameters)
This is called by the table to retrieve rows; map data-records to rows using the $row_builder e....
getComponent(ServerRequestInterface $request, ?array $filter)
Class ilCtrl provides processing control methods.
language handling
User class.
static _lookupTitle(int $obj_id)
@ilCtrl_Calls ilTestQuestionBrowserTableGUI: ilFormPropertyDispatchGUI
A Column describes the form of presentation for a certain aspect of data, i.e.
Definition: Column.php:28
buildDataRow(string $id, array $record)
This describes a Data Table.
Definition: Data.php:31
withId(string $id)
The DataTable comes with a storage to keep e.g.
An entity that renders components to a string output.
Definition: Renderer.php:31
global $lng
Definition: privfeed.php:31