ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjUserFolder.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27
34{
35 public const ORG_OP_EDIT_USER_ACCOUNTS = 'edit_user_accounts';
36 public const FILE_TYPE_EXCEL = 'userfolder_export_excel_x86';
37 public const FILE_TYPE_CSV = 'userfolder_export_csv';
38 public const FILE_TYPE_XML = 'userfolder_export_xml';
39
41
42 public function __construct(
43 int $a_id,
44 bool $a_call_by_reference = true
45 ) {
46 $this->type = "usrf";
47 parent::__construct($a_id, $a_call_by_reference);
48
49 $this->profile = LocalDIC::dic()[Profile::class];
50 }
51
52
53 public function delete(): bool
54 {
55 return false;
56 }
57
58 public function getExportFilename(
59 string $a_mode = self::FILE_TYPE_EXCEL
60 ): string {
61 $filename = "";
62 $inst_id = IL_INST_ID;
63
64 $date = time();
65
66 switch ($a_mode) {
68 $filename = $date . "__" . $inst_id . "__xls_usrf";
69 break;
71 $filename = $date . "__" . $inst_id . "__csv_usrf.csv";
72 break;
74 $filename = $date . "__" . $inst_id . "__xml_usrf.xml";
75 break;
76 }
77 return $filename;
78 }
79
80 public function getExportDirectory(): string
81 {
82 $export_dir = ilFileUtils::getDataDir() . "/usrf_data/export";
83
84 return $export_dir;
85 }
86
91 public function getExportFiles(): array
92 {
93 $dir = $this->getExportDirectory();
94
95 // quit if export dir not available
96 if (!is_dir($dir) or
97 !is_writable($dir)) {
98 return [];
99 }
100
101 // open directory
102 $dir = dir($dir);
103
104 // initialize array
105 $file = [];
106
107 // get files and save the in the array
108 while ($entry = $dir->read()) {
109 if ($entry != "." and
110 $entry != ".." and
111 preg_match("/^[0-9]{10}_{2}[0-9]+_{2}([a-z0-9]{3})_usrf\.[a-z]{1,4}\$/", $entry, $matches)) {
112 $filearray["filename"] = $entry;
113 $filearray["filesize"] = filesize($this->getExportDirectory() . "/" . $entry);
114 $file[] = $filearray;
115 }
116 }
117
118 // close import directory
119 $dir->close();
120
121 // sort files
122 sort($file);
123
124 return $file;
125 }
126
127 protected function escapeXML(string $value): string
128 {
129 return str_replace(['&', '<', '>'], ['&amp;', '&lt;', '&gt;'], $value);
130 }
131
132 protected function createXMLExport(
133 array $settings,
134 array $data,
135 string $filename
136 ): void {
137 $xml_writer = new ilUserXMLWriter();
138 $xml_writer->setObjects($data);
139 $xml_writer->setSettings($settings);
140 $xml_writer->setAttachRoles(true);
141
142 if ($xml_writer->start()) {
143 fwrite(fopen($filename, 'wb'), $xml_writer->getXML());
144 }
145 }
146
147 protected function getUserDefinedExportFields(): array // Missing array type.
148 {
149 return array_map(
150 fn(Field $v): array => [
151 'name' => $v->getLabel($this->lng),
152 'id' => $v->getIdentifier()
153 ],
154 $this->profile->getVisibleUserDefinedFields(Context::Export)
155 );
156 }
157
158 protected function createCSVExport(
159 array $settings,
160 array $data,
161 string $filename
162 ): void {
163 $headerrow = [];
164 $udf_ex_fields = $this->getUserDefinedExportFields();
165 foreach ($settings as $value) { // standard fields
166 $headerrow[] = $this->lng->txt($value);
167 }
168 foreach ($udf_ex_fields as $f) { // custom fields
169 $headerrow[] = $f["name"];
170 }
171
172 $separator = ";";
173 $file = fopen($filename, 'wb');
174 fwrite($file, $this->processCSVRow($headerrow) . "\n");
175 foreach ($data as $row) {
176 $csvrow = [];
177 foreach ($settings as $header) { // standard fields
178 // multi-text
179 if (isset($row[$header]) && is_array($row[$header])) {
180 $row[$header] = implode(", ", $row[$header]);
181 }
182
183 $csvrow[] = $row[$header] ?? '';
184 }
185
186 // custom fields
187 reset($udf_ex_fields);
188 if (count($udf_ex_fields) > 0) {
189 $udf = new ilUserDefinedData($row["usr_id"]);
190 foreach ($udf_ex_fields as $f) { // custom fields
191 $csvrow[] = $udf->get("f_" . $f["id"]);
192 }
193 }
194
195 fwrite($file, $this->processCSVRow($csvrow) . "\n");
196 }
197 fclose($file);
198 }
199
200 protected function createExcelExport(
201 array $settings,
202 array $data,
203 string $filename
204 ): void {
205 $worksheet = new ilExcel();
206 $worksheet->addSheet($this->lng->txt("users"));
207
208 $row = 1;
209 $col = 0;
210
211 $udf_ex_fields = $this->getUserDefinedExportFields();
212
213 // title row
214 foreach ($settings as $value) { // standard fields
215 if ($value == 'ext_account') {
216 $value = 'user_ext_account';
217 }
218 $worksheet->setCell($row, $col, $this->lng->txt($value));
219 $col++;
220 }
221 foreach ($udf_ex_fields as $f) { // custom fields
222 $worksheet->setCell($row, $col, $f["name"]);
223 $col++;
224 }
225 $worksheet->setBold("A1:" . $worksheet->getColumnCoord($col - 1) . "1");
226
227 $this->lng->loadLanguageModule("meta");
228 foreach ($data as $index => $rowdata) {
229 $row++;
230 $col = 0;
231
232 // standard fields
233 foreach ($settings as $fieldname) {
234 $value = $rowdata[$fieldname] ?? "";
235 switch ($fieldname) {
236 case "language":
237 $worksheet->setCell($row, $col, $this->lng->txt("meta_l_" . $value));
238 break;
239 case "time_limit_from":
240 case "time_limit_until":
241 $value = $value
242 ? new ilDateTime($value, IL_CAL_UNIX)
243 : null;
244 $worksheet->setCell($row, $col, $value);
245 break;
246 case "last_login":
247 case "last_update":
248 case "create_date":
249 case "approve_date":
250 case "agree_date":
251 $value = $value
252 ? new ilDateTime($value, IL_CAL_DATETIME)
253 : null;
254 $worksheet->setCell($row, $col, $value);
255 break;
256
257 case "interests_general":
258 case "interests_help_offered":
259 case "interests_help_looking":
260 if (is_array($value) && count($value)) {
261 $value = implode(", ", $value);
262 } else {
263 $value = null;
264 }
265 // fallthrough
266
267 // no break
268 default:
269 $worksheet->setCell($row, $col, $value);
270 break;
271 }
272 $col++;
273 }
274
275 // custom fields
276 reset($udf_ex_fields);
277 if (count($udf_ex_fields) > 0) {
278 $udf = new ilUserDefinedData($rowdata["usr_id"]);
279 foreach ($udf_ex_fields as $f) { // custom fields
280 $worksheet->setCell($row, $col, $udf->get("f_" . $f["id"]));
281 $col++;
282 }
283 }
284 }
285
286 $worksheet->writeToFile($filename);
287 }
288
292 public static function getExportSettings(): array // Missing array type.
293 {
294 global $DIC;
295
296 $ilDB = $DIC['ilDB'];
297
298 $db_settings = [];
299
300 $up = LocalDIC::dic()[Profile::class];
301 $profile_fields = $up->getFields([], [Roles::class]);
302
303 $query = "SELECT * FROM settings WHERE " .
304 $ilDB->like("keyword", "text", '%usr_settings_export_%');
305 $result = $ilDB->query($query);
306 while ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
307 if ($row["value"] == "1") {
308 if (preg_match("/usr_settings_export_(.*)/", $row["keyword"], $setting)) {
309 $db_settings[] = $setting[1];
310 }
311 }
312 }
313 $export_settings = [];
314 foreach ($profile_fields as $key => $value) {
315 if (in_array($key, $db_settings)) {
316 if (strcmp($key, "password") == 0) {
317 // we do not support password export with ILIAS >= 4.5.x
318 continue;
319 } else {
320 $export_settings[] = $key;
321 }
322 }
323 }
324 $export_settings[] = "usr_id";
325 $export_settings[] = "login";
326 $export_settings[] = "last_login";
327 $export_settings[] = "last_update";
328 $export_settings[] = "create_date";
329 $export_settings[] = "time_limit_owner";
330 $export_settings[] = "time_limit_unlimited";
331 $export_settings[] = "time_limit_from";
332 $export_settings[] = "time_limit_until";
333 $export_settings[] = "time_limit_message";
334 $export_settings[] = "active";
335 $export_settings[] = "approve_date";
336 $export_settings[] = "agree_date";
337 $export_settings[] = "client_ip";
338 $export_settings[] = "auth_mode";
339 $export_settings[] = "ext_account";
340 $export_settings[] = "feedhash";
341 return $export_settings;
342 }
343
347 public function buildExportFile(
348 string $a_mode = self::FILE_TYPE_EXCEL,
349 ?array $user_data_filter = null,
350 bool $use_temp_dir = false
351 ): string {
352 global $DIC;
353
354 $ilDB = $DIC['ilDB'];
355 $lng = $DIC['lng'];
356
357 if ($use_temp_dir) {
358 $expDir = ilFileUtils::ilTempnam();
359 $fullname = $expDir;
360 } else {
361 $expDir = $this->getExportDirectory();
362 // create export directory if needed
363 $this->createExportDirectory();
364 $fullname = $expDir . "/" . $this->getExportFilename($a_mode);
365 }
366
367 //get data
368 //$expLog->write(date("[y-m-d H:i:s] ")."User data export: build an array of all user data entries");
369 $settings = self::getExportSettings();
370
371 // user languages
372 $query = "SELECT * FROM usr_pref WHERE keyword = " . $ilDB->quote('language', 'text');
373 $res = $ilDB->query($query);
374 $languages = [];
375 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
376 $languages[$row['usr_id']] = $row['value'];
377 }
378
379 // multi-text
380 $multi = [];
381 $set = $ilDB->query("SELECT * FROM usr_profile_data");
382 while ($row = $ilDB->fetchAssoc($set)) {
383 if (!is_array($user_data_filter) ||
384 in_array($row["usr_id"], $user_data_filter)) {
385 $multi[$row["usr_id"]][$row["field_id"]][] = $row["value"];
386 }
387 }
388
389 $data = [];
390 $query = "SELECT usr_data.* FROM usr_data " .
391 " ORDER BY usr_data.lastname, usr_data.firstname";
392 $result = $ilDB->query($query);
393 while ($row = $ilDB->fetchAssoc($result)) {
394 if (isset($languages[$row['usr_id']])) {
395 $row['language'] = $languages[$row['usr_id']];
396 } else {
397 $row['language'] = $lng->getDefaultLanguage();
398 }
399
400 if (isset($multi[$row["usr_id"]])) {
401 $row = array_merge($row, $multi[$row["usr_id"]]);
402 }
403
404 if (is_array($user_data_filter)) {
405 if (in_array($row["usr_id"], $user_data_filter)) {
406 $data[] = $row;
407 }
408 } else {
409 $data[] = $row;
410 }
411 }
412 //$expLog->write(date("[y-m-d H:i:s] ")."User data export: build an array of all user data entries");
413
414 switch ($a_mode) {
415 case self::FILE_TYPE_EXCEL:
416 $this->createExcelExport($settings, $data, $fullname);
417 break;
418 case self::FILE_TYPE_CSV:
419 $this->createCSVExport($settings, $data, $fullname);
420 break;
421 case self::FILE_TYPE_XML:
422 $this->createXMLExport($settings, $data, $fullname);
423 break;
424 }
425 return $fullname;
426 }
427
428 private function processCSVRow(array $row): array
429 {
430 $resultarray = [];
431 foreach ($row as $rowindex => $entry) {
432 $resultarray[$rowindex] = iconv(
433 'UTF-8',
434 'ISO-8859-1',
435 '"' . str_replace(chr(13) . chr(10), chr(10), $entry) . '"'
436 );
437 }
438 return implode(';', $resultarray);
439 }
440
441
445 protected function createExportDirectory(): void
446 {
447 if (!is_dir($this->getExportDirectory())) {
448 $usrf_data_dir = ilFileUtils::getDataDir() . "/usrf_data";
449 ilFileUtils::makeDir($usrf_data_dir);
450 if (!is_writable($usrf_data_dir)) {
451 $this->ilias->raiseError("Userfolder data directory (" . $usrf_data_dir
452 . ") not writeable.", $this->ilias->error_obj->MESSAGE);
453 }
454
455 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
456 $export_dir = $usrf_data_dir . "/export";
457 ilFileUtils::makeDir($export_dir);
458 if (!is_dir($export_dir)) {
459 $this->ilias->raiseError("Creation of Userfolder Export Directory failed.", $this->ilias->error_obj->MESSAGE);
460 }
461 }
462 }
463
464
469 public static function getProfileFields(): array // Missing array type.
470 {
471 return array_key(LocalDIC::dic()[Profile::class]->getFields(
472 [],
473 [Alias::class, Roles::class]
474 ));
475 }
476
482 public static function _updateUserFolderAssignment(
483 int $a_old_id,
484 int $a_new_id
485 ): void {
486 global $DIC;
487
488 $ilDB = $DIC['ilDB'];
489
490 $query = "UPDATE usr_data SET time_limit_owner = " . $ilDB->quote($a_new_id, "integer") . " " .
491 "WHERE time_limit_owner = " . $ilDB->quote($a_old_id, "integer") . " ";
492 $ilDB->manipulate($query);
493 }
494}
$filename
Definition: buildRTE.php:78
const IL_CAL_UNIX
const IL_CAL_DATETIME
@classDescription Date and time handling
addSheet(string $a_name, bool $a_activate=true)
Add sheet.
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static getDataDir()
get data directory (outside webspace)
Class ilObjUserFolder.
escapeXML(string $value)
createExportDirectory()
creates data directory for export files
__construct(int $a_id, bool $a_call_by_reference=true)
createCSVExport(array $settings, array $data, string $filename)
createXMLExport(array $settings, array $data, string $filename)
static getProfileFields()
Get profile fields.
static _updateUserFolderAssignment(int $a_old_id, int $a_new_id)
Update user folder assignment Typically called after deleting a category with local user accounts.
createExcelExport(array $settings, array $data, string $filename)
buildExportFile(string $a_mode=self::FILE_TYPE_EXCEL, ?array $user_data_filter=null, bool $use_temp_dir=false)
build xml export file
getExportFilename(string $a_mode=self::FILE_TYPE_EXCEL)
getExportFiles()
Get a list of the already exported files in the export directory.
Class ilObject Basic functions for all objects.
XML writer class Class to simplify manual writing of xml documents.
setObjects(array $users)
const IL_INST_ID
Definition: constants.php:40
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ilObjForumAdministration.
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26