Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
user.php
1<?php
3
7
8class User extends \CBPRuntimeService
9{
10 protected const DEPARTMENT_MODULE_ID = 'intranet';
11 protected const DEPARTMENT_OPTION_NAME = 'iblock_structure';
12
13 public function getUserDepartments(int $userId): array
14 {
15 $departments = [];
16 $result = \CUser::getList(
17 'id', 'asc',
18 ['ID_EQUAL_EXACT' => $userId],
19 ['FIELDS' => ['ID'], 'SELECT' => ['UF_DEPARTMENT']]
20 );
21
22 if ($user = $result->fetch())
23 {
24 if (isset($user['UF_DEPARTMENT']))
25 {
26 $user['UF_DEPARTMENT'] = (array) $user['UF_DEPARTMENT'];
27 foreach ($user['UF_DEPARTMENT'] as $dpt)
28 {
29 $departments[] = (int) $dpt;
30 }
31 }
32 }
33
34 return $departments;
35 }
36
37 public function getUserInfo(int $userId): ?array
38 {
39 if ($userId <= 0)
40 {
41 return null;
42 }
43
44 $userFields = $this->getUserUserFields();
45 $user = $this->loadUser($userId, $userFields);
46
47 if (!$user)
48 {
49 return null;
50 }
51
52 $this->convertValues($user, $userFields);
53
54 $schedule = $this->getUserSchedule($userId);
55 $user['IS_ABSENT'] = $schedule->isAbsent();
56 $user['TIMEMAN_STATUS'] = $schedule->getWorkDayStatus();
57 $user['UF_HEAD'] = $this->convertUserValue($this->getUserHeads($userId));
58
59 return $user;
60 }
61
62 public function getUserExtendedFields(): array
63 {
64 $fields = $this->getUserUserFields();
65
66 if ($this->canUseIntranet())
67 {
68 $fields['UF_DEPARTMENT'] = [
69 'Name' => Loc::getMessage('BP_SERVICE_USER_DEPARTMENT'),
70 'Type' => 'int',
71 'Multiple' => true,
72 ];
73
74 $fields['UF_DEPARTMENT_PRINTABLE'] = [
75 'Name' => Loc::getMessage('BP_SERVICE_USER_DEPARTMENT_PRINTABLE'),
76 'Type' => 'string',
77 'Multiple' => true,
78 ];
79
80 $fields['IS_ABSENT'] = [
81 'Name' => Loc::getMessage('BP_SERVICE_USER_IS_ABSENT'),
82 'Type' => 'bool',
83 ];
84
85 if ($this->canUseIblockApi())
86 {
87 $fields['UF_HEAD'] = [
88 'Name' => Loc::getMessage('BP_SERVICE_USER_HEAD'),
89 'Type' => 'user',
90 'Multiple' => true,
91 ];
92 }
93 }
94
95 if ($this->canUseTimeman())
96 {
97 $fields['TIMEMAN_STATUS'] = [
98 'Name' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS'),
99 'Type' => 'select',
100 'Options' => [
101 'EXPIRED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_EXPIRED'),
102 'OPENED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_OPENED'),
103 'PAUSED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_PAUSED'),
104 'CLOSED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_CLOSED'),
105 ],
106 ];
107 }
108
109 return $fields;
110 }
111
112 public function getUserBaseFields(): array
113 {
114 return [
115 'ACTIVE' => [
116 'Name' => Loc::getMessage('BP_SERVICE_USER_ACTIVE'),
117 'Type' => 'bool',
118 ],
119 'EMAIL' => [
120 'Name' => Loc::getMessage('BP_SERVICE_USER_EMAIL'),
121 'Type' => 'string',
122 ],
123 'WORK_PHONE' => [
124 'Name' => Loc::getMessage('BP_SERVICE_USER_WORK_PHONE'),
125 'Type' => 'string',
126 ],
127 'PERSONAL_MOBILE' => [
128 'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_MOBILE'),
129 'Type' => 'string',
130 ],
131 'UF_PHONE_INNER' => [
132 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_PHONE_INNER'),
133 'Type' => 'string',
134 ],
135 'LOGIN' => [
136 'Name' => Loc::getMessage('BP_SERVICE_USER_LOGIN'),
137 'Type' => 'string',
138 ],
139 'NAME' => [
140 'Name' => Loc::getMessage('BP_SERVICE_USER_NAME'),
141 'Type' => 'string',
142 ],
143 'LAST_NAME' => [
144 'Name' => Loc::getMessage('BP_SERVICE_USER_LAST_NAME'),
145 'Type' => 'string',
146 ],
147 'SECOND_NAME' => [
148 'Name' => Loc::getMessage('BP_SERVICE_USER_SECOND_NAME'),
149 'Type' => 'string',
150 ],
151 'WORK_POSITION' => [
152 'Name' => Loc::getMessage('BP_SERVICE_USER_WORK_POSITION'),
153 'Type' => 'string',
154 ],
155 'PERSONAL_BIRTHDAY' => [
156 'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_BIRTHDAY'),
157 'Type' => 'date',
158 ],
159 'PERSONAL_WWW' => [
160 'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_WWW'),
161 'Type' => 'string',
162 ],
163 'PERSONAL_CITY' => [
164 'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_CITY'),
165 'Type' => 'string',
166 ],
167 'UF_DEPARTMENT' => [
168 'Name' => Loc::getMessage('BP_SERVICE_USER_DEPARTMENT'),
169 'Type' => 'int',
170 'Multiple' => true,
171 ],
172 'UF_SKYPE' => [
173 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_SKYPE'),
174 'Type' => 'string',
175 ],
176 'UF_TWITTER' => [
177 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_TWITTER'),
178 'Type' => 'string',
179 ],
180 'UF_FACEBOOK' => [
181 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_FACEBOOK'),
182 'Type' => 'string',
183 ],
184 'UF_LINKEDIN' => [
185 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_LINKEDIN'),
186 'Type' => 'string',
187 ],
188 'UF_XING' => [
189 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_XING'),
190 'Type' => 'string',
191 ],
192 'UF_WEB_SITES' => [
193 'Name' => Loc::getMessage('BP_SERVICE_USER_UF_WEB_SITES'),
194 'Type' => 'string',
195 ],
196 ];
197 }
198
199 public function getUserDepartmentChains(int $userId): array
200 {
201 $chains = [];
202
203 foreach ($this->getUserDepartments($userId) as $departmentId)
204 {
205 $chains[] = $this->getDepartmentChain($departmentId);
206 }
207
208 return $chains;
209 }
210
211 public function getDepartmentChain(int $departmentId): array
212 {
213 $chain = [];
214
215 if (!$this->canUseIblockApi())
216 {
217 return $chain;
218 }
219
220 $departmentIblockId = $this->getDepartmentIblockId();
221 $chain = \CIBlockSection::getNavChain($departmentIblockId, $departmentId, ['ID'], true);
222
223 $chain = array_map(
224 static fn($value) => (int)$value['ID'],
225 $chain
226 );
227
228 return array_reverse($chain);
229 }
230
231 public function getUserHeads(int $userId): array
232 {
233 $heads = [];
234 $userDepartments = $this->getUserDepartmentChains($userId);
235
236 foreach ($userDepartments as $chain)
237 {
238 foreach ($chain as $deptId)
239 {
240 $departmentHead = $this->getDepartmentHead($deptId);
241
242 if (!$departmentHead || $departmentHead === $userId)
243 {
244 continue;
245 }
246
247 $heads[] = $departmentHead;
248 break;
249 }
250 }
251
252 return array_unique($heads);
253 }
254
255 public function getDepartmentHead(int $departmentId): ?int
256 {
257 if (!$this->canUseIblockApi())
258 {
259 return null;
260 }
261
262 $departmentIblockId = $this->getDepartmentIblockId();
263 $sectionResult = \CIBlockSection::GetList(
264 [],
265 ['IBLOCK_ID' => $departmentIblockId, 'ID' => $departmentId],
266 false,
267 ['ID', 'UF_HEAD']
268 );
269 $section = $sectionResult->fetch();
270
271 return $section ? (int) $section['UF_HEAD'] : null;
272 }
273
274 public function getUserSchedule(int $userId): Sub\UserSchedule
275 {
276 return new Sub\UserSchedule($userId);
277 }
278
279 protected function getDepartmentIblockId(): int
280 {
281 return (int) Main\Config\Option::get(
282 static::DEPARTMENT_MODULE_ID,
283 static::DEPARTMENT_OPTION_NAME
284 );
285 }
286
287 private function canUseIblockApi()
288 {
289 return Main\Loader::includeModule('iblock');
290 }
291
292 private function canUseIntranet()
293 {
294 return Main\Loader::includeModule('intranet');
295 }
296
297 private function canUseTimeman()
298 {
299 return \CBPHelper::isWorkTimeAvailable();
300 }
301
302 public function getUserUserFields(): array
303 {
304 static $fields;
305
306 if (isset($fields))
307 {
308 return $fields;
309 }
310
311 $fields = [];
312
313 $userFieldIds = Main\UserFieldTable::getList([
314 'select' => ['ID'],
315 'filter' => [
316 '=ENTITY_ID' => 'USER',
317 '%=FIELD_NAME' => 'UF_USR_%',
318 ],
319 ])->fetchAll();
320
321 foreach ($userFieldIds as $fieldId)
322 {
323 $field = Main\UserFieldTable::getFieldData($fieldId['ID']);
324 $fieldName = $field['FIELD_NAME'];
325 $fieldType = FieldType::convertUfType($field['USER_TYPE_ID']) ?? "UF:{$field['USER_TYPE_ID']}";
326
327 $name = in_array(\LANGUAGE_ID, $field['LANGUAGE_ID'])
328 ? $field['LIST_COLUMN_LABEL'][\LANGUAGE_ID]
329 : $field['FIELD_NAME']
330 ;
331
332 $fields[$fieldName] = [
333 'Name' => $name,
334 'Type' => $fieldType,
335 'Multiple' => $field['MULTIPLE'] === 'Y',
336 ];
337
338 if ($fields[$fieldName]['Type'] === 'select')
339 {
340 $fields[$fieldName]['Options'] = array_combine(
341 array_column($field['ENUM'], 'XML_ID'),
342 array_column($field['ENUM'], 'VALUE'),
343 );
344 $fields[$fieldName]['Settings'] = ['ENUM' => $field['ENUM']];
345 }
346 }
347
348 return $fields;
349 }
350
351 private function convertValues(array &$values, array $userFields): void
352 {
353 foreach ($userFields as $id => $field)
354 {
355 if ($field['Type'] === 'bool')
356 {
357 $values[$id] = \CBPHelper::getBool($values[$id]) ? 'Y' : 'N';
358 }
359 elseif ($field['Type'] === 'select')
360 {
361 $values[$id] = $this->convertSelectValue($values[$id], $field);
362 }
363 }
364
365 if (!empty($values['UF_DEPARTMENT']))
366 {
367 $values['UF_DEPARTMENT_PRINTABLE'] = $this->loadDepartmentNames($values['UF_DEPARTMENT']);
368 }
369 }
370
371 private function convertSelectValue($value, $field)
372 {
373 $enumIds = array_combine(
374 array_column($field['Settings']['ENUM'], 'XML_ID'),
375 array_column($field['Settings']['ENUM'], 'ID'),
376 );
377
378 if (is_array($value))
379 {
380 $xmlIds = [];
381 foreach ($value as $val)
382 {
383 $xmlIds[] = array_search($val, $enumIds);
384 }
385
386 return array_filter($xmlIds, fn($id) => $id !== false);
387 }
388
389 $xmlId = array_search($value, $enumIds);
390
391 return $xmlId !== false ? $xmlId : '';
392 }
393
394 private function convertUserValue($value): array
395 {
396 $users = [];
397
398 $value = is_array($value) ? $value : [$value];
399 foreach ($value as $userId)
400 {
401 if (is_int($userId))
402 {
403 $users[] = 'user_' . $userId;
404 }
405 }
406
407 return $users;
408 }
409
410 private function loadUser(int $userId, array $fields): ?array
411 {
412 $dbUsers = \CUser::GetList(
413 'id',
414 'asc',
415 ['ID_EQUAL_EXACT' => $userId],
416 [
417 'FIELDS' => [
418 'ID',
419 'EMAIL',
420 'WORK_PHONE',
421 'PERSONAL_MOBILE',
422 'PERSONAL_BIRTHDAY',
423 'LOGIN',
424 'ACTIVE',
425 'NAME',
426 'LAST_NAME',
427 'SECOND_NAME',
428 'WORK_POSITION',
429 'PERSONAL_WWW',
430 'PERSONAL_CITY',
431 ],
432 'SELECT' => [
433 'UF_DEPARTMENT',
434 'UF_SKYPE',
435 'UF_TWITTER',
436 'UF_FACEBOOK',
437 'UF_LINKEDIN',
438 'UF_XING',
439 'UF_WEB_SITES',
440 'UF_PHONE_INNER',
441 ...array_keys($fields)
442 ]
443 ]
444 );
445
446 $user = $dbUsers->fetch();
447
448 return is_array($user) ? $user : null;
449 }
450
451 private function loadDepartmentNames(array $ids): array
452 {
453 $names = [];
454
455 if (!Main\Loader::includeModule('intranet') || !Main\Loader::includeModule('iblock'))
456 {
457 return $names;
458 }
459
460 $iblockId = Main\Config\Option::get('intranet', 'iblock_structure');
461
462 $iterator = \CIBlockSection::GetList(
463 ['ID' => 'ASC'],
464 [
465 '=IBLOCK_ID' => $iblockId,
466 'ID' => $ids
467 ],
468 false,
469 ['ID', 'NAME']
470 );
471
472 while ($row = $iterator->fetch())
473 {
474 $names[$row['ID']] = $row['NAME'];
475 }
476
477 return array_values(array_filter(
478 array_map(
479 fn($id) => $names[$id] ?? null,
480 $ids
481 )
482 ));
483 }
484}
static convertUfType(string $type)
getUserDepartments(int $userId)
Definition user.php:13
getUserInfo(int $userId)
Definition user.php:37
getUserSchedule(int $userId)
Definition user.php:274
getUserDepartmentChains(int $userId)
Definition user.php:199
getUserHeads(int $userId)
Definition user.php:231
getDepartmentHead(int $departmentId)
Definition user.php:255
getDepartmentChain(int $departmentId)
Definition user.php:211
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29