ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilTrMatrixTableGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once("./Services/Tracking/classes/class.ilLPTableBaseGUI.php");
5 
15 {
16  protected $obj_ids = NULL;
17  protected $objective_ids = NULL;
18  protected $sco_ids = NULL;
19  protected $subitem_ids = NULL;
20  protected $in_course; // int
21  protected $in_group; // int
22  protected $privacy_fields; // array
23  protected $privacy_cols = array(); // array
24 
28  function __construct($a_parent_obj, $a_parent_cmd, $ref_id)
29  {
30  global $ilCtrl, $lng, $tree;
31 
32  $this->setId("trsmtx_".$ref_id);
33  $this->ref_id = $ref_id;
34  $this->obj_id = ilObject::_lookupObjId($ref_id);
35 
36  $this->in_group = $tree->checkForParentType($this->ref_id, "grp");
37  if($this->in_group)
38  {
39  $this->in_group = ilObject::_lookupObjId($this->in_group);
40  }
41  else
42  {
43  $this->in_course = $tree->checkForParentType($this->ref_id, "crs");
44  if($this->in_course)
45  {
46  $this->in_course = ilObject::_lookupObjId($this->in_course);
47  }
48  }
49 
50  // has to be before constructor to work
51  $this->initFilter();
52 
53  parent::__construct($a_parent_obj, $a_parent_cmd);
54 
55  $this->setLimit(9999);
56  $this->parseTitle($this->obj_id, "trac_matrix");
57 
58  $this->setEnableHeader(true);
59  $this->setFormAction($ilCtrl->getFormActionByClass(get_class($this)));
60  $this->setRowTemplate("tpl.user_object_matrix_row.html", "Services/Tracking");
61  $this->setDefaultOrderField("login");
62  $this->setDefaultOrderDirection("asc");
63  $this->setShowTemplates(true);
64 
65  $this->addColumn($this->lng->txt("login"), "login");
66 
67  $labels = $this->getSelectableColumns();
68  $selected = $this->getSelectedColumns();
69  foreach ($selected as $c)
70  {
71  $title = $labels[$c]["txt"];
72 
73  if(isset($labels[$c]["no_permission"]) && (bool)$labels[$c]["no_permission"])
74  {
75  $title .= " (".$lng->txt("status_no_permission").")";
76  }
77 
78  $tooltip = "";
79  if(isset($labels[$c]["icon"]))
80  {
81  $alt = $lng->txt($labels[$c]["type"]);
82  $icon = '<img src="'.$labels[$c]["icon"].'" alt="'.$alt.'" />';
83  if(sizeof($selected) > 5)
84  {
85  $tooltip = $title;
86  $title = $icon;
87  }
88  else
89  {
90  $title = $icon.' '.$title;
91  }
92  }
93 
94  if(isset($labels[$c]["id"]))
95  {
96  $sort_id = $labels[$c]["id"];
97  }
98  else
99  {
100  // list cannot be sorted by udf fields (separate query)
101  $sort_id = (substr($c, 0, 4) == "udf_") ? "" : $c;
102  }
103 
104  $this->addColumn($title, $sort_id, "", false, "", $tooltip);
105  }
106 
107  $this->setExportFormats(array(self::EXPORT_CSV, self::EXPORT_EXCEL));
108  }
109 
110  function initFilter()
111  {
112  global $lng;
113 
114  $item = $this->addFilterItemByMetaType("name", ilTable2GUI::FILTER_TEXT);
115  $this->filter["name"] = $item->getValue();
116 
117  // #14949 - is called before constructor, so we have to do it ourselves
118  if(isset($_GET[$this->prefix."_tpl"]))
119  {
120  $this->filter["name"] = null;
121  $item->setValue(null);
122  }
123  }
124 
126  {
127  global $ilObjDataCache, $rbacsystem;
128 
129  $user_cols = $this->getSelectableUserColumns($this->in_course, $this->in_group);
130 
131  if($this->obj_ids === NULL)
132  {
133  // we cannot use the selected columns because they are not ready yet
134  // so we use all available columns, should be ok anyways
135  $this->obj_ids = $this->getItems(array_keys($user_cols[0]), $user_cols[1]);
136  }
137  if($this->obj_ids)
138  {
139  $tmp_cols = array();
140  foreach($this->obj_ids as $obj_id)
141  {
142  if($obj_id == $this->obj_id)
143  {
144  $parent = array("txt" => $this->lng->txt("status"),
145  "default" => true);
146  }
147  else
148  {
149  $no_perm = false;
150 
151  $ref_id = $this->ref_ids[$obj_id];
152  if($ref_id &&
153  !$rbacsystem->checkAccess('read_learning_progress', $ref_id))
154  {
155  $no_perm = true;
156  $this->privacy_cols[] = $obj_id;
157  }
158 
159  $title = $ilObjDataCache->lookupTitle($obj_id);
160  $type = $ilObjDataCache->lookupType($obj_id);
161  $icon = ilObject::_getIcon("", "tiny", $type);
162  if($type == "sess")
163  {
164  include_once "Modules/Session/classes/class.ilObjSession.php";
165  $sess = new ilObjSession($obj_id, false);
166  $title = $sess->getPresentationTitle();
167  }
168  $tmp_cols[strtolower($title)."#~#obj_".$obj_id] = array("txt" => $title, "icon" => $icon, "type" => $type, "default" => true, "no_permission" => $no_perm);
169  }
170  }
171  if(sizeof($this->objective_ids))
172  {
173  foreach($this->objective_ids as $obj_id => $title)
174  {
175  $tmp_cols[strtolower($title)."#~#objtv_".$obj_id] = array("txt" => $title, "default" => true);
176  }
177  }
178  if(sizeof($this->sco_ids))
179  {
180  foreach($this->sco_ids as $obj_id => $title)
181  {
182  $icon = ilUtil::getTypeIconPath("sco", $obj_id, "tiny");
183  $tmp_cols[strtolower($title)."#~#objsco_".$obj_id] = array("txt" => $title, "icon"=>$icon, "default" => true);
184  }
185  }
186  if(sizeof($this->subitem_ids))
187  {
188  foreach($this->subitem_ids as $obj_id => $title)
189  {
190  $icon = ilUtil::getTypeIconPath("st", $obj_id, "tiny");
191  $tmp_cols[strtolower($title)."#~#objsub_".$obj_id] = array("txt" => $title, "icon"=>$icon, "default" => true);
192  }
193  }
194 
195  // alex, 5 Nov 2011: Do not sort SCORM items or "chapters"
196  if(!sizeof($this->sco_ids) && !sizeof($this->subitem_ids))
197  {
198  ksort($tmp_cols);
199  }
200  foreach($tmp_cols as $id => $def)
201  {
202  $id = explode('#~#', $id);
203  $columns[$id[1]] = $def;
204  }
205  unset($tmp_cols);
206 
207  if($parent)
208  {
209  $columns["obj_".$this->obj_id] = $parent;
210  }
211  }
212 
213  unset($user_cols[0]["status"]);
214  unset($user_cols[0]["login"]);
215  foreach($user_cols[0] as $col_id => $col_def)
216  {
217  if(!isset($columns[$col_id]))
218  {
219  // these are all additional fields, no default
220  $col_def["default"] = false;
221  $columns[$col_id] = $col_def;
222  }
223  }
224 
225  return $columns;
226  }
227 
228  function getItems(array $a_user_fields, array $a_privary_fields = null)
229  {
230  include_once("./Services/Tracking/classes/class.ilTrQuery.php");
231  $collection = ilTrQuery::getObjectIds($this->obj_id, $this->ref_id, true);
232  if($collection["object_ids"])
233  {
234  // we need these for the timing warnings
235  $this->ref_ids = $collection["ref_ids"];
236 
237  // only if object is [part of] course/group
238  $check_agreement = false;
239  if($this->in_course)
240  {
241  // privacy (if course agreement is activated)
242  include_once "Services/PrivacySecurity/classes/class.ilPrivacySettings.php";
243  $privacy = ilPrivacySettings::_getInstance();
244  if($privacy->courseConfirmationRequired())
245  {
246  $check_agreement = $this->in_course;
247  }
248  }
249  else if($this->in_group)
250  {
251  // privacy (if group agreement is activated)
252  include_once "Services/PrivacySecurity/classes/class.ilPrivacySettings.php";
253  $privacy = ilPrivacySettings::_getInstance();
254  if($privacy->groupConfirmationRequired())
255  {
256  $check_agreement = $this->in_group;
257  }
258  }
259 
260  $data = ilTrQuery::getUserObjectMatrix($this->ref_id, $collection["object_ids"], $this->filter["name"], $a_user_fields, $a_privary_fields, $check_agreement);
261  if($collection["objectives_parent_id"] && $data["users"])
262  {
263  // sub-items: learning objectives
264  $objectives = ilTrQuery::getUserObjectiveMatrix($collection["objectives_parent_id"], $data["users"]);
265 
266  $this->objective_ids = array();
267 
268  foreach($objectives as $user_id => $objectives)
269  {
270  if(isset($data["set"][$user_id]))
271  {
272  foreach($objectives as $objective_id => $status)
273  {
274  $obj_id = "objtv_".$objective_id;
275  $data["set"][$user_id][$obj_id] = $status;
276 
277  if(!in_array($obj_id, $this->objective_ids))
278  {
279  $this->objective_ids[$objective_id] = ilCourseObjective::lookupObjectiveTitle($objective_id);
280  }
281  }
282  }
283  }
284  }
285 
286  // sub-items: SCOs
287  if($collection["scorm"] && $data["set"])
288  {
289  $this->sco_ids = array();
290  foreach(array_keys($data["set"]) as $user_id)
291  {
292  foreach($collection["scorm"]["scos"] as $sco)
293  {
294  if(!in_array($sco, $this->sco_ids))
295  {
296  $this->sco_ids[$sco] = $collection["scorm"]["scos_title"][$sco];
297  }
298 
299  // alex, 5 Nov 2011: we got users being in failed and in
300  // completed status, I changed the setting in: first check failed
301  // then check completed since failed should superseed completed
302  // (before completed has been checked before failed)
304  if(in_array($user_id, $collection["scorm"]["failed"][$sco]))
305  {
307  }
308  else if(in_array($user_id, $collection["scorm"]["completed"][$sco]))
309  {
311  }
312  else if(in_array($user_id, $collection["scorm"]["in_progress"][$sco]))
313  {
315  }
316 
317  $obj_id = "objsco_".$sco;
318  $data["set"][$user_id][$obj_id] = $status;
319  }
320  }
321  }
322 
323  // sub-items: generic, e.g. lm chapter
324  if($collection["subitems"] && $data["set"])
325  {
326  foreach(array_keys($data["set"]) as $user_id)
327  {
328  foreach($collection["subitems"]["items"] as $item_id)
329  {
330  $this->subitem_ids[$item_id] = $collection["subitems"]["item_titles"][$item_id];
331 
333  if(in_array($user_id, $collection["subitems"]["completed"][$item_id]))
334  {
336  }
337  else if(is_array($collection["subitems"]["in_progress"]) &&
338  in_array($user_id, $collection["subitems"]["in_progress"][$item_id]))
339  {
341  }
342 
343  $obj_id = "objsub_".$item_id;
344  $data["set"][$user_id][$obj_id] = $status;
345  }
346  }
347  }
348 
349  // percentage export
350  if($data["set"])
351  {
352  $this->perc_map = array();
353  foreach($data["set"] as $row)
354  {
355  foreach($row as $column => $value)
356  {
357  if(substr($column, -5) == "_perc")
358  {
359  if((int)$value > 0)
360  {
361  $obj_id = explode("_", $column);
362  $obj_id = (int)$obj_id[1];
363  $this->perc_map[$obj_id] = true;
364  }
365  }
366  }
367  }
368  }
369 
370  $this->setMaxCount($data["cnt"]);
371  $this->setData($data["set"]);
372 
373  return $collection["object_ids"];
374  }
375  return false;
376  }
377 
378  function fillRow(array $a_set)
379  {
380  global $lng;
381 
382  foreach ($this->getSelectedColumns() as $c)
383  {
384  switch($c)
385  {
386  case (substr($c, 0, 4) == "obj_"):
387  $obj_id = substr($c, 4);
388 
389  // object without read-lp-permission
390  if(in_array($obj_id, $this->privacy_cols) ||
391  $a_set["privacy_conflict"])
392  {
393  $this->tpl->setCurrentBlock("objects");
394  $this->tpl->setVariable("VAL_STATUS", "&nbsp;");
395  $this->tpl->parseCurrentBlock();
396  continue;
397  }
398 
399  $status = isset($a_set[$c])
400  ? (int)$a_set[$c]
402  $percentage = isset($a_set[$c."_perc"])
403  ? (int)$a_set[$c."_perc"]
404  : null;
405 
407  {
408  $timing = $this->showTimingsWarning($this->ref_ids[$obj_id], $a_set["usr_id"]);
409  if($timing)
410  {
411  if($timing !== true)
412  {
413  $timing = ": ".ilDatePresentation::formatDate(new ilDate($timing, IL_CAL_UNIX));
414  }
415  else
416  {
417  $timing = "";
418  }
419  $this->tpl->setCurrentBlock('warning_img');
420  $this->tpl->setVariable('WARNING_IMG', ilUtil::getImagePath('time_warn.svg'));
421  $this->tpl->setVariable('WARNING_ALT', $this->lng->txt('trac_time_passed').$timing);
422  $this->tpl->parseCurrentBlock();
423  }
424  }
425 
426  $this->tpl->setCurrentBlock("objects");
427  $this->tpl->setVariable("VAL_STATUS", $this->parseValue("status", $status, ""));
428  $this->tpl->setVariable("VAL_PERCENTAGE", $this->parseValue("percentage", $percentage, ""));
429  $this->tpl->parseCurrentBlock();
430  break;
431 
432 
433  case (substr($c, 0, 6) == "objtv_"):
434  case (substr($c, 0, 7) == "objsco_"):
435  case (substr($c, 0, 7) == "objsub_"):
436  $status = isset($a_set[$c])
437  ? (int)$a_set[$c]
439 
440  $this->tpl->setCurrentBlock("objects");
441  if(!$a_set["privacy_conflict"])
442  {
443  $this->tpl->setVariable("VAL_STATUS", $this->parseValue("status", $status, ""));
444  }
445  else
446  {
447  $this->tpl->setVariable("VAL_STATUS", "&nbsp;");
448  }
449  $this->tpl->parseCurrentBlock();
450  break;
451 
452  default:
453  $this->tpl->setCurrentBlock("user_field");
454  if(!$a_set["privacy_conflict"])
455  {
456  $this->tpl->setVariable("VAL_UF", $this->parseValue($c, $a_set[$c], ""));
457  }
458  else
459  {
460  $this->tpl->setVariable("VAL_UF", "&nbsp;");
461  }
462  $this->tpl->parseCurrentBlock();
463  break;
464  }
465  }
466 
467  // #7694
468  if(!$a_set["active"] || $a_set["privacy_conflict"])
469  {
470  $mess = array();
471  if($a_set["privacy_conflict"])
472  {
473  $mess[] = $lng->txt("status_no_permission");
474  }
475  else if(!$a_set["active"])
476  {
477  $mess[] = $lng->txt("inactive");
478  }
479  $this->tpl->setCurrentBlock('inactive_bl');
480  $this->tpl->setVariable('TXT_INACTIVE', implode(", ", $mess));
481  $this->tpl->parseCurrentBlock();
482  }
483 
484  $login = !$a_set["privacy_conflict"]
485  ? $a_set["login"]
486  : "&nbsp;";
487  $this->tpl->setVariable("VAL_LOGIN", $login);
488  }
489 
490  protected function fillHeaderExcel($worksheet, &$a_row)
491  {
492  global $ilObjDataCache;
493 
494  $worksheet->write($a_row, 0, $this->lng->txt("login"));
495 
496  $labels = $this->getSelectableColumns();
497  $cnt = 1;
498  foreach ($this->getSelectedColumns() as $c)
499  {
500  if(substr($c, 0, 4) == "obj_")
501  {
502  $obj_id = substr($c, 4);
503  $type = $ilObjDataCache->lookupType($obj_id);
504  $worksheet->write($a_row, $cnt, "(".$this->lng->txt($type).") ".$labels[$c]["txt"]);
505 
506  if(is_array($this->perc_map) && $this->perc_map[$obj_id])
507  {
508  $cnt++;
509  $worksheet->write($a_row, $cnt, $this->lng->txt("trac_percentage")." (%)");
510  }
511  }
512  else
513  {
514  $worksheet->write($a_row, $cnt, $labels[$c]["txt"]);
515  }
516  $cnt++;
517  }
518  }
519 
520  protected function fillRowExcel($worksheet, &$a_row, $a_set)
521  {
522  $worksheet->write($a_row, 0, $a_set["login"]);
523 
524  $cnt = 1;
525  foreach ($this->getSelectedColumns() as $c)
526  {
527  switch($c)
528  {
529  case (substr($c, 0, 4) == "obj_"):
530  $obj_id = substr($c, 4);
531  $val = ilLearningProgressBaseGUI::_getStatusText((int)$a_set[$c]);
532  $worksheet->write($a_row, $cnt, $val);
533 
534  if(is_array($this->perc_map) && $this->perc_map[$obj_id])
535  {
536  $cnt++;
537  $perc = (int)$a_set[$c."_perc"];
538  if(!$perc)
539  {
540  $perc = null;
541  }
542  $worksheet->write($a_row, $cnt, $perc);
543  }
544  break;
545 
546  case (substr($c, 0, 6) == "objtv_"):
547  case (substr($c, 0, 7) == "objsco_"):
548  case (substr($c, 0, 7) == "objsub_"):
549  $val = ilLearningProgressBaseGUI::_getStatusText((int)$a_set[$c]);
550  $worksheet->write($a_row, $cnt, $val);
551  break;
552 
553  /* #14142
554  case "last_access":
555  case "spent_seconds":
556  case "status_changed":
557  */
558  default:
559  $val = $this->parseValue($c, $a_set[$c], "user");
560  $worksheet->write($a_row, $cnt, $val);
561  break;
562 
563  }
564  $cnt++;
565  }
566  }
567 
568  protected function fillHeaderCSV($a_csv)
569  {
570  global $ilObjDataCache;
571 
572  $a_csv->addColumn($this->lng->txt("login"));
573 
574  $labels = $this->getSelectableColumns();
575  foreach ($this->getSelectedColumns() as $c)
576  {
577  if(substr($c, 0, 4) == "obj_")
578  {
579  $obj_id = substr($c, 4);
580  $type = $ilObjDataCache->lookupType($obj_id);
581  $a_csv->addColumn("(".$this->lng->txt($type).") ".$labels[$c]["txt"]);
582 
583  if(is_array($this->perc_map) && $this->perc_map[$obj_id])
584  {
585  $a_csv->addColumn($this->lng->txt("trac_percentage")." (%)");
586  }
587  }
588  else
589  {
590  $a_csv->addColumn($labels[$c]["txt"]);
591  }
592  }
593 
594  $a_csv->addRow();
595  }
596 
597  protected function fillRowCSV($a_csv, $a_set)
598  {
599  $a_csv->addColumn($a_set["login"]);
600 
601  foreach ($this->getSelectedColumns() as $c)
602  {
603  switch($c)
604  {
605  case (substr($c, 0, 4) == "obj_"):
606  $obj_id = substr($c, 4);
607  $val = ilLearningProgressBaseGUI::_getStatusText((int)$a_set[$c]);
608  $a_csv->addColumn($val);
609 
610  if(is_array($this->perc_map) && $this->perc_map[$obj_id])
611  {
612  $perc = (int)$a_set[$c."_perc"];
613  if(!$perc)
614  {
615  $perc = null;
616  }
617  $a_csv->addColumn($perc);
618  }
619  break;
620 
621  case (substr($c, 0, 6) == "objtv_"):
622  case (substr($c, 0, 7) == "objsco_"):
623  case (substr($c, 0, 7) == "objsub_"):
624  $val = ilLearningProgressBaseGUI::_getStatusText((int)$a_set[$c]);
625  $a_csv->addColumn($val);
626  break;
627 
628  /* #14142
629  case "last_access":
630  case "spent_seconds":
631  case "status_changed":
632  */
633  default:
634  $val = $this->parseValue($c, $a_set[$c], "user");
635  $a_csv->addColumn($val);
636  break;
637 
638  }
639  }
640 
641  $a_csv->addRow();
642  }
643 }
644 
645 ?>