ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilLPObjectStatisticsTableGUI.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=0);
4 
29 {
30  protected ?array $preselected;
31 
35  public function __construct(
36  ?object $a_parent_obj,
37  string $a_parent_cmd,
38  ?array $a_preselect = null
39  ) {
40  $this->preselected = $a_preselect;
41 
42  $this->setId("lpobjstattbl");
43  parent::__construct($a_parent_obj, $a_parent_cmd);
44  }
45 
46  public function init(): void
47  {
48  $this->setShowRowsSelector(true);
49  $this->initFilter();
50 
51  $this->addColumn("", "", "1", true);
52  $this->addColumn($this->lng->txt("trac_title"), "title", '30%');
53 
54  $all_columns = $this->getSelectableColumns();
55  foreach ($this->getSelectedColumns() as $col_name => $col_info) {
56  $column_definition = $all_columns[$col_name];
57  $this->addColumn(
58  $column_definition['txt'],
59  $column_definition['sortable'] ? $column_definition['field'] : '',
60  $column_definition['width']
61  );
62  }
63  if (strpos($this->filter["yearmonth"], "-") === false) {
64  foreach ($this->getMonthsYear(
65  $this->filter["yearmonth"]
66  ) as $num => $caption) {
67  $this->addColumn($caption, "month_" . $num);
68  }
69  }
70  $this->addColumn($this->lng->txt("total"), "total");
71 
72  $this->setTitle($this->lng->txt("trac_object_stat_access"));
73 
74  // $this->setSelectAllCheckbox("item_id");
75  $this->addMultiCommand(
76  "showAccessGraph",
77  $this->lng->txt("trac_show_graph")
78  );
79  $this->setResetCommand("resetAccessFilter");
80  $this->setFilterCommand("applyAccessFilter");
81 
82  $this->setFormAction(
83  $this->ctrl->getFormAction(
84  $this->getParentObject(),
85  $this->getParentCmd()
86  )
87  );
88  $this->setRowTemplate(
89  "tpl.lp_object_statistics_row.html",
90  "Services/Tracking"
91  );
92  $this->setEnableHeader(true);
93  $this->setEnableNumInfo(true);
94  $this->setEnableTitle(true);
95  $this->setDefaultOrderField("title");
96  $this->setDefaultOrderDirection("asc");
97  $this->setExportFormats(array(self::EXPORT_EXCEL, self::EXPORT_CSV));
98  }
99 
100  public function getSelectableColumns(): array
101  {
102  $columns = [];
103  $columns['obj_id'] = [
104  'field' => 'obj_id',
105  'txt' => $this->lng->txt('object_id'),
106  'default' => false,
107  'optional' => true,
108  'sortable' => true,
109  'width' => '5%'
110  ];
111  $columns['reference_ids'] = [
112  'field' => 'reference_ids',
113  'txt' => $this->lng->txt('trac_reference_ids_column'),
114  'default' => false,
115  'optional' => true,
116  'sortable' => true,
117  'width' => '5%'
118  ];
119  $columns['paths'] = [
120  'field' => 'paths',
121  'txt' => $this->lng->txt('trac_paths'),
122  'default' => false,
123  'optional' => true,
124  'sortable' => false,
125  'width' => '25%'
126  ];
127  return $columns;
128  }
129 
130  public function numericOrdering(string $a_field): bool
131  {
132  $alphabetic_ordering = [
133  'title'
134  ];
135  if (!in_array($a_field, $alphabetic_ordering)) {
136  return true;
137  }
138  return false;
139  }
140 
144  public function initFilter(): void
145  {
146  $this->setDisableFilterHiding(true);
147  // object type selection
148  $si = new ilSelectInputGUI($this->lng->txt("obj_type"), "type");
149  $si->setOptions($this->getPossibleTypes(true, false, true));
150  $this->addFilterItem($si);
151  $si->readFromSession();
152  if (!$si->getValue()) {
153  $si->setValue("crs");
154  }
155  $this->filter["type"] = $si->getValue();
156 
157  // title/description
158  $ti = new ilTextInputGUI(
159  $this->lng->txt("trac_title_description"),
160  "query"
161  );
162  $ti->setMaxLength(64);
163  $ti->setSize(20);
164  $this->addFilterItem($ti);
165  $ti->readFromSession();
166  $this->filter["query"] = $ti->getValue();
167 
168  // read_count/spent_seconds
169  $si = new ilSelectInputGUI($this->lng->txt("trac_figure"), "figure");
170  $si->setOptions(
171  array("read_count" => $this->lng->txt("trac_read_count"),
172  "spent_seconds" => $this->lng->txt("trac_spent_seconds"),
173  "users" => $this->lng->txt("users")
174  )
175  );
176  $this->addFilterItem($si);
177  $si->readFromSession();
178  if (!$si->getValue()) {
179  $si->setValue("read_count");
180  }
181  $this->filter["measure"] = $si->getValue();
182 
183  // year/month
184  $si = new ilSelectInputGUI(
185  $this->lng->txt("year") . " / " . $this->lng->txt("month"),
186  "yearmonth"
187  );
188  $si->setOptions($this->getMonthsFilter());
189  $this->addFilterItem($si);
190  $si->readFromSession();
191  if (!$si->getValue()) {
192  $si->setValue(date("Y-m"));
193  }
194  $this->filter["yearmonth"] = $si->getValue();
195  $this->filter = $this->initRepositoryFilter($this->filter);
196  }
197 
198  protected function isForwardingToFormDispatcher(): bool
199  {
200  return true;
201  }
202 
203  public function getItems(): void
204  {
205  $data = array();
206  $objects = [];
207  if ($this->filter["type"] != "prtf") {
208  // JF, 2016-06-06
209  $objects = $this->searchObjects(
210  $this->getCurrentFilter(true),
211  "",
212  null,
213  false
214  );
215 
216  if ($this->filter["type"] == "blog") {
218  $this->filter["query"]
219  ) as $obj_id) {
220  $objects[$obj_id] = array($obj_id);
221  }
222  }
223  } else {
224  // portfolios are not part of repository
225  foreach (ilTrQuery::getPortfolios(
226  $this->filter["query"]
227  ) as $obj_id) {
228  $objects[$obj_id] = array($obj_id);
229  }
230  }
231 
232  if ($objects) {
233  $yearmonth = explode("-", $this->filter["yearmonth"]);
234  if (sizeof($yearmonth) == 1) {
236  $objects,
237  $yearmonth[0]
238  ) as $obj_id => $months) {
239  $data[$obj_id]["obj_id"] = $obj_id;
240  $data[$obj_id]["title"] = ilObject::_lookupTitle($obj_id);
241  $data[$obj_id]['reference_ids'] = $this->findReferencesForObjId($obj_id);
242 
243  foreach ($months as $month => $values) {
244  $idx = $yearmonth[0] . "-" . str_pad(
245  $month,
246  2,
247  "0",
248  STR_PAD_LEFT
249  );
250  $data[$obj_id]["month_" . $idx] = (int) ($values[$this->filter["measure"]] ?? 0);
251  $data[$obj_id]["total"] = ($data[$obj_id]["total"] ?? 0) + (int) ($values[$this->filter["measure"]] ?? 0);
252  }
253  }
254  } else {
256  $objects,
257  (string) $yearmonth[0],
258  (string) $yearmonth[1]
259  ) as $obj_id => $days) {
260  $data[$obj_id]["obj_id"] = $obj_id;
261  $data[$obj_id]["title"] = ilObject::_lookupTitle($obj_id);
262  $data[$obj_id]['reference_ids'] = $this->findReferencesForObjId($obj_id);
263 
264  foreach ($days as $day => $values) {
265  $data[$obj_id]["day_" . $day] = (int) ($values[$this->filter["measure"]] ?? 0);
266  $data[$obj_id]["total"] = ($data[$obj_id]["total"] ?? 0) + (int) ($values[$this->filter["measure"]] ?? 0);
267  }
268  }
269  }
270 
271  // add objects with no usage data
272  foreach (array_keys($objects) as $obj_id) {
273  if (!isset($data[$obj_id])) {
274  $data[$obj_id]["obj_id"] = $obj_id;
275  $data[$obj_id]["title"] = ilObject::_lookupTitle($obj_id);
276  $data[$obj_id]['reference_ids'] = $this->findReferencesForObjId($obj_id);
277  }
278  }
279  }
280  $this->setData($data);
281  }
282 
286  protected function findReferencesForObjId(int $a_obj_id): array
287  {
288  $ref_ids = array_keys(ilObject::_getAllReferences($a_obj_id));
289  sort($ref_ids, SORT_NUMERIC);
290  return $ref_ids;
291  }
292 
296  protected function fillRow(array $a_set): void
297  {
298  $type = ilObject::_lookupType($a_set["obj_id"]);
299 
300  $this->tpl->setVariable("OBJ_ID", $a_set["obj_id"]);
301  $this->tpl->setVariable(
302  "ICON_SRC",
303  ilObject::_getIcon(0, "tiny", $type)
304  );
305  $this->tpl->setVariable("ICON_ALT", $this->lng->txt($type));
306  $this->tpl->setVariable("TITLE_TEXT", $a_set["title"]);
307 
308  if ($this->preselected && in_array(
309  $a_set["obj_id"],
310  $this->preselected
311  )) {
312  $this->tpl->setVariable("CHECKBOX_STATE", " checked=\"checked\"");
313  }
314 
315  $sum = 0;
316  if (strpos($this->filter["yearmonth"], "-") === false) {
317  $this->tpl->setCurrentBlock("month");
318  foreach (array_keys(
319  $this->getMonthsYear($this->filter["yearmonth"])
320  ) as $num) {
321  $value = (int) ($a_set["month_" . $num] ?? 0);
322  if (($this->filter["measure"] ?? "") != "spent_seconds") {
323  $value = $this->anonymizeValue($value);
324  } else {
325  $value = $this->formatSeconds($value, true);
326  }
327  $this->tpl->setVariable("MONTH_VALUE", $value);
328  $this->tpl->parseCurrentBlock();
329  }
330  }
331 
332  if (($this->filter["measure"] ?? "") == "spent_seconds") {
333  $sum = $this->formatSeconds((int) ($a_set["total"] ?? 0), true);
334  } else {
335  $sum = $this->anonymizeValue((int) ($a_set["total"] ?? 0));
336  }
337  $this->tpl->setVariable("TOTAL", $sum);
338 
339  // optional columns
340  if ($this->isColumnSelected('obj_id')) {
341  $this->tpl->setVariable('OBJ_ID_COL_VALUE', (string) $a_set['obj_id']);
342  }
343  if ($this->isColumnSelected('reference_ids')) {
344  $this->tpl->setVariable('REF_IDS', (string) implode(', ', $a_set['reference_ids']));
345  }
346  if ($this->isColumnSelected('paths')) {
347  $paths = [];
348  foreach ($a_set['reference_ids'] as $reference_id) {
349  $path_gui = new ilPathGUI();
350  $path_gui->enableTextOnly(false);
351  $path_gui->enableHideLeaf(false);
352  $path_gui->setUseImages(true);
353  $paths[] = $path_gui->getPath(ROOT_FOLDER_ID, $reference_id);
354  }
355  $this->tpl->setVariable('PATHS', implode('<br /> ', $paths));
356  }
357  }
358 
359  public function getGraph(array $a_graph_items): string
360  {
361  $chart = ilChart::getInstanceByType(ilChart::TYPE_GRID, "objstacc");
362  $chart->setSize("700", "500");
363 
364  $legend = new ilChartLegend();
365  $chart->setLegend($legend);
366 
367  $max_value = 0;
368  foreach ($this->getData() as $object) {
369  if (in_array($object["obj_id"], $a_graph_items)) {
370  $series = $chart->getDataInstance(ilChartGrid::DATA_LINES);
371  $series->setLabel(ilObject::_lookupTitle($object["obj_id"]));
372 
373  if (strpos($this->filter["yearmonth"], "-") === false) {
374  foreach (array_keys(
375  $this->getMonthsYear(
376  $this->filter["yearmonth"]
377  )
378  ) as $idx => $num) {
379  $value = (int) ($object["month_" . $num] ?? 0);
380  $max_value = max($max_value, $value);
381  if ($this->filter["measure"] != "spent_seconds") {
382  $value = $this->anonymizeValue($value, true);
383  }
384  $series->addPoint($idx, $value);
385  }
386  } else {
387  for ($loop = 1; $loop < 32; $loop++) {
388  $value = (int) ($object["day_" . $loop] ?? 0);
389  $max_value = max($max_value, $value);
390  if ($this->filter["measure"] != "spent_seconds") {
391  $value = $this->anonymizeValue($value, true);
392  }
393  $series->addPoint($loop, $value);
394  }
395  }
396 
397  $chart->addData($series);
398  }
399  }
400 
401  $value_ticks = $this->buildValueScale(
402  $max_value,
403  ($this->filter["measure"] != "spent_seconds"),
404  ($this->filter["measure"] == "spent_seconds")
405  );
406 
407  $labels = array();
408  if (strpos($this->filter["yearmonth"], "-") === false) {
409  foreach (array_values(
410  $this->getMonthsYear($this->filter["yearmonth"], true)
411  ) as $idx => $caption) {
412  $labels[$idx] = $caption;
413  }
414  } else {
415  for ($loop = 1; $loop < 32; $loop++) {
416  $labels[$loop] = $loop . ".";
417  }
418  }
419  $chart->setTicks($labels, $value_ticks, true);
420 
421  return $chart->getHTML();
422  }
423 
424  protected function fillMetaExcel(ilExcel $a_excel, int &$a_row): void
425  {
426  }
427 
428  protected function fillRowExcel(
429  ilExcel $a_excel,
430  int &$a_row,
431  array $a_set
432  ): void {
433  $a_excel->setCell($a_row, 0, ilObject::_lookupTitle($a_set["obj_id"]));
434 
435  $col = 0;
436 
437  // optional columns
438  if ($this->isColumnSelected('obj_id')) {
439  $a_excel->setCell($a_row, ++$col, (string) $a_set['obj_id']);
440  }
441  if ($this->isColumnSelected('reference_ids')) {
442  $a_excel->setCell($a_row, ++$col, implode(', ', $a_set['reference_ids']));
443  }
444  if ($this->isColumnSelected('paths')) {
445  $paths = [];
446  foreach ($a_set['reference_ids'] as $reference_id) {
447  $path_gui = new ilPathGUI();
448  $path_gui->enableTextOnly(true);
449  $path_gui->enableHideLeaf(false);
450  $path_gui->setUseImages(false);
451  $paths[] = $path_gui->getPath(ROOT_FOLDER_ID, $reference_id);
452  }
453  /*
454  * The strings returned by the PathGUI have a linebreak at the end,
455  * which has to be removed or it messes up how the paths are displayed in excel.
456  */
457  $a_excel->setCell($a_row, ++$col, substr(implode(', ', $paths), 0, -1));
458  }
459 
460  if (strpos($this->filter["yearmonth"], "-") === false) {
461  foreach (array_keys(
462  $this->getMonthsYear($this->filter["yearmonth"])
463  ) as $num) {
464  $value = (int) ($a_set["month_" . $num] ?? 0);
465  if ($this->filter["measure"] != "spent_seconds") {
466  $value = $this->anonymizeValue($value);
467  }
468 
469  $a_excel->setCell($a_row, ++$col, $value);
470  }
471  }
472 
473  if ($this->filter["measure"] == "spent_seconds") {
474  // keep seconds
475  // $sum = $this->formatSeconds((int)$a_set["total"]);
476  $sum = (int) ($a_set["total"] ?? 0);
477  } else {
478  $sum = $this->anonymizeValue((int) ($a_set["total"] ?? 0));
479  }
480  $a_excel->setCell($a_row, ++$col, $sum);
481  }
482 
483  protected function fillMetaCSV(ilCSVWriter $a_csv): void
484  {
485  }
486 
487  protected function fillRowCSV(ilCSVWriter $a_csv, array $a_set): void
488  {
489  $a_csv->addColumn(ilObject::_lookupTitle($a_set["obj_id"]));
490 
491  // optional columns
492  if ($this->isColumnSelected('obj_id')) {
493  $a_csv->addColumn($a_set["obj_id"]);
494  }
495  if ($this->isColumnSelected('reference_ids')) {
496  $a_csv->addColumn(implode(', ', $a_set['reference_ids']));
497  }
498  if ($this->isColumnSelected('paths')) {
499  $paths = [];
500  foreach ($a_set['reference_ids'] as $reference_id) {
501  $path_gui = new ilPathGUI();
502  $path_gui->enableTextOnly(true);
503  $path_gui->enableHideLeaf(false);
504  $path_gui->setUseImages(false);
505  $paths[] = $path_gui->getPath(ROOT_FOLDER_ID, $reference_id);
506  }
507  /*
508  * The strings returned by the PathGUI have a linebreak at the end,
509  * which has to be removed or it messes up how the paths are displayed in excel.
510  */
511  $a_csv->addColumn(substr(implode(', ', $paths), 0, -1));
512  }
513 
514  if (strpos($this->filter["yearmonth"], "-") === false) {
515  foreach (array_keys(
516  $this->getMonthsYear($this->filter["yearmonth"])
517  ) as $num) {
518  $value = (int) ($a_set["month_" . $num] ?? 0);
519  if ($this->filter["measure"] != "spent_seconds") {
520  $value = $this->anonymizeValue($value);
521  }
522 
523  $a_csv->addColumn($value);
524  }
525  }
526 
527  if ($this->filter["measure"] == "spent_seconds") {
528  // keep seconds
529  // $sum = $this->formatSeconds((int)$a_set["total"]);
530  $sum = (int) ($a_set["total"] ?? 0);
531  } else {
532  $sum = $this->anonymizeValue((int) ($a_set["total"] ?? 0));
533  }
534  $a_csv->addColumn($sum);
535 
536  $a_csv->addRow();
537  }
538 }
buildValueScale(int $a_max_value, bool $a_anonymize=false, bool $a_format_seconds=false)
setData(array $a_data)
Creates a path for a start and endnode.
addColumn(string $a_col)
getPossibleTypes(bool $a_split_learning_resources=false, bool $a_include_digilib=false, bool $a_allow_undefined_lp=false)
getCurrentFilter(bool $as_query=false)
setExportFormats(array $formats)
Set available export formats.
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
setFormAction(string $a_form_action, bool $a_multipart=false)
addFilterItem(ilTableFilterItem $a_input_item, bool $a_optional=false)
$type
setEnableTitle(bool $a_enabletitle)
const ROOT_FOLDER_ID
Definition: constants.php:32
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setResetCommand(string $a_val, string $a_caption="")
getMonthsYear($a_year=null, $a_short=false)
searchObjects(array $filter, string $permission, ?array $preset_obj_ids=null, bool $a_check_lp_activation=true)
Search objects that match current filters.
static _getAllReferences(int $id)
get all reference ids for object ID
fillRowCSV(ilCSVWriter $a_csv, array $a_set)
setDisableFilterHiding(bool $a_val=true)
setCell(int $a_row, int $a_col, $a_value, ?string $a_datatype=null)
Set cell value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setId(string $a_val)
fillMetaExcel(ilExcel $a_excel, int &$a_row)
anonymizeValue($a_value, bool $a_force_number=false)
isColumnSelected(string $col)
setShowRowsSelector(bool $a_value)
Toggle rows-per-page selector.
static _lookupTitle(int $obj_id)
TableGUI class for learning progress.
static getWorkspaceBlogs(?string $a_title=null)
setDefaultOrderField(string $a_defaultorderfield)
setRowTemplate(string $a_template, string $a_template_dir="")
Set row template.
setFilterCommand(string $a_val, string $a_caption="")
fillRowExcel(ilExcel $a_excel, int &$a_row, array $a_set)
setDefaultOrderDirection(string $a_defaultorderdirection)
formatSeconds(int $seconds, bool $a_shorten_zero=false)
const TYPE_GRID
setTitle(string $a_title, string $a_icon="", string $a_icon_alt="")
initRepositoryFilter(array $filter)
setEnableNumInfo(bool $a_val)
getMonthsFilter($a_short=false)
__construct(Container $dic, ilPlugin $plugin)
static getPortfolios(?string $a_title=null)
addColumn(string $a_text, string $a_sort_field="", string $a_width="", bool $a_is_checkbox_action_column=false, string $a_class="", string $a_tooltip="", bool $a_tooltip_with_html=false)
static _lookupType(int $id, bool $reference=false)
static getObjectAccessStatistics(array $a_ref_ids, string $a_year, ?string $a_month=null)
addMultiCommand(string $a_cmd, string $a_text)
setEnableHeader(bool $a_enableheader)
__construct(?object $a_parent_obj, string $a_parent_cmd, ?array $a_preselect=null)
Constructor.
static getInstanceByType(int $a_type, string $a_id)