1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once("./Services/Tracking/classes/class.ilLPTableBaseGUI.php");
5
6/**
7 * Build table list for objects of given user
8 *
9 * @author Jörg Lützenkirchen <luetzenkirchen@leifos.com>
10 * @version $Id$
11 *
12 * @ilCtrl_Calls ilTrUserObjectsPropsTableGUI: ilFormPropertyDispatchGUI
13 * @ingroup ServicesTracking
14 */
15class ilTrUserObjectsPropsTableGUI extends ilLPTableBaseGUI
16{
17    /**
18    * Constructor
19    */
20    public function __construct($a_parent_obj, $a_parent_cmd, $a_user_id, $a_obj_id, $a_ref_id, $a_print_view = false)
21    {
22        global $DIC;
23
24        $ilCtrl = $DIC['ilCtrl'];
25        $lng = $DIC['lng'];
26        $ilAccess = $DIC['ilAccess'];
27        $lng = $DIC['lng'];
28        $rbacsystem = $DIC['rbacsystem'];
29
30        $this->setId("truop");
31        $this->user_id = $a_user_id;
32        $this->obj_id = $a_obj_id;
33        $this->ref_id = $a_ref_id;
34
35        parent::__construct($a_parent_obj, $a_parent_cmd);
36        $this->setLimit(9999);
37
38        $this->parseTitle($this->obj_id, "details", $this->user_id);
39
40        if ($a_print_view) {
41            $this->setPrintMode(true);
42        }
43
44        $this->addColumn($this->lng->txt("title"), "title");
45
46        foreach ($this->getSelectedColumns() as $c) {
47            $l = $c;
48            if (in_array($l, array("last_access", "first_access", "read_count", "spent_seconds", "mark", "status", "percentage"))) {
49                $l = "trac_" . $l;
50            }
51            if ($l == "u_comment") {
52                $l = "trac_comment";
53            }
54            $this->addColumn($this->lng->txt($l), $c);
55        }
56
57        if (!$this->getPrintMode()) {
58            $this->addColumn($this->lng->txt("actions"), "");
59        }
60
61        $this->setExternalSorting(true);
62        $this->setExternalSegmentation(true);
63        $this->setEnableHeader(true);
64        $this->setFormAction($ilCtrl->getFormActionByClass(get_class($this)));
65        $this->setRowTemplate("tpl.user_objects_props_row.html", "Services/Tracking");
66        $this->setEnableTitle(true);
67        $this->setDefaultOrderField("title");
68        $this->setDefaultOrderDirection("asc");
69        $this->setShowTemplates(true);
70
71        $this->setExportFormats(array(self::EXPORT_CSV, self::EXPORT_EXCEL));
72
73        $this->initFilter();
74
75        $this->getItems();
76    }
77
78    /**
79     * Get selectable columns
80     *
81     * @param
82     * @return
83     */
84    public function getSelectableColumns()
85    {
86        global $DIC;
87
88        $lng = $DIC['lng'];
89
90        // default fields
91        $cols = array();
92
93        include_once 'Services/Tracking/classes/class.ilObjUserTracking.php';
94        $tracking = new ilObjUserTracking();
95        if ($tracking->hasExtendedData(ilObjUserTracking::EXTENDED_DATA_LAST_ACCESS)) {
96            $cols["first_access"] = array(
97                "txt" => $lng->txt("trac_first_access"),
98                "default" => true);
99            $cols["last_access"] = array(
100                "txt" => $lng->txt("trac_last_access"),
101                "default" => true);
102        }
103        if ($tracking->hasExtendedData(ilObjUserTracking::EXTENDED_DATA_READ_COUNT)) {
104            $cols["read_count"] = array(
105                "txt" => $lng->txt("trac_read_count"),
106                "default" => true);
107        }
108        if ($tracking->hasExtendedData(ilObjUserTracking::EXTENDED_DATA_SPENT_SECONDS)) {
109            $cols["spent_seconds"] = array(
110                "txt" => $lng->txt("trac_spent_seconds"),
111                "default" => true);
112        }
113
114        // #15334 - parent object does not matter, sub-objects may have percentage
115        $cols["percentage"] = array(
116            "txt" => $lng->txt("trac_percentage"),
117            "default" => true);
118
119        $cols["status"] = array(
120            "txt" => $lng->txt("trac_status"),
121            "default" => true);
122        $cols["mark"] = array(
123            "txt" => $lng->txt("trac_mark"),
124            "default" => true);
125        $cols["u_comment"] = array(
126            "txt" => $lng->txt("trac_comment"),
127            "default" => false);
128
129        return $cols;
130    }
131
132    /**
133    * Get user items
134    */
135    public function getItems()
136    {
137        global $DIC;
138
139        $rbacsystem = $DIC['rbacsystem'];
140
141        $this->determineOffsetAndOrder();
142
143        $additional_fields = $this->getSelectedColumns();
144
145        include_once("./Services/Tracking/classes/class.ilTrQuery.php");
146
147        $tr_data = ilTrQuery::getObjectsDataForUser(
148            $this->user_id,
149            $this->obj_id,
150            $this->ref_id,
151            ilUtil::stripSlashes($this->getOrderField()),
152            ilUtil::stripSlashes($this->getOrderDirection()),
153            ilUtil::stripSlashes($this->getOffset()),
154            ilUtil::stripSlashes($this->getLimit()),
155            $this->filter,
156            $additional_fields,
157            $this->filter["view_mode"]
158        );
159
160        if (count($tr_data["set"]) == 0 && $this->getOffset() > 0) {
161            $this->resetOffset();
162            $tr_data = ilTrQuery::getObjectsDataForUser(
163                $this->user_id,
164                $this->obj_id,
165                $this->ref_id,
166                ilUtil::stripSlashes($this->getOrderField()),
167                ilUtil::stripSlashes($this->getOrderDirection()),
168                ilUtil::stripSlashes($this->getOffset()),
169                ilUtil::stripSlashes($this->getLimit()),
170                $this->filter,
171                $additional_fields,
172                $this->filter["view_mode"]
173            );
174        }
175
176        // #13807
177        foreach ($tr_data["set"] as $idx => $row) {
178            include_once './Services/Tracking/classes/class.ilLearningProgressAccess.php';
179            if ($row["ref_id"] &&
180                !ilLearningProgressAccess::checkPermission('read_learning_progress', $row['ref_id'])) {
181                foreach (array_keys($row) as $col_id) {
182                    if (!in_array($col_id, array("type", "obj_id", "ref_id", "title", "sort_title"))) {
183                        $tr_data["set"][$idx][$col_id] = null;
184                    }
185                }
186                $tr_data["set"][$idx]["privacy_conflict"] = true;
187            }
188        }
189
190        $this->setMaxCount($tr_data["cnt"]);
191
192        if ($this->getOrderField() == "title") {
193            // sort alphabetically, move parent object to 1st position
194            $set = array();
195            $parent = false;
196            foreach ($tr_data["set"] as $idx => $row) {
197                if ($row['obj_id'] == $this->obj_id) {
198                    $parent = $row;
199                } elseif (isset($row["sort_title"])) {
200                    $set[strtolower($row["sort_title"]) . "__" . $idx] = $row;
201                } else {
202                    $set[strtolower($row["title"]) . "__" . $idx] = $row;
203                }
204            }
205            unset($tr_data["set"]);
206            if ($this->getOrderDirection() == "asc") {
207                ksort($set);
208            } else {
209                krsort($set);
210            }
211            $set = array_values($set);
212            if ($parent) {
213                array_unshift($set, $parent);
214            }
215
216            $this->setData($set);
217        } else {
218            $this->setData($tr_data["set"]);
219        }
220    }
221
222    /**
223    * Init filter
224    */
225    public function initFilter()
226    {
227        global $DIC;
228
229        $lng = $DIC['lng'];
230
231        // for scorm and objectives this filter does not make sense / is not implemented
232        include_once './Services/Object/classes/class.ilObjectLP.php';
233        $olp = ilObjectLP::getInstance($this->obj_id);
234        $collection = $olp->getCollectionInstance();
235        if ($collection instanceof ilLPCollectionOfRepositoryObjects) {
236            include_once("./Services/Form/classes/class.ilSubEnabledFormPropertyGUI.php");
237            include_once("./Services/Table/interfaces/interface.ilTableFilterItem.php");
238
239            // show collection only/all
240            include_once("./Services/Form/classes/class.ilRadioGroupInputGUI.php");
241            include_once("./Services/Form/classes/class.ilRadioOption.php");
242            $ti = new ilRadioGroupInputGUI($lng->txt("trac_view_mode"), "view_mode");
243            $ti->addOption(new ilRadioOption($lng->txt("trac_view_mode_all"), ""));
244            $ti->addOption(new ilRadioOption($lng->txt("trac_view_mode_collection"), "coll"));
245            $this->addFilterItem($ti);
246            $ti->readFromSession();
247            $this->filter["view_mode"] = $ti->getValue();
248        }
249    }
250
251    /**
252    * Fill table row
253    */
254    protected function fillRow($data)
255    {
256        global $DIC;
257
258        $ilCtrl = $DIC['ilCtrl'];
259        $lng = $DIC['lng'];
260        $rbacsystem = $DIC['rbacsystem'];
261
262        if (!$this->isPercentageAvailable($data["obj_id"])) {
263            $data["percentage"] = null;
264        }
265
266        foreach ($this->getSelectedColumns() as $c) {
267            if (!$data["privacy_conflict"]) {
268                $val = (trim($data[$c]) == "")
269                    ? " "
270                    : $data[$c];
271
272                if ($data[$c] != "" || $c == "status") {
273                    switch ($c) {
274                        case "first_access":
275                            $val = ilDatePresentation::formatDate(new ilDateTime($data[$c], IL_CAL_DATETIME));
276                            break;
277
278                        case "last_access":
279                            $val = ilDatePresentation::formatDate(new ilDateTime($data[$c], IL_CAL_UNIX));
280                            break;
281
282                        case "status":
283                            include_once("./Services/Tracking/classes/class.ilLearningProgressBaseGUI.php");
284                            $path = ilLearningProgressBaseGUI::_getImagePathForStatus($data[$c]);
285                            $text = ilLearningProgressBaseGUI::_getStatusText($data[$c]);
286                            $val = ilUtil::img($path, $text);
287
288                            if ($data["ref_id"] &&
289                                $data["type"] != "lobj" &&
290                                $data["type"] != "sco" &&
291                                $data["type"] != "st" &&
292                                $data["type"] != "mob") {
293                                $timing = $this->showTimingsWarning($data["ref_id"], $this->user_id);
294                                if ($timing) {
295                                    if ($timing !== true) {
296                                        $timing = ": " . ilDatePresentation::formatDate(new ilDate($timing, IL_CAL_UNIX));
297                                    } else {
298                                        $timing = "";
299                                    }
300                                    $this->tpl->setCurrentBlock('warning_img');
301                                    $this->tpl->setVariable('WARNING_IMG', ilUtil::getImagePath('time_warn.svg'));
302                                    $this->tpl->setVariable('WARNING_ALT', $this->lng->txt('trac_time_passed') . $timing);
303                                    $this->tpl->parseCurrentBlock();
304                                }
305                            }
306                            break;
307
308                        case "spent_seconds":
309                            if (!ilObjectLP::supportsSpentSeconds($data["type"])) {
310                                $val = "-";
311                            } else {
312                                $val = ilDatePresentation::secondsToString($data[$c], ($data[$c] < 3600 ? true : false)); // #14858
313                            }
314                            break;
315
316                        case "percentage":
317                            $val = $data[$c] . "%";
318                            break;
319
320                    }
321                }
322                if ($c == "mark" &&
323                    !ilObjectLP::supportsMark($this->type)) {
324                    $val = "-";
325                }
326                if ($c == "spent_seconds" &&
327                    !ilObjectLP::supportsSpentSeconds($this->type)) {
328                    $val = "-";
329                }
330                if ($c == "percentage" &&
331                    !$this->isPercentageAvailable($data["obj_id"])) {
332                    $val = "-";
333                }
334            } else {
335                $val = "&nbsp;";
336            }
337
338            $this->tpl->setCurrentBlock("user_field");
339            $this->tpl->setVariable("VAL_UF", $val);
340            $this->tpl->parseCurrentBlock();
341        }
342
343        if ($data["privacy_conflict"]) {
344            $this->tpl->setCurrentBlock("permission_bl");
345            $this->tpl->setVariable("TXT_NO_PERMISSION", $lng->txt("status_no_permission"));
346            $this->tpl->parseCurrentBlock();
347        }
348
349        if ($data["title"] == "") {
350            $data["title"] = "--" . $lng->txt("none") . "--";
351        }
352        $this->tpl->setVariable("ICON", ilObject::_getIcon("", "tiny", $data["type"]));
353        $this->tpl->setVariable("ICON_ALT", $lng->txt($data["type"]));
354
355        if (in_array($data['type'], array('fold', 'grp')) && $data['obj_id'] != $this->obj_id) {
356            if ($data['type'] == 'fold') {
357                $object_gui = 'ilobjfoldergui';
358            } else {
359                $object_gui = 'ilobjgroupgui';
360            }
361            $this->tpl->setCurrentBlock('title_linked');
362
363            // link structure gets too complicated
364            if ($_GET["baseClass"] != "ilPersonalDesktopGUI" && $_GET["baseClass"] != "ilAdministrationGUI") {
365                $old = $ilCtrl->getParameterArrayByClass('illplistofobjectsgui');
366                $ilCtrl->setParameterByClass('illplistofobjectsgui', 'ref_id', $data["ref_id"]);
367                $ilCtrl->setParameterByClass('illplistofobjectsgui', 'details_id', $data["ref_id"]);
368                $ilCtrl->setParameterByClass('illplistofobjectsgui', 'user_id', $this->user_id);
369                $url = $ilCtrl->getLinkTargetByClass(array('ilrepositorygui', $object_gui, 'illearningprogressgui', 'illplistofobjectsgui'), 'userdetails');
370                $ilCtrl->setParameterByClass('illplistofobjectsgui', 'ref_id', $old["ref_id"]);
371                $ilCtrl->setParameterByClass('illplistofobjectsgui', 'details_id', $old["details_id"]);
372                $ilCtrl->setParameterByClass('illplistofobjectsgui', 'user_id', $old["user_id"]);
373            } else {
374                $url = "#";
375            }
376
377            $this->tpl->setVariable("URL_TITLE", $url);
378            $this->tpl->setVariable("VAL_TITLE", $data["title"]);
379            $this->tpl->parseCurrentBlock();
380        } else {
381            $this->tpl->setCurrentBlock('title_plain');
382            $this->tpl->setVariable("VAL_TITLE", $data["title"]);
383            $this->tpl->parseCurrentBlock();
384        }
385
386        // #16453 / #17163
387        if ($data['ref_id']) {
388            include_once './Services/Tree/classes/class.ilPathGUI.php';
389            $path = new ilPathGUI();
390            $path = $path->getPath($this->ref_id, $data['ref_id']);
391            if ($path) {
392                $this->tpl->setVariable('COLL_PATH', $this->lng->txt('path') . ': ' . $path);
393            }
394        }
395
396        // #13807 / #17069
397        include_once './Services/Tracking/classes/class.ilLearningProgressAccess.php';
398        if ($data["ref_id"] &&
399            ilLearningProgressAccess::checkPermission('edit_learning_progress', $data['ref_id'])) {
400            if (!in_array($data["type"], array("sco", "lobj")) && !$this->getPrintMode()) {
401                $this->tpl->setCurrentBlock("item_command");
402                $ilCtrl->setParameterByClass("illplistofobjectsgui", "userdetails_id", $data["ref_id"]);
403                $this->tpl->setVariable("HREF_COMMAND", $ilCtrl->getLinkTargetByClass("illplistofobjectsgui", 'edituser'));
404                $this->tpl->setVariable("TXT_COMMAND", $lng->txt('edit'));
405                $ilCtrl->setParameterByClass("illplistofobjectsgui", "userdetails_id", "");
406                $this->tpl->parseCurrentBlock();
407            }
408        }
409    }
410
411    protected function fillHeaderExcel(ilExcel $a_excel, &$a_row)
412    {
413        $a_excel->setCell($a_row, 0, $this->lng->txt("type"));
414        $a_excel->setCell($a_row, 1, $this->lng->txt("title"));
415
416        $labels = $this->getSelectableColumns();
417        $cnt = 2;
418        foreach ($this->getSelectedColumns() as $c) {
419            $a_excel->setCell($a_row, $cnt++, $labels[$c]["txt"]);
420        }
421
422        $a_excel->setBold("A" . $a_row . ":" . $a_excel->getColumnCoord($cnt - 1) . $a_row);
423    }
424
425    protected function fillRowExcel(ilExcel $a_excel, &$a_row, $a_set)
426    {
427        $a_excel->setCell($a_row, 0, $this->lng->txt($a_set["type"]));
428        $a_excel->setCell($a_row, 1, $a_set["title"]);
429
430        $cnt = 2;
431        foreach ($this->getSelectedColumns() as $c) {
432            if ($c != 'status') {
433                $val = $this->parseValue($c, $a_set[$c], $this->type);
434            } else {
435                $val = ilLearningProgressBaseGUI::_getStatusText((int) $a_set[$c]);
436            }
437            $a_excel->setCell($a_row, $cnt++, $val);
438        }
439    }
440
441    protected function fillHeaderCSV($a_csv)
442    {
443        $a_csv->addColumn($this->lng->txt("type"));
444        $a_csv->addColumn($this->lng->txt("title"));
445
446        $labels = $this->getSelectableColumns();
447        foreach ($this->getSelectedColumns() as $c) {
448            $a_csv->addColumn($labels[$c]["txt"]);
449        }
450
451        $a_csv->addRow();
452    }
453
454    protected function fillRowCSV($a_csv, $a_set)
455    {
456        $a_csv->addColumn($this->lng->txt($a_set["type"]));
457        $a_csv->addColumn($a_set["title"]);
458
459        foreach ($this->getSelectedColumns() as $c) {
460            if ($c != 'status') {
461                $val = $this->parseValue($c, $a_set[$c], $this->type);
462            } else {
463                $val = ilLearningProgressBaseGUI::_getStatusText((int) $a_set[$c]);
464            }
465            $a_csv->addColumn($val);
466        }
467
468        $a_csv->addRow();
469    }
470}
471