1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4include_once("./Services/Table/classes/class.ilTable2GUI.php"); 5include_once './Services/Search/classes/class.ilSearchSettings.php'; 6require_once('./Services/Repository/classes/class.ilObjectPlugin.php'); 7 8/** 9* TableGUI class for learning progress 10* 11* @author Jörg Lützenkirchen <luetzenkirchen@leifos.com> 12* @version $Id$ 13* 14* @ingroup ServicesTracking 15*/ 16class ilLPTableBaseGUI extends ilTable2GUI 17{ 18 protected $filter; // array 19 protected $anonymized; // [bool] 20 21 public function __construct($a_parent_obj, $a_parent_cmd = "", $a_template_context = "") 22 { 23 parent::__construct($a_parent_obj, $a_parent_cmd, $a_template_context); 24 25 // country names 26 $this->lng->loadLanguageModule("meta"); 27 28 include_once("./Services/Object/classes/class.ilObjectLP.php"); 29 30 $this->anonymized = (bool) !ilObjUserTracking::_enabledUserRelatedData(); 31 if (!$this->anonymized && $this->obj_id) { 32 include_once "Services/Object/classes/class.ilObjectLP.php"; 33 $olp = ilObjectLP::getInstance($this->obj_id); 34 $this->anonymized = $olp->isAnonymized(); 35 } 36 } 37 38 public function executeCommand() 39 { 40 global $DIC; 41 42 $ilCtrl = $DIC['ilCtrl']; 43 $lng = $DIC['lng']; 44 45 $this->determineSelectedFilters(); 46 47 if (!$ilCtrl->getNextClass($this)) { 48 $to_hide = false; 49 50 switch ($ilCtrl->getCmd()) { 51 case "applyFilter": 52 $this->resetOffset(); 53 $this->writeFilterToSession(); 54 break; 55 56 case "resetFilter": 57 $this->resetOffset(); 58 $this->resetFilter(); 59 break; 60 61 case "hideSelected": 62 $to_hide = $_POST["item_id"]; 63 break; 64 65 case "hide": 66 $to_hide = array((int) $_GET["hide"]); 67 break; 68 69 case "mailselectedusers": 70 if (!sizeof($_POST["uid"])) { 71 ilUtil::sendFailure($lng->txt("no_checkbox"), true); 72 } else { 73 $this->sendMail($_POST["uid"], $this->parent_obj, $this->parent_cmd); 74 } 75 break; 76 77 case 'addToClipboard': 78 if (!sizeof($_POST['uid'])) { 79 ilUtil::sendFailure($lng->txt('no_checkbox'), true); 80 } else { 81 $this->addToClipboard(); 82 } 83 break; 84 85 // page selector 86 default: 87 $this->determineOffsetAndOrder(); 88 $this->storeNavParameter(); 89 break; 90 } 91 92 if ($to_hide) { 93 $obj = $this->getFilterItemByPostVar("hide"); 94 $value = array_unique(array_merge((array) $obj->getValue(), $to_hide)); 95 $obj->setValue($value); 96 $obj->writeToSession(); 97 } 98 99 if (isset($_REQUEST["tbltplcrt"])) { 100 $ilCtrl->setParameter($this->parent_obj, "tbltplcrt", $_REQUEST["tbltplcrt"]); 101 } 102 if (isset($_REQUEST["tbltpldel"])) { 103 $ilCtrl->setParameter($this->parent_obj, "tbltpldel", $_REQUEST["tbltpldel"]); 104 } 105 106 $ilCtrl->redirect($this->parent_obj, $this->parent_cmd); 107 } else { 108 // e.g. repository selector 109 return parent::executeCommand(); 110 } 111 } 112 113 protected function sendMail(array $a_user_ids, $a_parent_obj, $a_parent_cmd) 114 { 115 // see ilObjCourseGUI::sendMailToSelectedUsersObject() 116 117 require_once 'Services/Mail/classes/class.ilMailFormCall.php'; 118 119 $rcps = array(); 120 foreach ($a_user_ids as $usr_id) { 121 $rcps[] = ilObjUser::_lookupLogin($usr_id); 122 } 123 124 $template = array(); 125 $sig = null; 126 127 // repository-object-specific 128 $ref_id = (int) $_REQUEST["ref_id"]; 129 if ($ref_id) { 130 $obj_lp = ilObjectLP::getInstance(ilObject::_lookupObjectId($ref_id)); 131 $tmpl_id = $obj_lp->getMailTemplateId(); 132 133 if ($tmpl_id) { 134 $template = array( 135 ilMailFormCall::CONTEXT_KEY => $tmpl_id, 136 'ref_id' => $ref_id, 137 'ts' => time() 138 ); 139 } else { 140 include_once './Services/Link/classes/class.ilLink.php'; 141 $sig = ilLink::_getLink($ref_id); 142 $sig = rawurlencode(base64_encode($sig)); 143 } 144 } 145 146 ilUtil::redirect( 147 ilMailFormCall::getRedirectTarget( 148 $a_parent_obj, 149 $a_parent_cmd, 150 array(), 151 array( 152 'type' => 'new', 153 'rcp_to' => implode(',', $rcps), 154 'sig' => $sig 155 ), 156 $template 157 ) 158 ); 159 } 160 161 /** 162 * Search objects that match current filters 163 * 164 * @param array $filter 165 * @param string $permission 166 * @param array preset obj_ids 167 * @param bool check lp activation 168 * @return array 169 */ 170 protected function searchObjects(array $filter, $permission, array $preset_obj_ids = null, $a_check_lp_activation = true) 171 { 172 global $DIC; 173 174 $ilObjDataCache = $DIC['ilObjDataCache']; 175 176 include_once './Services/Search/classes/class.ilQueryParser.php'; 177 178 $query_parser = new ilQueryParser($filter["query"]); 179 $query_parser->setMinWordLength(0); 180 $query_parser->setCombination(QP_COMBINATION_AND); 181 $query_parser->parse(); 182 if (!$query_parser->validate()) { 183 ilLoggerFactory::getLogger('trac')->notice($query_parser->getMessage()); 184 // echo $query_parser->getMessage(); 185 return false; 186 } 187 188 if ($filter["type"] == "lres") { 189 $filter["type"] = array('lm','sahs','htlm'); 190 } else { 191 $filter["type"] = array($filter["type"]); 192 } 193 194 include_once 'Services/Search/classes/Like/class.ilLikeObjectSearch.php'; 195 $object_search = new ilLikeObjectSearch($query_parser); 196 $object_search->setFilter($filter["type"]); 197 if ($preset_obj_ids) { 198 $object_search->setIdFilter($preset_obj_ids); 199 } 200 $res = &$object_search->performSearch(); 201 202 if ($permission) { 203 $res->setRequiredPermission($permission); 204 } 205 206 $res->setMaxHits(1000); 207 208 if ($a_check_lp_activation) { 209 $res->addObserver($this, "searchFilterListener"); 210 } 211 212 if (!$this->filter["area"]) { 213 $res->filter(ROOT_FOLDER_ID, false); 214 } else { 215 $res->filter($this->filter["area"], false); 216 } 217 218 $objects = array(); 219 foreach ($res->getResults() as $obj_data) { 220 $objects[$obj_data['obj_id']][] = $obj_data['ref_id']; 221 } 222 223 // Check if search max hits is reached 224 if ($res->isLimitReached()) { 225 $this->lng->loadLanguageModule("search"); 226 ilUtil::sendFailure(sprintf($this->lng->txt("search_limit_reached"), 1000)); 227 } 228 229 return $objects ? $objects : array(); 230 } 231 232 /** 233 * Listener for SearchResultFilter 234 * Checks wheather the object is hidden and mode is not LP_MODE_DEACTIVATED 235 * @access public 236 */ 237 public function searchFilterListener($a_ref_id, $a_data) 238 { 239 if (is_array($this->filter["hide"]) && in_array($a_data["obj_id"], $this->filter["hide"])) { 240 return false; 241 } 242 $olp = ilObjectLP::getInstance($a_data["obj_id"]); 243 if (get_class($olp) != "ilObjectLP" && // #13654 - LP could be unsupported 244 !$olp->isActive()) { 245 return false; 246 } 247 return true; 248 } 249 250 /** 251 * Init filter 252 * 253 * @param bool $a_split_learning_resources 254 */ 255 public function initBaseFilter($a_split_learning_resources = false, $a_include_no_status_filter = true) 256 { 257 global $DIC; 258 259 $lng = $DIC['lng']; 260 $ilObjDataCache = $DIC['ilObjDataCache']; 261 262 $this->setDisableFilterHiding(true); 263 264 // object type selection 265 include_once("./Services/Form/classes/class.ilSelectInputGUI.php"); 266 $si = new ilSelectInputGUI($this->lng->txt("obj_type"), "type"); 267 $si->setOptions($this->getPossibleTypes($a_split_learning_resources)); 268 $this->addFilterItem($si); 269 $si->readFromSession(); 270 if (!$si->getValue()) { 271 $si->setValue("crs"); 272 } 273 $this->filter["type"] = $si->getValue(); 274 275 // hidden items 276 include_once("./Services/Form/classes/class.ilMultiSelectInputGUI.php"); 277 $msi = new ilMultiSelectInputGUI($lng->txt("trac_filter_hidden"), "hide"); 278 $this->addFilterItem($msi); 279 $msi->readFromSession(); 280 $this->filter["hide"] = $msi->getValue(); 281 if ($this->filter["hide"]) { 282 // create options from current value 283 $types = $this->getCurrentFilter(true); 284 $type = $types["type"]; 285 $options = array(); 286 if ($type == 'lres') { 287 $type = array('lm','sahs','htlm'); 288 } else { 289 $type = array($type); 290 } 291 foreach ($this->filter["hide"] as $obj_id) { 292 if (in_array($ilObjDataCache->lookupType($obj_id), $type)) { 293 $options[$obj_id] = $ilObjDataCache->lookupTitle($obj_id); 294 } 295 } 296 $msi->setOptions($options); 297 } 298 299 // title/description 300 include_once("./Services/Form/classes/class.ilTextInputGUI.php"); 301 $ti = new ilTextInputGUI($lng->txt("trac_title_description"), "query"); 302 $ti->setMaxLength(64); 303 $ti->setSize(20); 304 $this->addFilterItem($ti); 305 $ti->readFromSession(); 306 $this->filter["query"] = $ti->getValue(); 307 308 // repository area selection 309 include_once("./Services/Form/classes/class.ilRepositorySelectorInputGUI.php"); 310 $rs = new ilRepositorySelectorInputGUI($lng->txt("trac_filter_area"), "area"); 311 $rs->setSelectText($lng->txt("trac_select_area")); 312 $this->addFilterItem($rs); 313 $rs->readFromSession(); 314 $this->filter["area"] = $rs->getValue(); 315 316 // hide "not started yet" 317 if ($a_include_no_status_filter) { 318 include_once("./Services/Form/classes/class.ilCheckboxInputGUI.php"); 319 $cb = new ilCheckboxInputGUI($lng->txt("trac_filter_has_status"), "status"); 320 $this->addFilterItem($cb); 321 $cb->readFromSession(); 322 $this->filter["status"] = $cb->getChecked(); 323 } 324 } 325 326 /** 327 * Build path with deep-link 328 * 329 * @param array $ref_ids 330 * @return array 331 */ 332 protected function buildPath($ref_ids) 333 { 334 global $DIC; 335 336 $tree = $DIC['tree']; 337 $ilCtrl = $DIC['ilCtrl']; 338 339 include_once './Services/Link/classes/class.ilLink.php'; 340 341 if (!count($ref_ids)) { 342 return false; 343 } 344 foreach ($ref_ids as $ref_id) { 345 $path = "..."; 346 $counter = 0; 347 $path_full = $tree->getPathFull($ref_id); 348 foreach ($path_full as $data) { 349 if (++$counter < (count($path_full) - 1)) { 350 continue; 351 } 352 $path .= " » "; 353 if ($ref_id != $data['ref_id']) { 354 $path .= $data['title']; 355 } else { 356 $path .= ('<a target="_top" href="' . 357 ilLink::_getLink($data['ref_id'], $data['type']) . '">' . 358 $data['title'] . '</a>'); 359 } 360 } 361 362 $result[$ref_id] = $path; 363 } 364 return $result; 365 } 366 367 /** 368 * Get possible subtypes 369 * 370 * @param bool $a_split_learning_resources 371 * @param bool $a_include_digilib 372 * @param bool $a_allow_undefined_lp 373 */ 374 protected function getPossibleTypes($a_split_learning_resources = false, $a_include_digilib = false, $a_allow_undefined_lp = false) 375 { 376 global $DIC; 377 378 $lng = $DIC['lng']; 379 $ilPluginAdmin = $DIC['ilPluginAdmin']; 380 381 $options = array(); 382 383 if ($a_split_learning_resources) { 384 $options['lm'] = $lng->txt('objs_lm'); 385 $options['sahs'] = $lng->txt('objs_sahs'); 386 $options['htlm'] = $lng->txt('objs_htlm'); 387 } else { 388 $options['lres'] = $lng->txt('obj_lrss'); 389 } 390 391 $options['crs'] = $lng->txt('objs_crs'); 392 $options['grp'] = $lng->txt('objs_grp'); 393 $options['exc'] = $lng->txt('objs_exc'); 394 $options['file'] = $lng->txt('objs_file'); 395 $options['mcst'] = $lng->txt('objs_mcst'); 396 $options['svy'] = $lng->txt('objs_svy'); 397 $options['tst'] = $lng->txt('objs_tst'); 398 $options['prg'] = $lng->txt('objs_prg'); 399 $options['iass'] = $lng->txt('objs_iass'); 400 $options['copa'] = $lng->txt('objs_copa'); 401 $options['lso'] = $lng->txt('objs_lso'); 402 403 if ($a_allow_undefined_lp) { 404 $options["webr"] = $lng->txt("objs_webr"); 405 $options["wiki"] = $lng->txt("objs_wiki"); 406 $options["blog"] = $lng->txt("objs_blog"); 407 $options["prtf"] = $lng->txt("objs_prtf"); 408 $options["prtt"] = $lng->txt("objs_prtt"); 409 } 410 411 // repository plugins (currently only active) 412 include_once 'Services/Repository/classes/class.ilRepositoryObjectPluginSlot.php'; 413 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_SERVICE, "Repository", "robj"); 414 foreach ($pl_names as $pl) { 415 $pl_id = $ilPluginAdmin->getId(IL_COMP_SERVICE, "Repository", "robj", $pl); 416 if (ilRepositoryObjectPluginSlot::isTypePluginWithLP($pl_id)) { 417 $options[$pl_id] = ilObjectPlugin::lookupTxtById($pl_id, "objs_" . $pl_id); 418 } 419 } 420 421 asort($options); 422 return $options; 423 } 424 425 protected function parseValue($id, $value, $type) 426 { 427 global $DIC; 428 429 $lng = $DIC['lng']; 430 431 // get rid of aggregation 432 $pos = strrpos($id, "_"); 433 if ($pos !== false) { 434 $function = strtoupper(substr($id, $pos + 1)); 435 if (in_array($function, array("MIN", "MAX", "SUM", "AVG", "COUNT"))) { 436 $id = substr($id, 0, $pos); 437 } 438 } 439 440 if (trim($value) == "" && $id != "status") { 441 if ($id == "title" && 442 get_class($this) != "ilTrObjectUsersPropsTableGUI" && 443 get_class($this) != "ilTrMatrixTableGUI") { 444 return "--" . $lng->txt("none") . "--"; 445 } 446 return " "; 447 } 448 449 switch ($id) { 450 case "first_access": 451 case "create_date": 452 case 'status_changed': 453 $value = ilDatePresentation::formatDate(new ilDateTime($value, IL_CAL_DATETIME)); 454 break; 455 456 case "last_access": 457 $value = ilDatePresentation::formatDate(new ilDateTime($value, IL_CAL_UNIX)); 458 break; 459 460 case "birthday": 461 $value = ilDatePresentation::formatDate(new ilDate($value, IL_CAL_DATE)); 462 break; 463 464 case "spent_seconds": 465 if (!ilObjectLP::supportsSpentSeconds($type)) { 466 $value = "-"; 467 } else { 468 $value = ilDatePresentation::secondsToString($value, ($value < 3600 ? true : false)); // #14858 469 } 470 break; 471 472 case "percentage": 473 if (false /* $this->isPercentageAvailable() */) { 474 $value = "-"; 475 } else { 476 $value = $value . "%"; 477 } 478 break; 479 480 case "mark": 481 if (!ilObjectLP::supportsMark($type)) { 482 $value = "-"; 483 } 484 break; 485 486 case "gender": 487 $value = $lng->txt("gender_" . $value); 488 break; 489 490 case "status": 491 include_once("./Services/Tracking/classes/class.ilLearningProgressBaseGUI.php"); 492 $path = ilLearningProgressBaseGUI::_getImagePathForStatus($value); 493 $text = ilLearningProgressBaseGUI::_getStatusText($value); 494 $value = ilUtil::img($path, $text); 495 break; 496 497 case "language": 498 $lng->loadLanguageModule("meta"); 499 $value = $lng->txt("meta_l_" . $value); 500 break; 501 502 case "sel_country": 503 $value = $lng->txt("meta_c_" . $value); 504 break; 505 } 506 507 return $value; 508 } 509 510 public function getCurrentFilter($as_query = false) 511 { 512 $result = array(); 513 foreach ((array) $this->filter as $id => $value) { 514 $item = $this->getFilterItemByPostVar($id); 515 switch ($id) { 516 case "title": 517 case "country": 518 case "gender": 519 case "city": 520 case "language": 521 case "login": 522 case "firstname": 523 case "lastname": 524 case "mark": 525 case "u_comment": 526 case "institution": 527 case "department": 528 case "title": 529 case "street": 530 case "zipcode": 531 case "email": 532 case "matriculation": 533 case "sel_country": 534 case "query": 535 case "type": 536 case "area": 537 if ($value) { 538 $result[$id] = $value; 539 } 540 break; 541 542 case "status": 543 if ($value !== false) { 544 $result[$id] = $value; 545 } 546 break; 547 548 case "user_total": 549 case "read_count": 550 case "percentage": 551 case "hide": 552 case "spent_seconds": 553 if (is_array($value) && implode("", $value)) { 554 $result[$id] = $value; 555 } 556 break; 557 558 case "registration": 559 case "create_date": 560 case "first_access": 561 case "last_access": 562 case 'status_changed': 563 if ($value) { 564 if ($value["from"]) { 565 $result[$id]["from"] = $value["from"]->get(IL_CAL_DATETIME); 566 } 567 if ($value["to"]) { 568 $result[$id]["to"] = $value["to"]->get(IL_CAL_DATETIME); 569 } 570 } 571 break; 572 573 case "birthday": 574 if ($value) { 575 if ($value["from"]) { 576 $result[$id]["from"] = $value["from"]->get(IL_CAL_DATETIME); 577 $result[$id]["from"] = substr($result[$id]["from"], 0, -8) . "00:00:00"; 578 } 579 if ($value["to"]) { 580 $result[$id]["to"] = $value["to"]->get(IL_CAL_DATETIME); 581 $result[$id]["to"] = substr($result[$id]["to"], 0, -8) . "23:59:59"; 582 } 583 } 584 break; 585 } 586 } 587 588 return $result; 589 } 590 591 protected function isPercentageAvailable($a_obj_id) 592 { 593 // :TODO: 594 $olp = ilObjectLP::getInstance($a_obj_id); 595 $mode = $olp->getCurrentMode(); 596 if (in_array($mode, array(ilLPObjSettings::LP_MODE_TLT, 597 ilLPObjSettings::LP_MODE_VISITS, 598 ilLPObjSettings::LP_MODE_SCORM, 599 ilLPObjSettings::LP_MODE_VISITED_PAGES, 600 ilLPObjSettings::LP_MODE_TEST_PASSED))) { 601 return true; 602 } 603 return false; 604 } 605 606 protected function parseTitle($a_obj_id, $action, $a_user_id = false) 607 { 608 global $DIC; 609 610 $lng = $DIC['lng']; 611 $ilObjDataCache = $DIC['ilObjDataCache']; 612 $ilUser = $DIC['ilUser']; 613 614 $user = ""; 615 if ($a_user_id) { 616 if ($a_user_id != $ilUser->getId()) { 617 $a_user = ilObjectFactory::getInstanceByObjId($a_user_id); 618 } else { 619 $a_user = $ilUser; 620 } 621 $user .= ", " . $a_user->getFullName(); // " [".$a_user->getLogin()."]"; 622 } 623 624 if ($a_obj_id != ROOT_FOLDER_ID) { 625 $this->setTitle($lng->txt($action) . ": " . $ilObjDataCache->lookupTitle($a_obj_id) . $user); 626 627 $olp = ilObjectLP::getInstance($a_obj_id); 628 $this->setDescription($this->lng->txt('trac_mode') . ": " . $olp->getModeText($olp->getCurrentMode())); 629 } else { 630 $this->setTitle($lng->txt($action)); 631 } 632 } 633 634 /** 635 * Build export meta data 636 * 637 * @return array 638 */ 639 protected function getExportMeta() 640 { 641 global $DIC; 642 643 $lng = $DIC['lng']; 644 $ilObjDataCache = $DIC['ilObjDataCache']; 645 $ilUser = $DIC['ilUser']; 646 $ilClientIniFile = $DIC['ilClientIniFile']; 647 648 /* see spec 649 Name of installation 650 Name of the course 651 Permalink to course 652 Owner of course object 653 Date of report generation 654 Reporting period 655 Name of person who generated the report. 656 */ 657 658 ilDatePresentation::setUseRelativeDates(false); 659 include_once './Services/Link/classes/class.ilLink.php'; 660 661 $data = array(); 662 $data[$lng->txt("trac_name_of_installation")] = $ilClientIniFile->readVariable('client', 'name'); 663 664 if ($this->obj_id) { 665 $data[$lng->txt("trac_object_name")] = $ilObjDataCache->lookupTitle($this->obj_id); 666 if ($this->ref_id) { 667 $data[$lng->txt("trac_object_link")] = ilLink::_getLink($this->ref_id, ilObject::_lookupType($this->obj_id)); 668 } 669 $data[$lng->txt("trac_object_owner")] = ilObjUser::_lookupFullname(ilObject::_lookupOwner($this->obj_id)); 670 } 671 672 $data[$lng->txt("trac_report_date")] = ilDatePresentation::formatDate(new ilDateTime(time(), IL_CAL_UNIX)); 673 $data[$lng->txt("trac_report_owner")] = $ilUser->getFullName(); 674 675 return $data; 676 } 677 678 protected function fillMetaExcel(ilExcel $a_excel, &$a_row) 679 { 680 foreach ($this->getExportMeta() as $caption => $value) { 681 $a_excel->setCell($a_row, 0, $caption); 682 $a_excel->setCell($a_row, 1, $value); 683 $a_row++; 684 } 685 $a_row++; 686 } 687 688 protected function fillMetaCSV($a_csv) 689 { 690 foreach ($this->getExportMeta() as $caption => $value) { 691 $a_csv->addColumn(strip_tags($caption)); 692 $a_csv->addColumn(strip_tags($value)); 693 $a_csv->addRow(); 694 } 695 $a_csv->addRow(); 696 } 697 698 protected function showTimingsWarning($a_ref_id, $a_user_id) 699 { 700 $timing_cache = ilTimingCache::getInstanceByRefId($a_ref_id); 701 if ($timing_cache->isWarningRequired($a_user_id)) { 702 $timings = ilTimingCache::_getTimings($a_ref_id); 703 if ($timings['item']['changeable'] && $timings['user'][$a_user_id]['end']) { 704 $end = $timings['user'][$a_user_id]['end']; 705 } elseif ($timings['item']['suggestion_end']) { 706 $end = $timings['item']['suggestion_end']; 707 } else { 708 $end = true; 709 } 710 return $end; 711 } 712 } 713 714 protected function formatSeconds($seconds, $a_shorten_zero = false) 715 { 716 $seconds = ((int) $seconds > 0) ? $seconds : 0; 717 if ($a_shorten_zero && !$seconds) { 718 return "-"; 719 } 720 721 $hours = floor($seconds / 3600); 722 $rest = $seconds % 3600; 723 724 $minutes = floor($rest / 60); 725 $rest = $rest % 60; 726 727 if ($rest) { 728 $minutes++; 729 } 730 731 return sprintf("%dh%02dm", $hours, $minutes); 732 } 733 734 protected function anonymizeValue($a_value, $a_force_number = false) 735 { 736 // currently inactive 737 return $a_value; 738 739 if (is_numeric($a_value)) { 740 $threshold = 3; 741 $a_value = (int) $a_value; 742 if ($a_value <= $threshold) { 743 if (!$a_force_number) { 744 return "0-" . $threshold; 745 } else { 746 return $threshold; 747 } 748 } 749 } 750 return $a_value; 751 } 752 753 protected function buildValueScale($a_max_value, $a_anonymize = false, $a_format_seconds = false) 754 { 755 $step = 0; 756 if ($a_max_value) { 757 $step = $a_max_value / 10; 758 $base = ceil(log($step, 10)); 759 $fac = ceil($step / pow(10, ($base - 1))); 760 $step = pow(10, $base - 1) * $fac; 761 } 762 if ($step <= 1) { 763 $step = 1; 764 } 765 $ticks = range(0, $a_max_value + $step, $step); 766 767 $value_ticks = array(0 => 0); 768 foreach ($ticks as $tick) { 769 $value = $tvalue = $tick; 770 if ($a_anonymize) { 771 $value = $this->anonymizeValue($value, true); 772 $tvalue = $this->anonymizeValue($tvalue); 773 } 774 if ($a_format_seconds) { 775 $tvalue = $this->formatSeconds($value); 776 } 777 $value_ticks[$value] = $tvalue; 778 } 779 780 return $value_ticks; 781 } 782 783 protected function getMonthsFilter($a_short = false) 784 { 785 global $DIC; 786 787 $lng = $DIC['lng']; 788 789 $options = array(); 790 for ($loop = 0; $loop < 10; $loop++) { 791 $year = date("Y") - $loop; 792 $options[$year] = $year; 793 for ($loop2 = 12; $loop2 > 0; $loop2--) { 794 $month = str_pad($loop2, 2, "0", STR_PAD_LEFT); 795 if ($year . $month <= date("Ym")) { 796 if (!$a_short) { 797 $caption = $year . " / " . $lng->txt("month_" . $month . "_long"); 798 } else { 799 $caption = $year . "/" . $month; 800 } 801 $options[$year . "-" . $month] = $caption; 802 } 803 } 804 } 805 return $options; 806 } 807 808 protected function getMonthsYear($a_year = null, $a_short = false) 809 { 810 global $DIC; 811 812 $lng = $DIC['lng']; 813 814 if (!$a_year) { 815 $a_year = date("Y"); 816 } 817 818 $all = array(); 819 for ($loop = 1; $loop < 13; $loop++) { 820 $month = str_pad($loop, 2, "0", STR_PAD_LEFT); 821 if ($a_year . "-" . $month <= date("Y-m")) { 822 if (!$a_short) { 823 $caption = $lng->txt("month_" . $month . "_long"); 824 } else { 825 $caption = $lng->txt("month_" . $month . "_short"); 826 } 827 $all[$a_year . "-" . $month] = $caption; 828 } 829 } 830 return $all; 831 } 832 833 protected function getSelectableUserColumns($a_in_course = false, $a_in_group = false) 834 { 835 global $DIC; 836 837 $lng = $DIC['lng']; 838 $ilSetting = $DIC['ilSetting']; 839 840 $cols = $privacy_fields = array(); 841 842 include_once("./Services/User/classes/class.ilUserProfile.php"); 843 $up = new ilUserProfile(); 844 $up->skipGroup("preferences"); 845 $up->skipGroup("settings"); 846 $up->skipGroup("interests"); 847 $ufs = $up->getStandardFields(); 848 849 // default fields 850 $cols["login"] = array( 851 "txt" => $lng->txt("login"), 852 "default" => true); 853 854 if (!$this->anonymized) { 855 $cols["firstname"] = array( 856 "txt" => $lng->txt("firstname"), 857 "default" => true); 858 $cols["lastname"] = array( 859 "txt" => $lng->txt("lastname"), 860 "default" => true); 861 } 862 863 // show only if extended data was activated in lp settings 864 include_once 'Services/Tracking/classes/class.ilObjUserTracking.php'; 865 $tracking = new ilObjUserTracking(); 866 if ($tracking->hasExtendedData(ilObjUserTracking::EXTENDED_DATA_LAST_ACCESS)) { 867 $cols["first_access"] = array( 868 "txt" => $lng->txt("trac_first_access"), 869 "default" => true); 870 $cols["last_access"] = array( 871 "txt" => $lng->txt("trac_last_access"), 872 "default" => true); 873 } 874 if ($tracking->hasExtendedData(ilObjUserTracking::EXTENDED_DATA_READ_COUNT)) { 875 $cols["read_count"] = array( 876 "txt" => $lng->txt("trac_read_count"), 877 "default" => true); 878 } 879 if ($tracking->hasExtendedData(ilObjUserTracking::EXTENDED_DATA_SPENT_SECONDS) && 880 ilObjectLP::supportsSpentSeconds($this->type)) { 881 $cols["spent_seconds"] = array( 882 "txt" => $lng->txt("trac_spent_seconds"), 883 "default" => true); 884 } 885 886 if ($this->isPercentageAvailable($this->obj_id)) { 887 $cols["percentage"] = array( 888 "txt" => $lng->txt("trac_percentage"), 889 "default" => true); 890 } 891 892 // do not show status if learning progress is deactivated 893 $olp = ilObjectLP::getInstance($this->obj_id); 894 if ($olp->isActive()) { 895 $cols["status"] = array( 896 "txt" => $lng->txt("trac_status"), 897 "default" => true); 898 899 $cols['status_changed'] = array( 900 'txt' => $lng->txt('trac_status_changed'), 901 'default' => false); 902 } 903 904 if (ilObjectLP::supportsMark($this->type)) { 905 $cols["mark"] = array( 906 "txt" => $lng->txt("trac_mark"), 907 "default" => true); 908 } 909 910 $cols["u_comment"] = array( 911 "txt" => $lng->txt("trac_comment"), 912 "default" => false); 913 914 $cols["create_date"] = array( 915 "txt" => $lng->txt("create_date"), 916 "default" => false); 917 $cols["language"] = array( 918 "txt" => $lng->txt("language"), 919 "default" => false); 920 921 // add user data only if object is [part of] course 922 if (!$this->anonymized && 923 ($a_in_course || $a_in_group)) { 924 // only show if export permission is granted 925 include_once('Services/PrivacySecurity/classes/class.ilPrivacySettings.php'); 926 if (ilPrivacySettings::_getInstance()->checkExportAccess($this->ref_id)) { 927 // other user profile fields 928 foreach ($ufs as $f => $fd) { 929 if (!isset($cols[$f]) && $f != "username" && !$fd["lists_hide"]) { 930 if ($a_in_course && 931 !($fd["course_export_fix_value"] || $ilSetting->get("usr_settings_course_export_" . $f))) { 932 continue; 933 } 934 if ($a_in_group && 935 !($fd["group_export_fix_value"] || $ilSetting->get("usr_settings_group_export_" . $f))) { 936 continue; 937 } 938 939 $cols[$f] = array( 940 "txt" => $lng->txt($f), 941 "default" => false); 942 943 $privacy_fields[] = $f; 944 } 945 } 946 947 // additional defined user data fields 948 include_once './Services/User/classes/class.ilUserDefinedFields.php'; 949 $user_defined_fields = ilUserDefinedFields::_getInstance(); 950 if ($a_in_course) { 951 $user_defined_fields = $user_defined_fields->getCourseExportableFields(); 952 } else { 953 $user_defined_fields = $user_defined_fields->getGroupExportableFields(); 954 } 955 foreach ($user_defined_fields as $definition) { 956 if ($definition["field_type"] != UDF_TYPE_WYSIWYG) { 957 $f = "udf_" . $definition["field_id"]; 958 $cols[$f] = array( 959 "txt" => $definition["field_name"], 960 "default" => false); 961 962 $privacy_fields[] = $f; 963 } 964 } 965 } 966 } 967 968 return array($cols, $privacy_fields); 969 } 970 971 /** 972 * Add selected users to clipboard 973 */ 974 protected function addToClipboard() 975 { 976 $users = (array) $_POST['uid']; 977 include_once './Services/User/classes/class.ilUserClipboard.php'; 978 $clip = ilUserClipboard::getInstance($GLOBALS['DIC']['ilUser']->getId()); 979 $clip->add($users); 980 $clip->save(); 981 982 $GLOBALS['DIC']['lng']->loadLanguageModule('user'); 983 ilUtil::sendSuccess($this->lng->txt('clipboard_user_added'), true); 984 } 985} 986