1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4 5/** 6* Class ilObjUserFolder 7* 8* @author Stefan Meyer <meyer@leifos.com> 9* @version $Id$ 10* 11* @extends ilObject 12*/ 13 14require_once "./Services/Object/classes/class.ilObject.php"; 15 16define('USER_FOLDER_ID', 7); 17 18class ilObjUserFolder extends ilObject 19{ 20 /** 21 * Constructor 22 * @access public 23 * @param integer reference_id or object_id 24 * @param boolean treat the id as reference_id (true) or object_id (false) 25 */ 26 public function __construct($a_id, $a_call_by_reference = true) 27 { 28 $this->type = "usrf"; 29 parent::__construct($a_id, $a_call_by_reference); 30 } 31 32 33 /** 34 * delete userfolder and all related data 35 * DISABLED 36 * @access public 37 * @return boolean true if all object data were removed; false if only a references were removed 38 */ 39 public function delete() 40 { 41 // DISABLED 42 return false; 43 44 // always call parent delete function first!! 45 if (!parent::delete()) { 46 return false; 47 } 48 // put here userfolder specific stuff 49 50 // always call parent delete function at the end!! 51 return true; 52 } 53 54 55 public function getExportFilename($a_mode = "userfolder_export_excel_x86") 56 { 57 $filename = ""; 58 //$settings = $this->ilias->getAllSettings(); 59 //$this->inst_id = $settings["inst_id"]; 60 $inst_id = IL_INST_ID; 61 62 $date = time(); 63 64 switch ($a_mode) { 65 case "userfolder_export_excel_x86": 66 $filename = $date . "__" . $inst_id . "__xls_usrf"; 67 break; 68 case "userfolder_export_csv": 69 $filename = $date . "__" . $inst_id . "__csv_usrf.csv"; 70 break; 71 case "userfolder_export_xml": 72 $filename = $date . "__" . $inst_id . "__xml_usrf.xml"; 73 break; 74 } 75 return $filename; 76 } 77 78 79 /** 80 * Get the location of the export directory for the user accounts 81 * 82 * Get the location of the export directory for the user accounts 83 * 84 * @access public 85 */ 86 public function getExportDirectory() 87 { 88 $export_dir = ilUtil::getDataDir() . "/usrf_data/export"; 89 90 return $export_dir; 91 } 92 93 /** 94 * Get a list of the already exported files in the export directory 95 * 96 * Get a list of the already exported files in the export directory 97 * 98 * @return array A list of file names 99 * @access public 100 */ 101 public function getExportFiles() 102 { 103 $dir = $this->getExportDirectory(); 104 105 // quit if export dir not available 106 if (!@is_dir($dir) or 107 !is_writeable($dir)) { 108 return array(); 109 } 110 111 // open directory 112 $dir = dir($dir); 113 114 // initialize array 115 $file = array(); 116 117 // get files and save the in the array 118 while ($entry = $dir->read()) { 119 if ($entry != "." and 120 $entry != ".." and 121 preg_match("/^[0-9]{10}_{2}[0-9]+_{2}([a-z0-9]{3})_usrf\.[a-z]{1,4}\$/", $entry, $matches)) { 122 $filearray["filename"] = $entry; 123 $filearray["filesize"] = filesize($this->getExportDirectory() . "/" . $entry); 124 array_push($file, $filearray); 125 } 126 } 127 128 // close import directory 129 $dir->close(); 130 131 // sort files 132 sort($file); 133 reset($file); 134 135 return $file; 136 } 137 138 public function escapeXML($value) 139 { 140 $value = str_replace("&", "&", $value); 141 $value = str_replace("<", "<", $value); 142 $value = str_replace(">", ">", $value); 143 return $value; 144 } 145 146 public function createXMLExport(&$settings, &$data, $filename) 147 { 148 include_once './Services/User/classes/class.ilUserDefinedData.php'; 149 include_once './Services/User/classes/class.ilObjUser.php'; 150 151 global $DIC; 152 153 $rbacreview = $DIC['rbacreview']; 154 global $DIC; 155 156 $ilDB = $DIC['ilDB']; 157 global $DIC; 158 159 $log = $DIC['log']; 160 161 $file = fopen($filename, "w"); 162 163 if (is_array($data)) { 164 include_once './Services/User/classes/class.ilUserXMLWriter.php'; 165 166 $xmlWriter = new ilUserXMLWriter(); 167 $xmlWriter->setObjects($data); 168 $xmlWriter->setSettings($settings); 169 $xmlWriter->setAttachRoles(true); 170 171 if ($xmlWriter->start()) { 172 fwrite($file, $xmlWriter->getXML()); 173 } 174 } 175 } 176 177 178 /** 179 * Get all exportable user defined fields 180 */ 181 public function getUserDefinedExportFields() 182 { 183 include_once './Services/User/classes/class.ilUserDefinedFields.php'; 184 $udf_obj = &ilUserDefinedFields::_getInstance(); 185 186 $udf_ex_fields = array(); 187 foreach ($udf_obj->getDefinitions() as $definition) { 188 if ($definition["export"] != false) { 189 $udf_ex_fields[] = array("name" => $definition["field_name"], 190 "id" => $definition["field_id"]); 191 } 192 } 193 194 return $udf_ex_fields; 195 } 196 197 public function createCSVExport(&$settings, &$data, $filename) 198 { 199 200 // header 201 $headerrow = array(); 202 $udf_ex_fields = $this->getUserDefinedExportFields(); 203 foreach ($settings as $value) { // standard fields 204 array_push($headerrow, $this->lng->txt($value)); 205 } 206 foreach ($udf_ex_fields as $f) { // custom fields 207 array_push($headerrow, $f["name"]); 208 } 209 210 $separator = ";"; 211 $file = fopen($filename, "w"); 212 $formattedrow = &ilUtil::processCSVRow($headerrow, true, $separator); 213 fwrite($file, join($separator, $formattedrow) . "\n"); 214 foreach ($data as $row) { 215 $csvrow = array(); 216 foreach ($settings as $header) { // standard fields 217 // multi-text 218 if (is_array($row[$header])) { 219 $row[$header] = implode(", ", $row[$header]); 220 } 221 222 array_push($csvrow, $row[$header]); 223 } 224 225 // custom fields 226 reset($udf_ex_fields); 227 if (count($udf_ex_fields) > 0) { 228 include_once("./Services/User/classes/class.ilUserDefinedData.php"); 229 $udf = new ilUserDefinedData($row["usr_id"]); 230 foreach ($udf_ex_fields as $f) { // custom fields 231 array_push($csvrow, $udf->get("f_" . $f["id"])); 232 } 233 } 234 235 $formattedrow = &ilUtil::processCSVRow($csvrow, true, $separator); 236 fwrite($file, join($separator, $formattedrow) . "\n"); 237 } 238 fclose($file); 239 } 240 241 public function createExcelExport(&$settings, &$data, $filename) 242 { 243 include_once "./Services/Excel/classes/class.ilExcel.php"; 244 $worksheet = new ilExcel(); 245 $worksheet->addSheet($this->lng->txt("users")); 246 247 $row = 1; 248 $col = 0; 249 250 $udf_ex_fields = $this->getUserDefinedExportFields(); 251 252 // title row 253 foreach ($settings as $value) { // standard fields 254 if ($value == 'ext_account') { 255 $value = 'user_ext_account'; 256 } 257 $worksheet->setCell($row, $col, $this->lng->txt($value)); 258 $col++; 259 } 260 foreach ($udf_ex_fields as $f) { // custom fields 261 $worksheet->setCell($row, $col, $f["name"]); 262 $col++; 263 } 264 $worksheet->setBold("A1:" . $worksheet->getColumnCoord($col - 1) . "1"); 265 266 $this->lng->loadLanguageModule("meta"); 267 foreach ($data as $index => $rowdata) { 268 $row++; 269 $col = 0; 270 271 // standard fields 272 foreach ($settings as $fieldname) { 273 $value = $rowdata[$fieldname]; 274 switch ($fieldname) { 275 case "language": 276 $worksheet->setCell($row, $col, $this->lng->txt("meta_l_" . $value)); 277 break; 278 case "time_limit_from": 279 case "time_limit_until": 280 $value = $value 281 ? new ilDateTime($value, IL_CAL_UNIX) 282 : null; 283 $worksheet->setCell($row, $col, $value); 284 break; 285 case "last_login": 286 case "last_update": 287 case "create_date": 288 case "approve_date": 289 case "agree_date": 290 $value = $value 291 ? new ilDateTime($value, IL_CAL_DATETIME) 292 : null; 293 $worksheet->setCell($row, $col, $value); 294 break; 295 296 case "interests_general": 297 case "interests_help_offered": 298 case "interests_help_looking": 299 if (is_array($value) && sizeof($value)) { 300 $value = implode(", ", $value); 301 } else { 302 $value = null; 303 } 304 // fallthrough 305 306 // no break 307 default: 308 $worksheet->setCell($row, $col, $value); 309 break; 310 } 311 $col++; 312 } 313 314 // custom fields 315 reset($udf_ex_fields); 316 if (count($udf_ex_fields) > 0) { 317 include_once("./Services/User/classes/class.ilUserDefinedData.php"); 318 $udf = new ilUserDefinedData($rowdata["usr_id"]); 319 foreach ($udf_ex_fields as $f) { // custom fields 320 $worksheet->setCell($row, $col, $udf->get("f_" . $f["id"])); 321 $col++; 322 } 323 } 324 } 325 326 $worksheet->writeToFile($filename); 327 } 328 329 /** 330 * getExport Settings 331 * 332 * @return array of exportable fields 333 */ 334 public static function getExportSettings() 335 { 336 global $DIC; 337 338 $ilDB = $DIC['ilDB']; 339 340 $db_settings = array(); 341 342 include_once("./Services/User/classes/class.ilUserProfile.php"); 343 $up = new ilUserProfile(); 344 $up->skipField("roles"); 345 $profile_fields = $up->getStandardFields(); 346 347 /*$profile_fields =& ilObjUserFolder::getProfileFields(); 348 $profile_fields[] = "preferences";*/ 349 350 $query = "SELECT * FROM settings WHERE " . 351 $ilDB->like("keyword", "text", '%usr_settings_export_%'); 352 $result = $ilDB->query($query); 353 while ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) { 354 if ($row["value"] == "1") { 355 if (preg_match("/usr_settings_export_(.*)/", $row["keyword"], $setting)) { 356 array_push($db_settings, $setting[1]); 357 } 358 } 359 } 360 $export_settings = array(); 361 foreach ($profile_fields as $key => $value) { 362 if (in_array($key, $db_settings)) { 363 if (strcmp($key, "password") == 0) { 364 // we do not support password export with ILIAS >= 4.5.x 365 continue; 366 } else { 367 array_push($export_settings, $key); 368 } 369 } 370 } 371 array_push($export_settings, "usr_id"); 372 array_push($export_settings, "login"); 373 array_push($export_settings, "last_login"); 374 array_push($export_settings, "last_update"); 375 array_push($export_settings, "create_date"); 376 array_push($export_settings, "time_limit_owner"); 377 array_push($export_settings, "time_limit_unlimited"); 378 array_push($export_settings, "time_limit_from"); 379 array_push($export_settings, "time_limit_until"); 380 array_push($export_settings, "time_limit_message"); 381 array_push($export_settings, "active"); 382 array_push($export_settings, "approve_date"); 383 array_push($export_settings, "agree_date"); 384 array_push($export_settings, "client_ip"); 385 array_push($export_settings, "auth_mode"); 386 array_push($export_settings, "ext_account"); 387 array_push($export_settings, "feedhash"); 388 return $export_settings; 389 } 390 391 /** 392 * build xml export file 393 */ 394 public function buildExportFile($a_mode = "userfolder_export_excel_x86", $user_data_filter = false) 395 { 396 global $DIC; 397 398 $ilBench = $DIC['ilBench']; 399 global $DIC; 400 401 $log = $DIC['log']; 402 global $DIC; 403 404 $ilDB = $DIC['ilDB']; 405 global $DIC; 406 407 $ilias = $DIC['ilias']; 408 global $DIC; 409 410 $lng = $DIC['lng']; 411 412 //get Log File 413 $expDir = $this->getExportDirectory(); 414 //$expLog = &$log; 415 //$expLog->delete(); 416 //$expLog->setLogFormat(""); 417 //$expLog->write(date("[y-m-d H:i:s] ")."Start export of user data"); 418 419 // create export directory if needed 420 $this->createExportDirectory(); 421 422 //get data 423 //$expLog->write(date("[y-m-d H:i:s] ")."User data export: build an array of all user data entries"); 424 $settings = &$this->getExportSettings(); 425 426 // user languages 427 $query = "SELECT * FROM usr_pref WHERE keyword = " . $ilDB->quote('language', 'text'); 428 $res = $ilDB->query($query); 429 $languages = array(); 430 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) { 431 $languages[$row['usr_id']] = $row['value']; 432 } 433 434 // multi-text 435 $multi = array(); 436 $set = $ilDB->query("SELECT * FROM usr_data_multi"); 437 while ($row = $ilDB->fetchAssoc($set)) { 438 if (!is_array($user_data_filter) || 439 in_array($row["usr_id"], $user_data_filter)) { 440 $multi[$row["usr_id"]][$row["field_id"]][] = $row["value"]; 441 } 442 } 443 444 $data = array(); 445 $query = "SELECT usr_data.* FROM usr_data " . 446 " ORDER BY usr_data.lastname, usr_data.firstname"; 447 $result = $ilDB->query($query); 448 while ($row = $ilDB->fetchAssoc($result)) { 449 if (isset($languages[$row['usr_id']])) { 450 $row['language'] = $languages[$row['usr_id']]; 451 } else { 452 $row['language'] = $lng->getDefaultLanguage(); 453 } 454 455 if (isset($multi[$row["usr_id"]])) { 456 $row = array_merge($row, $multi[$row["usr_id"]]); 457 } 458 459 if (is_array($user_data_filter)) { 460 if (in_array($row["usr_id"], $user_data_filter)) { 461 array_push($data, $row); 462 } 463 } else { 464 array_push($data, $row); 465 } 466 } 467 //$expLog->write(date("[y-m-d H:i:s] ")."User data export: build an array of all user data entries"); 468 469 $fullname = $expDir . "/" . $this->getExportFilename($a_mode); 470 switch ($a_mode) { 471 case "userfolder_export_excel_x86": 472 $this->createExcelExport($settings, $data, $fullname); 473 break; 474 case "userfolder_export_csv": 475 $this->createCSVExport($settings, $data, $fullname); 476 break; 477 case "userfolder_export_xml": 478 $this->createXMLExport($settings, $data, $fullname); 479 break; 480 } 481 //$expLog->write(date("[y-m-d H:i:s] ")."Finished export of user data"); 482 483 return $fullname; 484 } 485 486 487 /** 488 * creates data directory for export files 489 * (data_dir/usrf_data/export, depending on data 490 * directory that is set in ILIAS setup/ini) 491 */ 492 public function createExportDirectory() 493 { 494 if (!@is_dir($this->getExportDirectory())) { 495 $usrf_data_dir = ilUtil::getDataDir() . "/usrf_data"; 496 ilUtil::makeDir($usrf_data_dir); 497 if (!is_writable($usrf_data_dir)) { 498 $this->ilias->raiseError("Userfolder data directory (" . $usrf_data_dir 499 . ") not writeable.", $this->ilias->error_obj->MESSAGE); 500 } 501 502 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export) 503 $export_dir = $usrf_data_dir . "/export"; 504 ilUtil::makeDir($export_dir); 505 if (!@is_dir($export_dir)) { 506 $this->ilias->raiseError("Creation of Userfolder Export Directory failed.", $this->ilias->error_obj->MESSAGE); 507 } 508 } 509 } 510 511 512 /** 513 * Get profile fields (DEPRECATED, use ilUserProfile() instead) 514 * 515 * @return array of fieldnames 516 */ 517 public static function &getProfileFields() 518 { 519 include_once("./Services/User/classes/class.ilUserProfile.php"); 520 $up = new ilUserProfile(); 521 $up->skipField("username"); 522 $up->skipField("roles"); 523 $up->skipGroup("preferences"); 524 $fds = $up->getStandardFields(); 525 foreach ($fds as $k => $f) { 526 $profile_fields[] = $k; 527 } 528 529 return $profile_fields; 530 } 531 532 public static function _writeNewAccountMail($a_lang, $a_subject, $a_sal_g, $a_sal_f, $a_sal_m, $a_body) 533 { 534 global $DIC; 535 536 $ilDB = $DIC['ilDB']; 537 538 if (self::_lookupNewAccountMail($a_lang)) { 539 $values = array( 540 'subject' => array('text',$a_subject), 541 'body' => array('clob',$a_body), 542 'sal_g' => array('text',$a_sal_g), 543 'sal_f' => array('text',$a_sal_f), 544 'sal_m' => array('text',$a_sal_m) 545 ); 546 $ilDB->update( 547 'mail_template', 548 $values, 549 array('lang' => array('text',$a_lang), 'type' => array('text','nacc')) 550 ); 551 } else { 552 $values = array( 553 'subject' => array('text',$a_subject), 554 'body' => array('clob',$a_body), 555 'sal_g' => array('text',$a_sal_g), 556 'sal_f' => array('text',$a_sal_f), 557 'sal_m' => array('text',$a_sal_m), 558 'lang' => array('text',$a_lang), 559 'type' => array('text','nacc') 560 ); 561 $ilDB->insert('mail_template', $values); 562 } 563 } 564 565 /** 566 * Update account mail attachment 567 * @param $a_lang 568 * @param $a_tmp_name 569 * @param $a_name 570 * @throws ilFileUtilsException 571 */ 572 public static function _updateAccountMailAttachment($a_lang, $a_tmp_name, $a_name) 573 { 574 global $DIC; 575 576 $ilDB = $DIC['ilDB']; 577 578 include_once "Services/User/classes/class.ilFSStorageUserFolder.php"; 579 $fs = new ilFSStorageUserFolder(USER_FOLDER_ID); 580 $fs->create(); 581 $path = $fs->getAbsolutePath() . "/"; 582 583 ilUtil::moveUploadedFile($a_tmp_name, $a_lang, $path . $a_lang); 584 585 $ilDB->update( 586 'mail_template', 587 array('att_file' => array('text', $a_name)), 588 array('lang' => array('text',$a_lang), 'type' => array('text','nacc')) 589 ); 590 } 591 592 /** 593 * Delete account mail attachment 594 * @param $a_lang 595 */ 596 public static function _deleteAccountMailAttachment($a_lang) 597 { 598 global $DIC; 599 600 $ilDB = $DIC['ilDB']; 601 602 include_once "Services/User/classes/class.ilFSStorageUserFolder.php"; 603 $fs = new ilFSStorageUserFolder(USER_FOLDER_ID); 604 $path = $fs->getAbsolutePath() . "/"; 605 606 if (file_exists($path . $a_lang)) { 607 unlink($path . $a_lang); 608 } 609 610 $ilDB->update( 611 'mail_template', 612 array('att_file' => array('text', '')), 613 array('lang' => array('text',$a_lang), 'type' => array('text','nacc')) 614 ); 615 } 616 617 public static function _lookupNewAccountMail($a_lang) 618 { 619 global $DIC; 620 621 $ilDB = $DIC['ilDB']; 622 623 $set = $ilDB->query("SELECT * FROM mail_template " . 624 " WHERE type='nacc' AND lang = " . $ilDB->quote($a_lang, 'text')); 625 626 if ($rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) { 627 return $rec; 628 } 629 return array(); 630 } 631 632 /** 633 * Update user folder assignment 634 * Typically called after deleting a category with local user accounts. 635 * These users will be assigned to the global user folder. 636 * 637 * @access public 638 * @static 639 * 640 * @param int old_id 641 * @param int new id 642 */ 643 public static function _updateUserFolderAssignment($a_old_id, $a_new_id) 644 { 645 global $DIC; 646 647 $ilDB = $DIC['ilDB']; 648 649 $query = "UPDATE usr_data SET time_limit_owner = " . $ilDB->quote($a_new_id, "integer") . " " . 650 "WHERE time_limit_owner = " . $ilDB->quote($a_old_id, "integer") . " "; 651 $ilDB->manipulate($query); 652 653 return true; 654 } 655} // END class.ilObjUserFolder 656