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 * Learning progress table: One object, rows: users, columns: properties 8 * Example: A course, rows: members, columns: name, status, mark, ... 9 * 10 * PD, Personal Learning Progress -> UserObjectsProps 11 * PD, Learning Progress of Users -> UserAggObjectsProps 12 * Crs, Learnign Progress of Participants -> ObjectUsersProps 13 * Details -> UserObjectsProps 14 * 15 * More: 16 * PropUsersObjects (Grading Overview in Course) 17 * @author Alex Killing <alex.killing@gmx.de> 18 * @version $Id$ 19 * 20 * @ilCtrl_Calls ilTrObjectUsersPropsTableGUI: ilFormPropertyDispatchGUI 21 * @ingroup ServicesTracking 22 */ 23class ilTrObjectUsersPropsTableGUI extends ilLPTableBaseGUI 24{ 25 protected $user_fields; // array 26 protected $filter; // array 27 protected $in_course; // int 28 protected $in_group; // int 29 protected $has_edit; // bool 30 protected $has_collection; // bool 31 protected $has_multi; // bool 32 33 /** 34 * Constructor 35 */ 36 public function __construct($a_parent_obj, $a_parent_cmd, $a_obj_id, $a_ref_id, $a_print_view = false) 37 { 38 global $DIC; 39 40 $ilCtrl = $DIC['ilCtrl']; 41 $ilUser = $DIC['ilUser']; 42 $tree = $DIC['tree']; 43 $rbacsystem = $DIC['rbacsystem']; 44 45 $this->setId("troup"); 46 $this->obj_id = $a_obj_id; 47 $this->ref_id = $a_ref_id; 48 $this->type = ilObject::_lookupType($a_obj_id); 49 50 $this->in_group = $tree->checkForParentType($this->ref_id, "grp"); 51 if ($this->in_group) { 52 $this->in_group = ilObject::_lookupObjId($this->in_group); 53 } else { 54 $this->in_course = $tree->checkForParentType($this->ref_id, "crs"); 55 if ($this->in_course) { 56 $this->in_course = ilObject::_lookupObjId($this->in_course); 57 } 58 } 59 60 parent::__construct($a_parent_obj, $a_parent_cmd); 61 62 $this->parseTitle($a_obj_id, "trac_participants"); 63 64 if ($a_print_view) { 65 $this->setPrintMode(true); 66 } 67 68 if (!$this->getPrintMode()) { 69 // see ilObjCourseGUI::addMailToMemberButton() 70 include_once "Services/Mail/classes/class.ilMail.php"; 71 $mail = new ilMail($ilUser->getId()); 72 if ($rbacsystem->checkAccess("internal_mail", $mail->getMailObjectReferenceId())) { 73 $this->addMultiCommand("mailselectedusers", $this->lng->txt("send_mail")); 74 } 75 $this->lng->loadLanguageModule('user'); 76 $this->addMultiCommand( 77 'addToClipboard', 78 $this->lng->txt('clipboard_add_btn') 79 ); 80 $this->addColumn("", "", 1); 81 $this->has_multi = true; 82 } 83 84 $labels = $this->getSelectableColumns(); 85 foreach ($this->getSelectedColumns() as $c) { 86 $first = $c; 87 88 // list cannot be sorted by udf fields (separate query) 89 // because of pagination only core fields can be sorted 90 $sort_id = (substr($c, 0, 4) == "udf_") ? "" : $c; 91 92 $this->addColumn($labels[$c]["txt"], $sort_id); 93 } 94 95 if (!$this->getPrintMode()) { 96 $this->addColumn($this->lng->txt("actions"), ""); 97 } 98 $this->setSelectAllCheckbox('uid'); 99 $this->setExternalSorting(true); 100 $this->setExternalSegmentation(true); 101 $this->setEnableHeader(true); 102 $this->setFormAction($ilCtrl->getFormActionByClass(get_class($this))); 103 $this->setRowTemplate("tpl.object_users_props_row.html", "Services/Tracking"); 104 $this->setEnableTitle(true); 105 $this->setShowTemplates(true); 106 $this->setExportFormats(array(self::EXPORT_CSV, self::EXPORT_EXCEL)); 107 108 if ($first) { 109 $this->setDefaultOrderField($first); 110 $this->setDefaultOrderDirection("asc"); 111 } 112 113 $this->initFilter(); 114 115 $this->getItems(); 116 117 // #13807 118 include_once './Services/Tracking/classes/class.ilLearningProgressAccess.php'; 119 $this->has_edit = ilLearningProgressAccess::checkPermission('edit_learning_progress', $this->ref_id); 120 121 /* currently not active, needs to be revised 122 include_once "Services/Object/classes/class.ilObjectLP.php"; 123 include_once "Services/Tracking/classes/collection/class.ilLPCollection.php"; 124 $objlp = ilObjectLP::getInstance($this->obj_id); 125 $this->has_collection = in_array($objlp->getCurrentMode(), ilLPCollection::getCollectionModes()); 126 */ 127 } 128 129 /** 130 * Get selectable columns 131 * 132 * @param 133 * @return 134 */ 135 public function getSelectableColumns() 136 { 137 if ($this->selectable_columns) { 138 return $this->selectable_columns; 139 } 140 141 $cols = $this->getSelectableUserColumns($this->in_course, $this->in_group); 142 $this->user_fields = $cols[1]; 143 $this->selectable_columns = $cols[0]; 144 145 return $this->selectable_columns; 146 } 147 148 /** 149 * Get user items 150 */ 151 public function getItems() 152 { 153 global $DIC; 154 155 $lng = $DIC['lng']; 156 157 $this->determineOffsetAndOrder(); 158 159 include_once("./Services/Tracking/classes/class.ilTrQuery.php"); 160 161 $additional_fields = $this->getSelectedColumns(); 162 163 // only if object is [part of] course/group 164 $check_agreement = false; 165 if ($this->in_course) { 166 // privacy (if course agreement is activated) 167 include_once "Services/PrivacySecurity/classes/class.ilPrivacySettings.php"; 168 $privacy = ilPrivacySettings::_getInstance(); 169 if ($privacy->courseConfirmationRequired()) { 170 $check_agreement = $this->in_course; 171 } 172 } elseif ($this->in_group) { 173 // privacy (if group agreement is activated) 174 include_once "Services/PrivacySecurity/classes/class.ilPrivacySettings.php"; 175 $privacy = ilPrivacySettings::_getInstance(); 176 if ($privacy->groupConfirmationRequired()) { 177 $check_agreement = $this->in_group; 178 } 179 } 180 181 $tr_data = ilTrQuery::getUserDataForObject( 182 $this->ref_id, 183 ilUtil::stripSlashes($this->getOrderField()), 184 ilUtil::stripSlashes($this->getOrderDirection()), 185 ilUtil::stripSlashes($this->getOffset()), 186 ilUtil::stripSlashes($this->getLimit()), 187 $this->getCurrentFilter(), 188 $additional_fields, 189 $check_agreement, 190 $this->user_fields 191 ); 192 193 if (count($tr_data["set"]) == 0 && $this->getOffset() > 0) { 194 $this->resetOffset(); 195 $tr_data = ilTrQuery::getUserDataForObject( 196 $this->ref_id, 197 ilUtil::stripSlashes($this->getOrderField()), 198 ilUtil::stripSlashes($this->getOrderDirection()), 199 ilUtil::stripSlashes($this->getOffset()), 200 ilUtil::stripSlashes($this->getLimit()), 201 $this->getCurrentFilter(), 202 $additional_fields, 203 $check_agreement, 204 $this->user_fields 205 ); 206 } 207 208 $this->setMaxCount($tr_data["cnt"]); 209 $this->setData($tr_data["set"]); 210 } 211 212 213 /** 214 * Init filter 215 */ 216 public function initFilter() 217 { 218 global $DIC; 219 220 $lng = $DIC['lng']; 221 222 foreach ($this->getSelectableColumns() as $column => $meta) { 223 // no udf! 224 switch ($column) { 225 case "firstname": 226 case "lastname": 227 case "mark": 228 case "u_comment": 229 case "institution": 230 case "department": 231 case "title": 232 case "street": 233 case "zipcode": 234 case "city": 235 case "country": 236 case "email": 237 case "matriculation": 238 case "login": 239 if ($column != "mark" || 240 ilObjectLP::supportsMark($this->type)) { 241 $item = $this->addFilterItemByMetaType($column, ilTable2GUI::FILTER_TEXT, true, $meta["txt"]); 242 $this->filter[$column] = $item->getValue(); 243 } 244 break; 245 246 case "first_access": 247 case "last_access": 248 case "create_date": 249 case 'status_changed': 250 $item = $this->addFilterItemByMetaType($column, ilTable2GUI::FILTER_DATETIME_RANGE, true, $meta["txt"]); 251 $this->filter[$column] = $item->getDate(); 252 break; 253 254 case "birthday": 255 $item = $this->addFilterItemByMetaType($column, ilTable2GUI::FILTER_DATE_RANGE, true, $meta["txt"]); 256 $this->filter[$column] = $item->getDate(); 257 break; 258 259 case "read_count": 260 case "percentage": 261 $item = $this->addFilterItemByMetaType($column, ilTable2GUI::FILTER_NUMBER_RANGE, true, $meta["txt"]); 262 $this->filter[$column] = $item->getValue(); 263 break; 264 265 case "gender": 266 $item = $this->addFilterItemByMetaType("gender", ilTable2GUI::FILTER_SELECT, true, $meta["txt"]); 267 $item->setOptions(array( 268 "" => $lng->txt("trac_all"), 269 "n" => $lng->txt("gender_n"), 270 "m" => $lng->txt("gender_m"), 271 "f" => $lng->txt("gender_f"), 272 )); 273 $this->filter["gender"] = $item->getValue(); 274 break; 275 276 case "sel_country": 277 $item = $this->addFilterItemByMetaType("sel_country", ilTable2GUI::FILTER_SELECT, true, $meta["txt"]); 278 279 $options = array(); 280 include_once("./Services/Utilities/classes/class.ilCountry.php"); 281 foreach (ilCountry::getCountryCodes() as $c) { 282 $options[$c] = $lng->txt("meta_c_" . $c); 283 } 284 asort($options); 285 $item->setOptions(array("" => $lng->txt("trac_all")) + $options); 286 287 $this->filter["sel_country"] = $item->getValue(); 288 break; 289 290 case "status": 291 include_once "Services/Tracking/classes/class.ilLPStatus.php"; 292 $item = $this->addFilterItemByMetaType("status", ilTable2GUI::FILTER_SELECT, true, $meta["txt"]); 293 $item->setOptions(array("" => $lng->txt("trac_all"), 294 ilLPStatus::LP_STATUS_NOT_ATTEMPTED_NUM + 1 => $lng->txt(ilLPStatus::LP_STATUS_NOT_ATTEMPTED), 295 ilLPStatus::LP_STATUS_IN_PROGRESS_NUM + 1 => $lng->txt(ilLPStatus::LP_STATUS_IN_PROGRESS), 296 ilLPStatus::LP_STATUS_COMPLETED_NUM + 1 => $lng->txt(ilLPStatus::LP_STATUS_COMPLETED), 297 ilLPStatus::LP_STATUS_FAILED_NUM + 1 => $lng->txt(ilLPStatus::LP_STATUS_FAILED))); 298 $this->filter["status"] = $item->getValue(); 299 if (is_numeric($this->filter["status"])) { 300 $this->filter["status"]--; 301 } 302 break; 303 304 case "language": 305 $item = $this->addFilterItemByMetaType("language", ilTable2GUI::FILTER_LANGUAGE, true); 306 $this->filter["language"] = $item->getValue(); 307 break; 308 309 case "spent_seconds": 310 if (ilObjectLP::supportsSpentSeconds($this->type)) { 311 $item = $this->addFilterItemByMetaType("spent_seconds", ilTable2GUI::FILTER_DURATION_RANGE, true, $meta["txt"]); 312 $this->filter["spent_seconds"]["from"] = $item->getCombinationItem("from")->getValueInSeconds(); 313 $this->filter["spent_seconds"]["to"] = $item->getCombinationItem("to")->getValueInSeconds(); 314 } 315 break; 316 } 317 } 318 } 319 320 /** 321 * Fill table row 322 */ 323 protected function fillRow($data) 324 { 325 global $DIC; 326 327 $ilCtrl = $DIC['ilCtrl']; 328 $lng = $DIC['lng']; 329 $objDefinition = $DIC['objDefinition']; 330 331 if ($this->has_multi) { 332 $this->tpl->setVariable("USER_ID", $data["usr_id"]); 333 } 334 335 foreach ($this->getSelectedColumns() as $c) { 336 if (!(bool) $data["privacy_conflict"]) { 337 if ($c == 'status' && $data[$c] != ilLPStatus::LP_STATUS_COMPLETED_NUM) { 338 $timing = $this->showTimingsWarning($this->ref_id, $data["usr_id"]); 339 if ($timing) { 340 if ($timing !== true) { 341 $timing = ": " . ilDatePresentation::formatDate(new ilDate($timing, IL_CAL_UNIX)); 342 } else { 343 $timing = ""; 344 } 345 $this->tpl->setCurrentBlock('warning_img'); 346 $this->tpl->setVariable('WARNING_IMG', ilUtil::getImagePath('time_warn.svg')); 347 $this->tpl->setVariable('WARNING_ALT', $this->lng->txt('trac_time_passed') . $timing); 348 $this->tpl->parseCurrentBlock(); 349 } 350 } 351 352 // #7694 353 if ($c == 'login' && !$data["active"]) { 354 $this->tpl->setCurrentBlock('inactive_bl'); 355 $this->tpl->setVariable('TXT_INACTIVE', $lng->txt("inactive")); 356 $this->tpl->parseCurrentBlock(); 357 } 358 359 $val = $this->parseValue($c, $data[$c], $this->type); 360 } else { 361 if ($c == 'login') { 362 $this->tpl->setCurrentBlock('inactive_bl'); 363 $this->tpl->setVariable('TXT_INACTIVE', $lng->txt("status_no_permission")); 364 $this->tpl->parseCurrentBlock(); 365 } 366 367 $val = " "; 368 } 369 370 $this->tpl->setCurrentBlock("user_field"); 371 $this->tpl->setVariable("VAL_UF", $val); 372 $this->tpl->parseCurrentBlock(); 373 } 374 375 $ilCtrl->setParameterByClass("illplistofobjectsgui", "user_id", $data["usr_id"]); 376 377 if (!$this->getPrintMode() && !(bool) $data["privacy_conflict"]) { 378 // details for containers and collections 379 if ($this->has_collection || 380 $objDefinition->isContainer($this->type)) { 381 $this->tpl->setCurrentBlock("item_command"); 382 $this->tpl->setVariable("HREF_COMMAND", $ilCtrl->getLinkTargetByClass("illplistofobjectsgui", "userdetails")); 383 $this->tpl->setVariable("TXT_COMMAND", $lng->txt('details')); 384 $this->tpl->parseCurrentBlock(); 385 } 386 387 if ($this->has_edit) { 388 $this->tpl->setCurrentBlock("item_command"); 389 $this->tpl->setVariable("HREF_COMMAND", $ilCtrl->getLinkTargetByClass("illplistofobjectsgui", "edituser")); 390 $this->tpl->setVariable("TXT_COMMAND", $lng->txt('edit')); 391 $this->tpl->parseCurrentBlock(); 392 } 393 } 394 395 $ilCtrl->setParameterByClass("illplistofobjectsgui", 'user_id', ''); 396 } 397 398 protected function fillHeaderExcel(ilExcel $a_excel, &$a_row) 399 { 400 $labels = $this->getSelectableColumns(); 401 $cnt = 0; 402 foreach ($this->getSelectedColumns() as $c) { 403 $a_excel->setCell($a_row, $cnt++, $labels[$c]["txt"]); 404 } 405 406 $a_excel->setBold("A" . $a_row . ":" . $a_excel->getColumnCoord($cnt - 1) . $a_row); 407 } 408 409 protected function fillRowExcel(ilExcel $a_excel, &$a_row, $a_set) 410 { 411 $cnt = 0; 412 foreach ($this->getSelectedColumns() as $c) { 413 if ($c != 'status') { 414 $val = $this->parseValue($c, $a_set[$c], $this->type); 415 } else { 416 $val = ilLearningProgressBaseGUI::_getStatusText((int) $a_set[$c]); 417 } 418 $a_excel->setCell($a_row, $cnt++, $val); 419 } 420 } 421 422 protected function fillHeaderCSV($a_csv) 423 { 424 $labels = $this->getSelectableColumns(); 425 foreach ($this->getSelectedColumns() as $c) { 426 $a_csv->addColumn($labels[$c]["txt"]); 427 } 428 429 $a_csv->addRow(); 430 } 431 432 protected function fillRowCSV($a_csv, $a_set) 433 { 434 foreach ($this->getSelectedColumns() as $c) { 435 if ($c != 'status') { 436 $val = $this->parseValue($c, $a_set[$c], $this->type); 437 } else { 438 $val = ilLearningProgressBaseGUI::_getStatusText((int) $a_set[$c]); 439 } 440 $a_csv->addColumn($val); 441 } 442 443 $a_csv->addRow(); 444 } 445} 446