19 declare(strict_types=1);
50 protected int $parent_obj_id,
51 protected int $request_ref_id
55 if ($this->taxonomy) {
62 return $this->ui_factory->table()->data(
63 $this->
lng->txt(
'questions'),
68 ->withId(
'qpt' . $this->parent_obj_id .
'_' . $this->request_ref_id);
77 $lifecycle_options = array_merge(
78 [
'' => $this->
lng->txt(
'qst_lifecycle_filter_all')],
81 $question_type_options = [
82 '' => $this->
lng->txt(
'filter_all_question_types')
85 foreach ($question_types as $translation => $row) {
86 $question_type_options[$row[
'type_tag']] = $translation;
89 $field_factory = $this->ui_factory->input()->field();
91 'title' => $field_factory->text($this->
lng->txt(
"title")),
92 'description' => $field_factory->text($this->lng->txt(
"description")),
93 'author' => $field_factory->text($this->lng->txt(
"author")),
94 'lifecycle' => $field_factory->select($this->lng->txt(
"qst_lifecycle"), $lifecycle_options),
95 'type' => $field_factory->select($this->lng->txt(
"type"), $question_type_options),
96 'commented' => $field_factory->select(
97 $this->lng->txt(
"ass_comments"),
105 if ($this->taxonomy) {
106 $taxs = $this->taxonomy->getUsageOfObject($this->parent_obj_id,
true);
107 $tax_filter_options = [
108 'null' =>
'<b>' . $this->
lng->txt(
'tax_filter_notax') .
'</b>' 111 foreach ($taxs as $tax_entry) {
113 $tax_tree = $tax->getTree();
115 $children = $this->
taxNodeReader($tax_tree, $sortfield, $tax_tree->readRootId());
116 $nodes = implode(
'-', array_map(fn($node) => $node[
'obj_id'], $children));
118 $tax_id = $tax_entry[
'tax_id'] .
'-0-' . $nodes;
119 $tax_title =
'<b>' . $tax_entry[
'title'] .
'</b>';
120 $tax_filter_options[$tax_id] = $tax_title;
122 foreach ($children as $subtax) {
123 $stax_id = $subtax[
'tax_id'] .
'-' . $subtax[
'obj_id'];
124 $stax_title = str_repeat(
' ', ($subtax[
'depth'] - 2) * 2)
125 .
' └─ ' 128 $tax_filter_options[$stax_id] = $stax_title;
131 $filter_inputs[
'taxonomies'] = $field_factory->multiSelect($this->
lng->txt(
"tax_filter"), $tax_filter_options);
134 $active = array_fill(0, count($filter_inputs),
true);
136 $filter = $ui_service->
filter()->standard(
137 "question_table_filter_id",
150 $f = $this->ui_factory->table()->column();
151 $df = $this->data_factory->dateFormat();
152 $date_format = $df->withTime24($this->data_factory->dateFormat()->germanShort());
153 $icon_yes = $this->ui_factory->symbol()->icon()->custom(
ilUtil::getImagePath(
'standard/icon_checked.svg'),
'yes');
154 $icon_no = $this->ui_factory->symbol()->icon()->custom(
ilUtil::getImagePath(
'standard/icon_unchecked.svg'),
'no');
157 'title' =>
$f->link($this->
lng->txt(
'title')),
158 'description' =>
$f->text($this->lng->txt(
'description'))->withIsOptional(
true,
true),
159 'ttype' =>
$f->text($this->
lng->txt(
'question_type'))->withIsOptional(
true,
true),
160 'points' =>
$f->number($this->
lng->txt(
'points'))->withDecimals(2)->withIsOptional(
true,
true),
161 'author' =>
$f->text($this->
lng->txt(
'author'))->withIsOptional(
true,
true),
162 'lifecycle' =>
$f->text($this->
lng->txt(
'qst_lifecycle'))->withIsOptional(
true,
true),
164 if ($this->taxonomy) {
165 $cols[
'taxonomies'] =
$f->text($this->
lng->txt(
'qpl_settings_subtab_taxonomies'))->withIsOptional(
true,
true);
167 $cols = array_merge($cols, [
168 'feedback' =>
$f->boolean($this->lng->txt(
'feedback'), $icon_yes, $icon_no)->withIsOptional(
true,
true),
169 'hints' =>
$f->boolean($this->
lng->txt(
'hints'), $icon_yes, $icon_no)->withIsOptional(
true,
true),
170 'created' =>
$f->date($this->
lng->txt(
'create_date'), $date_format)->withIsOptional(
true,
true),
171 'tstamp' =>
$f->date($this->
lng->txt(
'last_update'), $date_format)->withIsOptional(
true,
true),
172 'comments' =>
$f->number($this->
lng->txt(
'comments'))->withIsOptional(
true,
false),
179 $hop = array_shift($stack);
183 if (! array_key_exists($hop, $pointer)) {
186 $this->
treeify($pointer[$hop], $stack);
192 foreach ($nodes as $k => $n) {
199 return $this->ui_renderer->render(
200 $this->ui_factory->listing()->unordered($entries)
207 $nodes = $tree->getChildsByTypeFilter($node_id, [
'taxn']);
210 fn(
$a,
$b) => strcmp(
211 (
string)
$a[$sortfield],
212 (
string)
$b[$sortfield]
216 foreach ($nodes as $node) {
218 foreach ($this->
taxNodeReader($tree, $sortfield, $node[
'obj_id']) as
$c) {
227 array $stored_tax_data,
231 $tax_tree = $tax->getTree();
233 $taxnodes = $this->
taxNodeReader($tax_tree, $sortfield, $tax_tree->readRootId());
236 foreach ($taxnodes as $taxnode) {
237 $taxdata = array_filter(
239 fn($data_child) => $data_child[
'node_id'] === $taxnode[
'obj_id']
242 foreach (array_keys($taxdata) as $node_obj_id) {
244 fn($n) => in_array($n[
'obj_id'], array_keys($stored_tax_data)) ? $check_marker . $n[
'title'] : $n[
'title'],
245 $tax_tree->getPathFull($node_obj_id),
256 $check = $this->ui_renderer->render(
257 $this->ui_factory->symbol()->icon()->custom(
ilUtil::getImagePath(
'standard/icon_checked.svg'),
'checked')
261 $taxs = $this->taxonomy->getUsageOfObject($this->parent_obj_id,
true);
262 foreach ($taxs as $tax_entry) {
263 $tax_id = $tax_entry[
'tax_id'];
264 if (!array_key_exists($tax_id, $taxonomy_data)) {
269 $taxonomy_data[$tax_id],
273 return implode(
'', $taxonomies);
278 array $visible_column_ids,
282 ?array $additional_parameters
284 $no_write_access = !($this->
rbac->checkAccess(
'write', $this->request_ref_id));
285 foreach ($this->
getData($order, $range) as $idx => $record) {
286 $row_id = (string) $record[
'question_id'];
287 $record[
'created'] = (new \DateTimeImmutable())->setTimestamp($record[
'created']);
288 $record[
'tstamp'] = (new \DateTimeImmutable())->setTimestamp($record[
'tstamp']);
290 $record[
'lifecycle'] =
$lifecycle->getTranslation($this->
lng);
292 $title = $record[
'title'];
293 $to_question = $this->url_builder
294 ->withParameter($this->action_parameter_token,
'preview')
295 ->withParameter($this->row_id_token, $row_id)
296 ->buildURI()->__toString();
297 if (!(
bool) $record[
'complete']) {
298 $title .=
' (' . $this->
lng->txt(
'warning_question_not_complete') .
')';
300 $record[
'title'] = $this->ui_factory->link()->standard($title, $to_question);
301 if ($this->taxonomy) {
305 yield $row_builder->buildDataRow($row_id, $record)
306 ->withDisabledAction(
'move', $no_write_access)
307 ->withDisabledAction(
'copy', $no_write_access)
308 ->withDisabledAction(
'delete', $no_write_access)
309 ->withDisabledAction(
'feedback', $no_write_access)
310 ->withDisabledAction(
'hints', $no_write_access)
317 ?array $additional_parameters
329 [$offset, $length] = $range->
unpack();
330 $length = $length > 0 ? $length : null;
331 return array_slice(
$data, $offset, $length);
351 protected function buildAction(
string $act,
string $type,
bool $async =
false): array
353 $action = $this->ui_factory->table()->action()
355 $this->
lng->txt($act),
356 $this->url_builder->withParameter($this->action_parameter_token, $act),
360 $action = $action->withAsync(
true);
363 return [$act => $action];
368 [$aspect, $direction] = $order->join(
'',
function ($i, $k, $v) {
371 usort($list,
static function (array
$a, array
$b) use ($aspect):
int {
372 if (is_numeric($a[$aspect]) || is_bool($a[$aspect])) {
373 return $a[$aspect] <=> $b[$aspect];
375 if (is_array($a[$aspect])) {
376 return $a[$aspect] <=> $b[$aspect];
381 if ($a[$aspect] !== null) {
382 $aspect_a = $a[$aspect];
384 if ($b[$aspect] !== null) {
385 $aspect_b = $b[$aspect];
388 return strcmp($aspect_a, $aspect_b);
391 if ($direction === $order::DESC) {
392 $list = array_reverse($list);
399 return $this->notes_service->domain()->commentsActive($this->parent_obj_id)
400 || $this->
rbac->checkAccess(
'write', $this->request_ref_id);
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
taxonomyRepresentation(array $taxonomy_data)
static getInstance($identifier)
Readable part of repository interface to ilComponentDataDB.
getData(Order $order, Range $range)
This describes a Data Table.
Class ChatMainBarProvider .
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
const QUESTION_COMMENTED_ONLY
loadLanguageModule(string $a_module)
Load language module.
const QUESTION_COMMENTED_EXCLUDED
getTotalRowCount(?array $filter_data, ?array $additional_parameters)
Both the subject and the direction need to be specified when expressing an order. ...
static _lookupTitle(int $obj_id)
setParentObjId($parentObjId)
getFilter(ilUIService $ui_service, string $action)
Filters should be part of the Table; for now, since they are not fully integrated, they are rendered and applied seperately.
singleTaxonomyRepresentation(int $tax_id, array $stored_tax_data, string $check_marker)
getRows(Table\DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, ?array $filter_data, ?array $additional_parameters)
buildAction(string $act, string $type, bool $async=false)
toNestedList(array $nodes)
__construct(protected UIFactory $ui_factory, protected UIRenderer $ui_renderer, protected DataFactory $data_factory, protected Refinery $refinery, protected URLBuilder $url_builder, protected URLBuilderToken $action_parameter_token, protected URLBuilderToken $row_id_token, protected ilDBInterface $db, protected ilLanguage $lng, protected ilComponentRepository $component_repository, protected ilRbacSystem $rbac, protected ?TaxonomyService $taxonomy, protected NotesService $notes_service, protected int $parent_obj_id, protected int $request_ref_id)
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
treeify(&$pointer, $stack)
A simple class to express a range of whole positive numbers.
postOrder(array $list, \ILIAS\Data\Order $order)
static getDraftInstance()
taxNodeReader($tree, $sortfield, $node_id)
static _getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)
setAvailableTaxonomyIds($availableTaxonomyIds)
Refinery Factory $refinery