ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilObjUserFolder.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
27 {
28  public const ORG_OP_EDIT_USER_ACCOUNTS = 'edit_user_accounts';
29  public const FILE_TYPE_EXCEL = 'userfolder_export_excel_x86';
30  public const FILE_TYPE_CSV = 'userfolder_export_csv';
31  public const FILE_TYPE_XML = 'userfolder_export_xml';
32 
33  public function __construct(
34  int $a_id,
35  bool $a_call_by_reference = true
36  ) {
37  $this->type = "usrf";
38  parent::__construct($a_id, $a_call_by_reference);
39  }
40 
41 
42  public function delete(): bool
43  {
44  return false;
45  }
46 
47  public function getExportFilename(
48  string $a_mode = self::FILE_TYPE_EXCEL
49  ): string {
50  $filename = "";
51  $inst_id = IL_INST_ID;
52 
53  $date = time();
54 
55  switch ($a_mode) {
56  case self::FILE_TYPE_EXCEL:
57  $filename = $date . "__" . $inst_id . "__xls_usrf";
58  break;
59  case self::FILE_TYPE_CSV:
60  $filename = $date . "__" . $inst_id . "__csv_usrf.csv";
61  break;
62  case self::FILE_TYPE_XML:
63  $filename = $date . "__" . $inst_id . "__xml_usrf.xml";
64  break;
65  }
66  return $filename;
67  }
68 
69  public function getExportDirectory(): string
70  {
71  $export_dir = ilFileUtils::getDataDir() . "/usrf_data/export";
72 
73  return $export_dir;
74  }
75 
80  public function getExportFiles(): array
81  {
82  $dir = $this->getExportDirectory();
83 
84  // quit if export dir not available
85  if (!is_dir($dir) or
86  !is_writable($dir)) {
87  return [];
88  }
89 
90  // open directory
91  $dir = dir($dir);
92 
93  // initialize array
94  $file = [];
95 
96  // get files and save the in the array
97  while ($entry = $dir->read()) {
98  if ($entry != "." and
99  $entry != ".." and
100  preg_match("/^[0-9]{10}_{2}[0-9]+_{2}([a-z0-9]{3})_usrf\.[a-z]{1,4}\$/", $entry, $matches)) {
101  $filearray["filename"] = $entry;
102  $filearray["filesize"] = filesize($this->getExportDirectory() . "/" . $entry);
103  $file[] = $filearray;
104  }
105  }
106 
107  // close import directory
108  $dir->close();
109 
110  // sort files
111  sort($file);
112 
113  return $file;
114  }
115 
116  protected function escapeXML(string $value): string
117  {
118  return str_replace(['&', '<', '>'], ['&amp;', '&lt;', '&gt;'], $value);
119  }
120 
121  protected function createXMLExport(
122  array $settings,
123  array $data,
124  string $filename
125  ): void {
126  $xml_writer = new ilUserXMLWriter();
127  $xml_writer->setObjects($data);
128  $xml_writer->setSettings($settings);
129  $xml_writer->setAttachRoles(true);
130 
131  if ($xml_writer->start()) {
132  fwrite(fopen($filename, 'wb'), $xml_writer->getXML());
133  }
134  }
135 
136  protected function getUserDefinedExportFields(): array // Missing array type.
137  {
138  $udf_ex_fields = [];
139  foreach (ilUserDefinedFields::_getInstance()->getDefinitions() as $definition) {
140  if ($definition['export'] != false) {
141  $udf_ex_fields[] = ['name' => $definition['field_name'],
142  'id' => $definition['field_id']];
143  }
144  }
145 
146  return $udf_ex_fields;
147  }
148 
149  protected function createCSVExport(
150  array $settings,
151  array $data,
152  string $filename
153  ): void {
154  $headerrow = [];
155  $udf_ex_fields = $this->getUserDefinedExportFields();
156  foreach ($settings as $value) { // standard fields
157  $headerrow[] = $this->lng->txt($value);
158  }
159  foreach ($udf_ex_fields as $f) { // custom fields
160  $headerrow[] = $f["name"];
161  }
162 
163  $separator = ";";
164  $file = fopen($filename, 'wb');
165  fwrite($file, $this->processCSVRow($headerrow) . "\n");
166  foreach ($data as $row) {
167  $csvrow = [];
168  foreach ($settings as $header) { // standard fields
169  // multi-text
170  if (isset($row[$header]) && is_array($row[$header])) {
171  $row[$header] = implode(", ", $row[$header]);
172  }
173 
174  $csvrow[] = $row[$header] ?? '';
175  }
176 
177  // custom fields
178  reset($udf_ex_fields);
179  if (count($udf_ex_fields) > 0) {
180  $udf = new ilUserDefinedData($row["usr_id"]);
181  foreach ($udf_ex_fields as $f) { // custom fields
182  $csvrow[] = $udf->get("f_" . $f["id"]);
183  }
184  }
185 
186  fwrite($file, $this->processCSVRow($csvrow) . "\n");
187  }
188  fclose($file);
189  }
190 
191  protected function createExcelExport(
192  array $settings,
193  array $data,
194  string $filename
195  ): void {
196  $worksheet = new ilExcel();
197  $worksheet->addSheet($this->lng->txt("users"));
198 
199  $row = 1;
200  $col = 0;
201 
202  $udf_ex_fields = $this->getUserDefinedExportFields();
203 
204  // title row
205  foreach ($settings as $value) { // standard fields
206  if ($value == 'ext_account') {
207  $value = 'user_ext_account';
208  }
209  $worksheet->setCell($row, $col, $this->lng->txt($value));
210  $col++;
211  }
212  foreach ($udf_ex_fields as $f) { // custom fields
213  $worksheet->setCell($row, $col, $f["name"]);
214  $col++;
215  }
216  $worksheet->setBold("A1:" . $worksheet->getColumnCoord($col - 1) . "1");
217 
218  $this->lng->loadLanguageModule("meta");
219  foreach ($data as $index => $rowdata) {
220  $row++;
221  $col = 0;
222 
223  // standard fields
224  foreach ($settings as $fieldname) {
225  $value = $rowdata[$fieldname] ?? "";
226  switch ($fieldname) {
227  case "language":
228  $worksheet->setCell($row, $col, $this->lng->txt("meta_l_" . $value));
229  break;
230  case "time_limit_from":
231  case "time_limit_until":
232  $value = $value
233  ? new ilDateTime($value, IL_CAL_UNIX)
234  : null;
235  $worksheet->setCell($row, $col, $value);
236  break;
237  case "last_login":
238  case "last_update":
239  case "create_date":
240  case "approve_date":
241  case "agree_date":
242  $value = $value
243  ? new ilDateTime($value, IL_CAL_DATETIME)
244  : null;
245  $worksheet->setCell($row, $col, $value);
246  break;
247 
248  case "interests_general":
249  case "interests_help_offered":
250  case "interests_help_looking":
251  if (is_array($value) && count($value)) {
252  $value = implode(", ", $value);
253  } else {
254  $value = null;
255  }
256  // fallthrough
257 
258  // no break
259  default:
260  $worksheet->setCell($row, $col, $value);
261  break;
262  }
263  $col++;
264  }
265 
266  // custom fields
267  reset($udf_ex_fields);
268  if (count($udf_ex_fields) > 0) {
269  $udf = new ilUserDefinedData($rowdata["usr_id"]);
270  foreach ($udf_ex_fields as $f) { // custom fields
271  $worksheet->setCell($row, $col, $udf->get("f_" . $f["id"]));
272  $col++;
273  }
274  }
275  }
276 
277  $worksheet->writeToFile($filename);
278  }
279 
283  public static function getExportSettings(): array // Missing array type.
284  {
285  global $DIC;
286 
287  $ilDB = $DIC['ilDB'];
288 
289  $db_settings = [];
290 
291  $up = new ilUserProfile();
292  $up->skipField("roles");
293  $profile_fields = $up->getStandardFields();
294 
295  $query = "SELECT * FROM settings WHERE " .
296  $ilDB->like("keyword", "text", '%usr_settings_export_%');
297  $result = $ilDB->query($query);
298  while ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
299  if ($row["value"] == "1") {
300  if (preg_match("/usr_settings_export_(.*)/", $row["keyword"], $setting)) {
301  $db_settings[] = $setting[1];
302  }
303  }
304  }
305  $export_settings = [];
306  foreach ($profile_fields as $key => $value) {
307  if (in_array($key, $db_settings)) {
308  if (strcmp($key, "password") == 0) {
309  // we do not support password export with ILIAS >= 4.5.x
310  continue;
311  } else {
312  $export_settings[] = $key;
313  }
314  }
315  }
316  $export_settings[] = "usr_id";
317  $export_settings[] = "login";
318  $export_settings[] = "last_login";
319  $export_settings[] = "last_update";
320  $export_settings[] = "create_date";
321  $export_settings[] = "time_limit_owner";
322  $export_settings[] = "time_limit_unlimited";
323  $export_settings[] = "time_limit_from";
324  $export_settings[] = "time_limit_until";
325  $export_settings[] = "time_limit_message";
326  $export_settings[] = "active";
327  $export_settings[] = "approve_date";
328  $export_settings[] = "agree_date";
329  $export_settings[] = "client_ip";
330  $export_settings[] = "auth_mode";
331  $export_settings[] = "ext_account";
332  $export_settings[] = "feedhash";
333  return $export_settings;
334  }
335 
339  public function buildExportFile(
340  string $a_mode = self::FILE_TYPE_EXCEL,
341  ?array $user_data_filter = null,
342  bool $use_temp_dir = false
343  ): string {
344  global $DIC;
345 
346  $ilDB = $DIC['ilDB'];
347  $lng = $DIC['lng'];
348 
349  if ($use_temp_dir) {
350  $expDir = ilFileUtils::ilTempnam();
351  $fullname = $expDir;
352  } else {
353  $expDir = $this->getExportDirectory();
354  // create export directory if needed
355  $this->createExportDirectory();
356  $fullname = $expDir . "/" . $this->getExportFilename($a_mode);
357  }
358 
359  //get data
360  //$expLog->write(date("[y-m-d H:i:s] ")."User data export: build an array of all user data entries");
361  $settings = self::getExportSettings();
362 
363  // user languages
364  $query = "SELECT * FROM usr_pref WHERE keyword = " . $ilDB->quote('language', 'text');
365  $res = $ilDB->query($query);
366  $languages = [];
367  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
368  $languages[$row['usr_id']] = $row['value'];
369  }
370 
371  // multi-text
372  $multi = [];
373  $set = $ilDB->query("SELECT * FROM usr_data_multi");
374  while ($row = $ilDB->fetchAssoc($set)) {
375  if (!is_array($user_data_filter) ||
376  in_array($row["usr_id"], $user_data_filter)) {
377  $multi[$row["usr_id"]][$row["field_id"]][] = $row["value"];
378  }
379  }
380 
381  $data = [];
382  $query = "SELECT usr_data.* FROM usr_data " .
383  " ORDER BY usr_data.lastname, usr_data.firstname";
384  $result = $ilDB->query($query);
385  while ($row = $ilDB->fetchAssoc($result)) {
386  if (isset($languages[$row['usr_id']])) {
387  $row['language'] = $languages[$row['usr_id']];
388  } else {
389  $row['language'] = $lng->getDefaultLanguage();
390  }
391 
392  if (isset($multi[$row["usr_id"]])) {
393  $row = array_merge($row, $multi[$row["usr_id"]]);
394  }
395 
396  if (is_array($user_data_filter)) {
397  if (in_array($row["usr_id"], $user_data_filter)) {
398  $data[] = $row;
399  }
400  } else {
401  $data[] = $row;
402  }
403  }
404  //$expLog->write(date("[y-m-d H:i:s] ")."User data export: build an array of all user data entries");
405 
406  switch ($a_mode) {
407  case self::FILE_TYPE_EXCEL:
408  $this->createExcelExport($settings, $data, $fullname);
409  break;
410  case self::FILE_TYPE_CSV:
411  $this->createCSVExport($settings, $data, $fullname);
412  break;
413  case self::FILE_TYPE_XML:
414  $this->createXMLExport($settings, $data, $fullname);
415  break;
416  }
417  return $fullname;
418  }
419 
420  private function processCSVRow(array $row): array
421  {
422  $resultarray = [];
423  foreach ($row as $rowindex => $entry) {
424  $resultarray[$rowindex] = iconv(
425  'UTF-8',
426  'ISO-8859-1',
427  '"' . str_replace(chr(13) . chr(10), chr(10), $entry) . '"'
428  );
429  }
430  return implode(';', $resultarray);
431  }
432 
433 
437  protected function createExportDirectory(): void
438  {
439  if (!is_dir($this->getExportDirectory())) {
440  $usrf_data_dir = ilFileUtils::getDataDir() . "/usrf_data";
441  ilFileUtils::makeDir($usrf_data_dir);
442  if (!is_writable($usrf_data_dir)) {
443  $this->ilias->raiseError("Userfolder data directory (" . $usrf_data_dir
444  . ") not writeable.", $this->ilias->error_obj->MESSAGE);
445  }
446 
447  // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
448  $export_dir = $usrf_data_dir . "/export";
449  ilFileUtils::makeDir($export_dir);
450  if (!is_dir($export_dir)) {
451  $this->ilias->raiseError("Creation of Userfolder Export Directory failed.", $this->ilias->error_obj->MESSAGE);
452  }
453  }
454  }
455 
456 
461  public static function getProfileFields(): array // Missing array type.
462  {
463  $up = new ilUserProfile();
464  $up->skipField("username");
465  $up->skipField("roles");
466  $up->skipGroup("preferences");
467  $fds = $up->getStandardFields();
468  $profile_fields = [];
469  foreach ($fds as $k => $f) {
470  $profile_fields[] = $k;
471  }
472 
473  return $profile_fields;
474  }
475 
476  public static function _writeNewAccountMail(
477  string $a_lang,
478  string $a_subject,
479  string $a_sal_g,
480  string $a_sal_f,
481  string $a_sal_m,
482  string $a_body
483  ): void {
484  global $DIC;
485 
486  $ilDB = $DIC['ilDB'];
487 
488  if (self::_lookupNewAccountMail($a_lang)) {
489  $values = [
490  'subject' => ['text',$a_subject],
491  'body' => ['clob',$a_body],
492  'sal_g' => ['text',$a_sal_g],
493  'sal_f' => ['text',$a_sal_f],
494  'sal_m' => ['text',$a_sal_m]
495  ];
496  $ilDB->update(
497  'mail_template',
498  $values,
499  ['lang' => ['text',$a_lang], 'type' => ['text','nacc']]
500  );
501  } else {
502  $values = [
503  'subject' => ['text',$a_subject],
504  'body' => ['clob',$a_body],
505  'sal_g' => ['text',$a_sal_g],
506  'sal_f' => ['text',$a_sal_f],
507  'sal_m' => ['text',$a_sal_m],
508  'lang' => ['text',$a_lang],
509  'type' => ['text','nacc']
510  ];
511  $ilDB->insert('mail_template', $values);
512  }
513  }
514 
519  public static function _updateAccountMailAttachment(
520  string $a_lang,
521  string $a_tmp_name,
522  string $a_name
523  ): void {
524  global $DIC;
525 
526  $ilDB = $DIC['ilDB'];
527 
529  $fs->create();
530  $path = $fs->getAbsolutePath() . "/";
531 
532  ilFileUtils::moveUploadedFile($a_tmp_name, $a_lang, $path . $a_lang);
533 
534  $ilDB->update(
535  'mail_template',
536  ['att_file' => ['text', $a_name]],
537  ['lang' => ['text',$a_lang], 'type' => ['text','nacc']]
538  );
539  }
540 
544  public static function _deleteAccountMailAttachment(
545  string $a_lang
546  ): void {
547  global $DIC;
548 
549  $ilDB = $DIC['ilDB'];
550 
552  $path = $fs->getAbsolutePath() . "/";
553 
554  if (file_exists($path . $a_lang)) {
555  unlink($path . $a_lang);
556  }
557 
558  $ilDB->update(
559  'mail_template',
560  ['att_file' => ['text', '']],
561  ['lang' => ['text',$a_lang], 'type' => ['text','nacc']]
562  );
563  }
564 
569  public static function _lookupNewAccountMail(string $a_lang): array
570  {
571  global $DIC;
572 
573  $ilDB = $DIC['ilDB'];
574 
575  $set = $ilDB->query("SELECT * FROM mail_template " .
576  " WHERE type='nacc' AND lang = " . $ilDB->quote($a_lang, 'text'));
577 
578  if ($rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
579  return $rec;
580  }
581 
582  return [];
583  }
584 
590  public static function _updateUserFolderAssignment(
591  int $a_old_id,
592  int $a_new_id
593  ): void {
594  global $DIC;
595 
596  $ilDB = $DIC['ilDB'];
597 
598  $query = "UPDATE usr_data SET time_limit_owner = " . $ilDB->quote($a_new_id, "integer") . " " .
599  "WHERE time_limit_owner = " . $ilDB->quote($a_old_id, "integer") . " ";
600  $ilDB->manipulate($query);
601  }
602 }
createXMLExport(array $settings, array $data, string $filename)
Class ilObjUserFolder.
$res
Definition: ltiservices.php:66
static _writeNewAccountMail(string $a_lang, string $a_subject, string $a_sal_g, string $a_sal_f, string $a_sal_m, string $a_body)
const IL_INST_ID
Definition: constants.php:40
const IL_CAL_DATETIME
const USER_FOLDER_ID
Definition: constants.php:33
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _updateUserFolderAssignment(int $a_old_id, int $a_new_id)
Update user folder assignment Typically called after deleting a category with local user accounts...
getDefaultLanguage()
Return default language.
getExportFiles()
Get a list of the already exported files in the export directory.
Class ilUserProfile.
static getProfileFields()
Get profile fields.
static _updateAccountMailAttachment(string $a_lang, string $a_tmp_name, string $a_name)
Update account mail attachment.
const IL_CAL_UNIX
createExportDirectory()
creates data directory for export files
createExcelExport(array $settings, array $data, string $filename)
sort()
description: > Example for rendering a Sort Glyph.
Definition: sort.php:41
$path
Definition: ltiservices.php:29
createCSVExport(array $settings, array $data, string $filename)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getExportFilename(string $a_mode=self::FILE_TYPE_EXCEL)
buildExportFile(string $a_mode=self::FILE_TYPE_EXCEL, ?array $user_data_filter=null, bool $use_temp_dir=false)
build xml export file
static _lookupNewAccountMail(string $a_lang)
XML writer class Class to simplify manual writing of xml documents.
ilLanguage $lng
escapeXML(string $value)
global $DIC
Definition: shib_login.php:26
Class ilObjForumAdministration.
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static _deleteAccountMailAttachment(string $a_lang)
Delete account mail attachment.
static getDataDir()
get data directory (outside webspace)
$filename
Definition: buildRTE.php:78
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
__construct(Container $dic, ilPlugin $plugin)
__construct(int $a_id, bool $a_call_by_reference=true)
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...