ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilObjUserFolder.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22use ILIAS\User\BuildExportFieldArray;
28
35{
36 use BuildExportFieldArray;
37
38 public const string PERM_READ_ALL = 'read_all_accounts';
39 public const string PERM_READ_ALL_AND_WRITE = 'read_all_accounts,write';
40
41 public const ORG_OP_EDIT_USER_ACCOUNTS = 'edit_user_accounts';
42 public const FILE_TYPE_EXCEL = 'userfolder_export_excel_x86';
43 public const FILE_TYPE_CSV = 'userfolder_export_csv';
44 public const FILE_TYPE_XML = 'userfolder_export_xml';
45
48
49 public function __construct(
50 int $a_id,
51 bool $a_call_by_reference = true
52 ) {
53 $this->type = 'usrf';
54 parent::__construct($a_id, $a_call_by_reference);
55
56 $this->profile = LocalDIC::dic()[Profile::class];
57 $this->settings = LocalDIC::dic()[Settings::class];
58 }
59
60
61 public function delete(): bool
62 {
63 return false;
64 }
65
66 public function getExportFilename(
67 string $a_mode = self::FILE_TYPE_EXCEL
68 ): string {
69 $filename = '';
70 $inst_id = IL_INST_ID;
71
72 $date = time();
73
74 switch ($a_mode) {
76 $filename = $date . '__' . $inst_id . '__xls_usrf';
77 break;
79 $filename = $date . '__' . $inst_id . '__csv_usrf.csv';
80 break;
82 $filename = $date . '__' . $inst_id . '__xml_usrf.xml';
83 break;
84 }
85 return $filename;
86 }
87
88 public function getExportDirectory(): string
89 {
90 $export_dir = ilFileUtils::getDataDir() . '/usrf_data/export';
91
92 return $export_dir;
93 }
94
99 public function getExportFiles(): array
100 {
101 $dir = $this->getExportDirectory();
102
103 // quit if export dir not available
104 if (!is_dir($dir)
105 || !is_writable($dir)) {
106 return [];
107 }
108
109 // open directory
110 $dir = dir($dir);
111
112 // initialize array
113 $file = [];
114
115 // get files and save the in the array
116 while ($entry = $dir->read()) {
117 if ($entry !== '.'
118 && $entry !== '..'
119 && preg_match('/^[0-9]{10}_{2}[0-9]+_{2}([a-z0-9]{3})_usrf\.[a-z]{1,4}$/', $entry, $matches)) {
120 $filearray['filename'] = $entry;
121 $filearray['filesize'] = filesize($this->getExportDirectory() . '/' . $entry);
122 $file[] = $filearray;
123 }
124 }
125
126 // close import directory
127 $dir->close();
128
129 // sort files
130 sort($file);
131
132 return $file;
133 }
134
135 protected function escapeXML(string $value): string
136 {
137 return str_replace(['&', '<', '>'], ['&amp;', '&lt;', '&gt;'], $value);
138 }
139
140 protected function createXMLExport(
141 array $fields_to_export,
142 array $data,
143 string $filename
144 ): void {
145 $xml_writer = new ilUserXMLWriter();
146 $xml_writer->setObjects($data);
147 $xml_writer->setFieldsToExport(
148 array_merge(array_keys($fields_to_export), ['time_limit_owner'])
149 );
150 $xml_writer->setAttachRoles(true);
151
152 if ($xml_writer->start()) {
153 fwrite(fopen($filename, 'wb'), $xml_writer->getXML());
154 }
155 }
156
157 protected function createCSVExport(
158 array $fields_to_export,
159 array $data,
160 string $filename
161 ): void {
162 $headerrow = [];
163 $udf_ex_fields = $this->getUserDefinedExportFields();
164 foreach ($fields_to_export as $value) { // standard fields
165 $headerrow[] = $this->lng->txt($value);
166 }
167 foreach ($udf_ex_fields as $f) { // custom fields
168 $headerrow[] = $f['name'];
169 }
170
171 $file = fopen($filename, 'wb');
172 fwrite($file, $this->processCSVRow($headerrow) . "\n");
173 foreach ($data as $row) {
174 $csvrow = [];
175 foreach ($settings as $header) { // standard fields
176 // multi-text
177 if (isset($row[$header]) && is_array($row[$header])) {
178 $row[$header] = implode(', ', $row[$header]);
179 }
180
181 $csvrow[] = $row[$header] ?? '';
182 }
183
184 // custom fields
185 reset($udf_ex_fields);
186 if (count($udf_ex_fields) > 0) {
187 $udf = $this->profile->getDataFor($row['usr_id']);
188 foreach ($udf_ex_fields as $f) { // custom fields
189 $csvrow[] = $udf->get('f_' . $f['id']);
190 }
191 }
192
193 fwrite($file, $this->processCSVRow($csvrow) . "\n");
194 }
195 fclose($file);
196 }
197
198 protected function createExcelExport(
199 array $fields_to_export,
200 array $data,
201 string $filename
202 ): void {
203 $worksheet = new ilExcel();
204 $worksheet->addSheet($this->lng->txt('users'));
205
206 $row = 1;
207 $col = 0;
208
209 // title row
210 foreach ($fields_to_export as $label) { // standard fields
211 $worksheet->setCell($row, $col, $label);
212 $col++;
213 }
214 $worksheet->setBold('A1:' . $worksheet->getColumnCoord($col - 1) . '1');
215
216 $this->lng->loadLanguageModule('meta');
217 foreach ($data as $rowdata) {
218 $row++;
219 $col = 0;
220
221 // standard fields
222 foreach (array_keys($fields_to_export) as $fieldname) {
223 $value = $rowdata[$fieldname] ?? '';
224 switch ($fieldname) {
225 case 'language':
226 $worksheet->setCell($row, $col, $this->lng->txt('meta_l_' . $value));
227 break;
228 case 'time_limit_from':
229 case 'time_limit_until':
230 $value = $value
231 ? new ilDateTime($value, IL_CAL_UNIX)
232 : null;
233 $worksheet->setCell($row, $col, $value);
234 break;
235 case 'last_login':
236 case 'last_update':
237 case 'create_date':
238 case 'approve_date':
239 case 'agree_date':
240 $value = $value
241 ? new ilDateTime($value, IL_CAL_DATETIME)
242 : null;
243 $worksheet->setCell($row, $col, $value);
244 break;
245
246 default:
247 $worksheet->setCell(
248 $row,
249 $col,
250 is_array($value) && $value !== []
251 ? implode(', ', $value)
252 : $value
253 );
254 }
255 $col++;
256 }
257 }
258
259 $worksheet->writeToFile($filename);
260 }
261
265 public function buildExportFile(
266 string $a_mode = self::FILE_TYPE_EXCEL,
267 ?array $user_data_filter = null,
268 bool $use_temp_dir = false
269 ): string {
270 if ($use_temp_dir) {
271 $export_dir = ilFileUtils::ilTempnam();
272 $fullname = $export_dir;
273 } else {
274 $export_dir = $this->getExportDirectory();
275 // create export directory if needed
276 $this->createExportDirectory();
277 $fullname = $export_dir . '/' . $this->getExportFilename($a_mode);
278 }
279
280 $fields_to_export = $this->getExportFieldArray(
281 $this->lng,
282 $this->profile,
283 $this->settings
284 );
285 $data = $this->retrieveExportDataArray(
286 $this->buildWhereForUserDataFilterArray($user_data_filter ?? [])
287 );
288
289 switch ($a_mode) {
290 case self::FILE_TYPE_EXCEL:
291 $this->createExcelExport($fields_to_export, $data, $fullname);
292 break;
293 case self::FILE_TYPE_CSV:
294 $this->createCSVExport($fields_to_export, $data, $fullname);
295 break;
296 case self::FILE_TYPE_XML:
297 $this->createXMLExport($fields_to_export, $data, $fullname);
298 break;
299 }
300 return $fullname;
301 }
302
303 private function processCSVRow(array $row): array
304 {
305 $resultarray = [];
306 foreach ($row as $rowindex => $entry) {
307 $resultarray[$rowindex] = iconv(
308 'UTF-8',
309 'ISO-8859-1',
310 '"' . str_replace(chr(13) . chr(10), chr(10), $entry) . '"'
311 );
312 }
313 return implode(';', $resultarray);
314 }
315
316 private function retrieveExportDataArray(string $usr_ids_where): array
317 {
318 $query = "SELECT * FROM usr_pref WHERE keyword = {$this->db->quote('language', 'text')}";
319 if ($usr_ids_where !== '') {
320 $query .= "AND {$usr_ids_where}";
321 }
322 $res = $this->db->query($query);
323 $languages = [];
324 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
325 $languages[$row['usr_id']] = $row['value'];
326 }
327
328 // multi-text
329 $multi = $this->retrieveMultiRowDataArray($usr_ids_where);
330
331 $query = 'SELECT usr_data.* FROM usr_data ';
332 if ($usr_ids_where !== '') {
333 $query .= "WHERE {$usr_ids_where} ";
334 }
335 $set = $this->db->query("{$query} ORDER BY usr_data.lastname, usr_data.firstname");
336
337 $data = [];
338 while ($row = $this->db->fetchAssoc($set)) {
339 $row['language'] = $languages[$row['usr_id']] ?? $this->lng->getDefaultLanguage();
340 $data[] = array_merge($row, $multi[$row['usr_id']] ?? []);
341 }
342
343 return $data;
344 }
345
346 private function retrieveMultiRowDataArray(string $usr_ids_where): array
347 {
348 $query = 'SELECT * FROM usr_profile_data';
349 if ($usr_ids_where !== '') {
350 $query .= " WHERE {$usr_ids_where}";
351 }
352 $set = $this->db->query($query);
353 $multi = [];
354 while ($row = $this->db->fetchAssoc($set)) {
355 $multi[$row['usr_id']][$row['field_id']][] = $row['value'];
356 }
357 return $multi;
358 }
359
360 private function buildWhereForUserDataFilterArray(array $user_data_filter): string
361 {
362 if ($user_data_filter === []) {
363 return '';
364 }
365
366 return $this->db->in('usr_id', $user_data_filter, false, ilDBConstants::T_INTEGER);
367 }
368
369
373 private function createExportDirectory(): void
374 {
375 if (!is_dir($this->getExportDirectory())) {
376 $usrf_data_dir = ilFileUtils::getDataDir() . '/usrf_data';
377 ilFileUtils::makeDir($usrf_data_dir);
378 if (!is_writable($usrf_data_dir)) {
379 $this->ilias->raiseError('Userfolder data directory (' . $usrf_data_dir
380 . ') not writeable.', $this->ilias->error_obj->MESSAGE);
381 }
382
383 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
384 $export_dir = $usrf_data_dir . '/export';
385 ilFileUtils::makeDir($export_dir);
386 if (!is_dir($export_dir)) {
387 $this->ilias->raiseError('Creation of Userfolder Export Directory failed.', $this->ilias->error_obj->MESSAGE);
388 }
389 }
390 }
391
392
397 public static function getProfileFields(): array // Missing array type.
398 {
399 return array_key(LocalDIC::dic()[Profile::class]->getFields(
400 [],
401 [Alias::class, Roles::class]
402 ));
403 }
404
410 public static function _updateUserFolderAssignment(
411 int $a_old_id,
412 int $a_new_id
413 ): void {
414 global $DIC;
415
416 $ilDB = $DIC['ilDB'];
417
418 $query = 'UPDATE usr_data SET time_limit_owner = ' . $ilDB->quote($a_new_id, ilDBConstants::T_INTEGER) . ' ' .
419 'WHERE time_limit_owner = ' . $ilDB->quote($a_old_id, ilDBConstants::T_INTEGER) . ' ';
420 $ilDB->manipulate($query);
421 }
422}
$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)
createExcelExport(array $fields_to_export, array $data, string $filename)
buildWhereForUserDataFilterArray(array $user_data_filter)
createCSVExport(array $fields_to_export, array $data, string $filename)
createXMLExport(array $fields_to_export, 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.
SettingsImplementation $settings
retrieveMultiRowDataArray(string $usr_ids_where)
buildExportFile(string $a_mode=self::FILE_TYPE_EXCEL, ?array $user_data_filter=null, bool $use_temp_dir=false)
build xml export file
const string PERM_READ_ALL_AND_WRITE
const string PERM_READ_ALL
retrieveExportDataArray(string $usr_ids_where)
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.
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26