Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
User.php
1<?php
2
4
10use Bitrix\Im\V2\Common\ContextCustomer;
22
23class User implements RestEntity
24{
25 use ContextCustomer;
26
27 public const PHONE_MOBILE = 'PERSONAL_MOBILE';
28 public const PHONE_WORK = 'WORK_PHONE';
29 public const PHONE_INNER = 'INNER_PHONE';
31 'USER_ID' => 'ID',
32 'IDLE' => 'STATUS.IDLE',
33 'DESKTOP_LAST_DATE' => 'STATUS.DESKTOP_LAST_DATE',
34 'MOBILE_LAST_DATE' => 'STATUS.MOBILE_LAST_DATE',
35 'LAST_ACTIVITY_DATE'
36 ];
38 'USER_ID' => 'ID',
39 'LAST_ACTIVITY_DATE'
40 ];
41
45 protected static string $moduleManager = ModuleManager::class;
49 protected static string $loader = Loader::class;
50
54 protected static array $userStaticCache = [];
55
56 protected array $accessCache = [];
57 protected array $userData = [];
58
59 protected bool $isOnlineDataFilled = false;
60 protected bool $isOnlineDataWithStatusFilled = false;
61 protected ?bool $isAdmin = null;
62
63 protected ?DateTime $idle = null;
64 protected ?DateTime $lastActivityDate = null;
65 protected ?DateTime $mobileLastDate = null;
66 protected ?DateTime $desktopLastDate = null;
67
68 public static function getInstance(?int $id): self
69 {
70 if (!isset($id))
71 {
72 return new NullUser();
73 }
74
75 if (isset(self::$userStaticCache[$id]))
76 {
77 return self::$userStaticCache[$id];
78 }
79
80 self::$userStaticCache[$id] = UserFactory::getInstance()->getUserById($id);
81
82 return self::$userStaticCache[$id];
83 }
84
85 public static function getCurrent(): self
86 {
87 return Locator::getContext()->getUser();
88 }
89
90 public static function initByArray(array $userData): self
91 {
92 if (!isset($userData['ID']))
93 {
94 return new NullUser();
95 }
96
97 $user = new static();
98 $user->userData = $userData;
99
100 return $user;
101 }
102
109 public function getChatWith(int $userId, bool $createIfNotExist = true): ?PrivateChat
110 {
111 $chatId = false;
112 if ($userId === $this->getId())
113 {
114 $result = FavoriteChat::find(['TO_USER_ID' => $userId])->getResult();
115 if ($result && isset($result['ID']))
116 {
117 $chatId = (int)$result['ID'];
118 }
119 }
120 else
121 {
122 $result = RelationTable::query()
123 ->setSelect(['CHAT_ID'])
124 ->registerRuntimeField(
125 'SELF',
126 new Reference(
127 'SELF',
128 RelationTable::class,
129 Join::on('this.CHAT_ID', 'ref.CHAT_ID'),
130 ['join_type' => Join::TYPE_INNER]
131 )
132 )->where('USER_ID', $this->getId())
133 ->where('SELF.USER_ID', $userId)
134 ->where('MESSAGE_TYPE', \IM_MESSAGE_PRIVATE)
135 ->setLimit(1)
136 ->fetch()
137 ;
138 if ($result && isset($result['CHAT_ID']))
139 {
140 $chatId = (int)$result['CHAT_ID'];
141 }
142 }
143
144 if ($chatId !== false)
145 {
146 $chat = PrivateChat::getInstance($chatId);
147
148 if ($chat instanceof PrivateChat)
149 {
150 return $chat;
151 }
152
153 return null;
154 }
155
156 if (!$createIfNotExist)
157 {
158 return null;
159 }
160
161 try
162 {
163 $createResult = (new PrivateChat())->add(['FROM_USER_ID' => $this->getId(), 'TO_USER_ID' => $userId]);
164 }
165 catch (SystemException $exception)
166 {
167 return null;
168 }
169
170 if (!$createResult->isSuccess())
171 {
172 return null;
173 }
174
175 return $createResult->getResult()['CHAT'];
176 }
177
178 final public function hasAccess(?int $idOtherUser = null): bool
179 {
180 $idOtherUser = $idOtherUser ?? Locator::getContext()->getUserId();
181
182 $otherUser = User::getInstance($idOtherUser);
183
184 if (!$otherUser->isExist())
185 {
186 return false;
187 }
188
189 if ($this->getId() === $idOtherUser)
190 {
191 return true;
192 }
193
194 if (isset($this->accessCache[$idOtherUser]))
195 {
196 return $this->accessCache[$idOtherUser];
197 }
198
199 $this->accessCache[$idOtherUser] = $this->checkAccessWithoutCaching($otherUser);
200
201 return $this->accessCache[$idOtherUser];
202 }
203
204 protected function checkAccessWithoutCaching(self $otherUser): bool
205 {
206 if (!static::$moduleManager::isModuleInstalled('intranet'))
207 {
208 return $this->hasAccessBySocialNetwork($otherUser->getId());
209 }
210
211 if ($otherUser->isExtranet())
212 {
213 $inGroup = \Bitrix\Im\Integration\Socialnetwork\Extranet::isUserInGroup($this->getId(), $otherUser->getId());
214 if ($inGroup)
215 {
216 return true;
217 }
218
219 return false;
220 }
221
222 if ($this->isNetwork())
223 {
224 return true;
225 }
226
227 return true;
228 }
229
230 final protected function hasAccessBySocialNetwork(int $idOtherUser): bool
231 {
232 $isContactPrivacy = (
233 \CIMSettings::GetPrivacy(\CIMSettings::PRIVACY_MESSAGE) === \CIMSettings::PRIVACY_RESULT_CONTACT
234 || \CIMSettings::GetPrivacy(\CIMSettings::PRIVACY_MESSAGE, $this->getId()) === \CIMSettings::PRIVACY_RESULT_CONTACT
235 );
236
237 return !(
238 $isContactPrivacy
239 && static::$loader::includeModule('socialnetwork')
240 && \CSocNetUser::IsFriendsAllowed()
241 && !\CSocNetUserRelations::IsFriends($this->getId(), $idOtherUser)
242 );
243 }
244
245 protected function fillOnlineData(bool $withStatus = false): void
246 {
247 if ((!$withStatus && $this->isOnlineDataFilled)
248 || $this->isOnlineDataWithStatusFilled)
249 {
250 return;
251 }
252
254 $query = UserTable::query()
255 ->setSelect($select)
256 ->where('ID', $this->getId())
257 ;
258 if ($withStatus)
259 {
260 $query->registerRuntimeField(
261 new Reference(
262 'STATUS',
263 StatusTable::class,
264 Join::on('this.ID', 'ref.USER_ID'),
265 ['join_type' => Join::TYPE_LEFT]
266 )
267 );
268 }
269
270 $statusData = $query->fetch() ?: [];
271 $this->setOnlineData($statusData, $withStatus);
272 }
273
274 public function getId(): ?int
275 {
276 return isset($this->userData['ID']) ? (int)$this->userData['ID'] : null;
277 }
278
279 public static function getRestEntityName(): string
280 {
281 return 'user';
282 }
283
284 public function toRestFormat(array $option = []): array
285 {
286 if (isset($option['USER_SHORT_FORMAT']) && $option['USER_SHORT_FORMAT'] === true)
287 {
288 return [
289 'id' => $this->getId(),
290 'name' => $this->getName(),
291 'avatar' => $this->getAvatar(),
292 ];
293 }
294
295 $idle = false;
296 $lastActivityDate = false;
297 $mobileLastDate = false;
298 $desktopLastDate = false;
299
300 if (!isset($option['WITHOUT_ONLINE']) || $option['WITHOUT_ONLINE'] === false)
301 {
302 $idle = $this->getIdle() ? $this->getIdle()->format('c') : false;
303 $lastActivityDate = $this->getLastActivityDate() ? $this->getLastActivityDate()->format('c') : false;
304 $mobileLastDate = $this->getMobileLastDate() ? $this->getMobileLastDate()->format('c') : false;
305 $desktopLastDate = $this->getDesktopLastDate() ? $this->getDesktopLastDate()->format('c') : false;
306 }
307
308 return [
309 'id' => $this->getId(),
310 'active' => $this->isActive(),
311 'name' => $this->getName(),
312 'firstName' => $this->getFirstName(),
313 'lastName' => $this->getLastName(),
314 'workPosition' => $this->getWorkPosition(),
315 'color' => $this->getColor(),
316 'avatar' => $this->getAvatar(),
317 'avatarHr' => $this->getAvatarHr(),
318 'gender' => $this->getGender(),
319 'birthday' => (string)$this->getBirthday(),
320 'extranet' => $this->isExtranet(),
321 'network' => $this->isNetwork(),
322 'bot' => $this->isBot(),
323 'connector' => $this->isConnector(),
324 'externalAuthId' => $this->getExternalAuthId(),
325 'status' => $this->getStatus(),
326 'idle' => $idle,
327 'lastActivityDate' => $lastActivityDate,
328 'mobileLastDate' => $mobileLastDate,
329 'desktopLastDate' => $desktopLastDate,
330 'absent' => $this->getAbsent() !== null ? $this->getAbsent()->format('c') : false,
331 'departments' => $this->getDepartmentIds(),
332 'phones' => empty($this->getPhones()) ? false : $this->getPhones(),
333 'botData' => null,
334 ];
335 }
336
337 public function getArray(array $option = []): array
338 {
339 $userData = $this->toRestFormat($option);
340
341 $converter = new Converter(Converter::TO_SNAKE | Converter::TO_UPPER | Converter::KEYS);
342 $userData = $converter->process($userData);
343
344 if ($userData['PHONES'])
345 {
346 $converter = new Converter(Converter::TO_LOWER | Converter::KEYS);
347 $userData['PHONES'] = $converter->process($userData['PHONES']);
348 }
349 if (isset($userData['BOT_DATA']))
350 {
351 $converter = new Converter(Converter::TO_SNAKE | Converter::TO_LOWER | Converter::KEYS);
352 $userData['BOT_DATA'] = $converter->process($userData['BOT_DATA']);
353 }
354
355 return $userData;
356 }
357
358 //region Getters & setters
359
360 public function isExist(): bool
361 {
362 return $this->getId() !== null;
363 }
364
365 public function setOnlineData(array $onlineData, bool $withStatus): void
366 {
367 $this->idle = $onlineData['IDLE'] ?? null;
368 $this->lastActivityDate = $onlineData['LAST_ACTIVITY_DATE'] ?? null;
369 $this->mobileLastDate = $onlineData['MOBILE_LAST_DATE'] ?? null;
370 $this->desktopLastDate = $onlineData['DESKTOP_LAST_DATE'] ?? null;
371 if ($withStatus)
372 {
373 $this->isOnlineDataWithStatusFilled = true;
374 }
375 else
376 {
377 $this->isOnlineDataFilled = true;
378 }
379 }
380
381 public function getName(): ?string
382 {
383 return $this->userData['NAME'] ?? null;
384 }
385
386 public function getFirstName(): ?string
387 {
388 return $this->userData['FIRST_NAME'] ?? null;
389 }
390
391 public function getLastName(): ?string
392 {
393 return $this->userData['LAST_NAME'] ?? null;
394 }
395
396 public function getAvatar(bool $forRest = true): string
397 {
398 $avatar = $this->userData['AVATAR'] ?? '';
399
400 return $forRest ? $this->prependPublicDomain($avatar) : $avatar;
401 }
402
403 public function getAvatarHr(bool $forRest = true): string
404 {
405 $avatarHr = $this->userData['AVATAR_HR'] ?? '';
406
407 return $forRest ? $this->prependPublicDomain($avatarHr) : $avatarHr;
408 }
409
410 public function getBirthday(): string
411 {
412 return $this->userData['BIRTHDAY'] ?? '';
413 }
414
415 public function getAvatarId(): int
416 {
417 return $this->userData['AVATAR_ID'] ?? 0;
418 }
419
420 public function getWorkPosition(): ?string
421 {
422 return $this->userData['WORK_POSITION'] ?? null;
423 }
424
425 public function getGender(): string
426 {
427 return $this->userData['PERSONAL_GENDER'] === 'F' ? 'F' : 'M';
428 }
429
430 public function getExternalAuthId(): string
431 {
432 return $this->userData['EXTERNAL_AUTH_ID'] ?? 'default';
433 }
434
435 public function getWebsite(): string
436 {
437 return $this->userData['PERSONAL_WWW'] ?? '';
438 }
439
440 public function getEmail(): string
441 {
442 return $this->userData['EMAIL'] ?? '';
443 }
444
445 public function getPhones(): array
446 {
447 $result = [];
448
449 foreach ([self::PHONE_MOBILE, self::PHONE_WORK, self::PHONE_INNER] as $phoneType)
450 {
451 if (isset($this->userData[$phoneType]) && $this->userData[$phoneType])
452 {
453 $result[$phoneType] = $this->userData[$phoneType];
454 }
455 }
456
457 return $result;
458 }
459
460 public function getColor(): string
461 {
462 return $this->userData['COLOR'] ?? '';
463 }
464
465 public function getTzOffset(): string
466 {
467 return $this->userData['TIME_ZONE_OFFSET'] ?? '';
468 }
469
470 public function getLanguageId(): ?string
471 {
472 return $this->userData['LANGUAGE_ID'] ?? null;
473 }
474
475 public function isExtranet(): bool
476 {
477 return $this->userData['IS_EXTRANET'] ?? false;
478 }
479
480 public function isActive(): bool
481 {
482 return $this->userData['ACTIVE'] === 'Y';
483 }
484
485 public function getAbsent(): ?DateTime
486 {
487 return $this->userData['ABSENT'] ?? null;
488 }
489
490 public function isNetwork(): bool
491 {
492 return $this->userData['IS_NETWORK'] ?? false;
493 }
494
495 public function isBot(): bool
496 {
497 return $this->userData['IS_BOT'] ?? false;
498 }
499
500 public function isConnector(): bool
501 {
502 return $this->userData['IS_CONNECTOR'] ?? false;
503 }
504
505 public function getDepartmentIds(): array
506 {
507 return
508 (isset($this->userData['UF_DEPARTMENT']) && is_array($this->userData['UF_DEPARTMENT']))
509 ? $this->userData['UF_DEPARTMENT']
510 : []
511 ;
512 }
513
514 public function getDepartments(): Departments
515 {
516 return new Departments(...$this->getDepartmentIds());
517 }
518
519 public function isOnlineDataFilled(bool $withStatus): bool
520 {
521 return $withStatus ? $this->isOnlineDataWithStatusFilled : $this->isOnlineDataWithStatusFilled || $this->isOnlineDataFilled;
522 }
523
524 public function getStatus(bool $real = false): ?string
525 {
526 if ($real)
527 {
528 return $this->userData['STATUS'] ?? 'online';
529 }
530
531 return 'online';
532 }
533
534 public function getIdle(bool $real = false): ?DateTime
535 {
536 if ($real)
537 {
538 $this->fillOnlineData(true);
539 }
540
541 return $this->idle;
542 }
543
544 public function getLastActivityDate(): ?DateTime
545 {
546 $this->fillOnlineData();
547
549 }
550
551 public function getMobileLastDate(bool $real = false): ?DateTime
552 {
553 if ($real)
554 {
555 $this->fillOnlineData(true);
556 }
557
559 }
560
561 public function getDesktopLastDate(bool $real = false): ?DateTime
562 {
563 if ($real)
564 {
565 $this->fillOnlineData(true);
566 }
567
569 }
570
571 public function isAdmin(): bool
572 {
573 if ($this->isAdmin !== null)
574 {
575 return $this->isAdmin;
576 }
577
578 global $USER;
579 if (Loader::includeModule('bitrix24'))
580 {
581 if (
582 $USER instanceof \CUser
583 && $USER->isAuthorized()
584 && $USER->isAdmin()
585 && (int)$USER->getId() === $this->getId()
586 )
587 {
588 $this->isAdmin = true;
589
590 return $this->isAdmin;
591 }
592 $this->isAdmin = \CBitrix24::isPortalAdmin($this->getId());
593
594 return $this->isAdmin;
595 }
596
597 if (
598 $USER instanceof \CUser
599 && $USER->isAuthorized()
600 && (int)$USER->getId() === $this->getId()
601 )
602 {
603 $this->isAdmin = $USER->isAdmin();
604
605 return $this->isAdmin;
606 }
607
608 $result = false;
609 $groups = UserTable::getUserGroupIds($this->getId());
610 foreach ($groups as $groupId)
611 {
612 if ((int)$groupId === 1)
613 {
614 $result = true;
615 break;
616 }
617 }
618 $this->isAdmin = $result;
619
620 return $this->isAdmin;
621 }
622
623 public function isSuperAdmin(): bool
624 {
625 global $USER;
626 if (!Loader::includeModule('socialnetwork') || (int)$USER->getId() !== $this->getId())
627 {
628 return false;
629 }
630
631 return $this->isAdmin() && \CSocNetUser::IsEnabledModuleAdmin();
632 }
633
634 //endregion
635
636 private function prependPublicDomain(string $url): string
637 {
638 if ($url !== '' && mb_strpos($url, 'http') !== 0)
639 {
640 return Common::getPublicDomain() . $url;
641 }
642
643 return $url;
644 }
645}
static getPublicDomain()
Definition common.php:8
static find(array $params=[], ?Context $context=null)
getIdle(bool $real=false)
Definition User.php:534
hasAccessBySocialNetwork(int $idOtherUser)
Definition User.php:230
toRestFormat(array $option=[])
Definition User.php:284
getAvatarHr(bool $forRest=true)
Definition User.php:403
static initByArray(array $userData)
Definition User.php:90
isOnlineDataFilled(bool $withStatus)
Definition User.php:519
const ONLINE_DATA_SELECTED_FIELDS_WITHOUT_STATUS
Definition User.php:37
checkAccessWithoutCaching(self $otherUser)
Definition User.php:204
setOnlineData(array $onlineData, bool $withStatus)
Definition User.php:365
getAvatar(bool $forRest=true)
Definition User.php:396
static getInstance(?int $id)
Definition User.php:68
getChatWith(int $userId, bool $createIfNotExist=true)
Definition User.php:109
static array $userStaticCache
Definition User.php:54
static string $loader
Definition User.php:49
getDesktopLastDate(bool $real=false)
Definition User.php:561
hasAccess(?int $idOtherUser=null)
Definition User.php:178
getStatus(bool $real=false)
Definition User.php:524
getMobileLastDate(bool $real=false)
Definition User.php:551
fillOnlineData(bool $withStatus=false)
Definition User.php:245
static string $moduleManager
Definition User.php:45
getArray(array $option=[])
Definition User.php:337