3namespace Bitrix\Im\Call;
9use Bitrix\Im\Model\AliasTable;
10use Bitrix\Im\Model\ConferenceUserRoleTable;
11use Bitrix\Im\Model\RelationTable;
12use Bitrix\Im\Settings;
13use Bitrix\Im\V2\Chat\ChatFactory;
14use Bitrix\Main\Config\Option;
15use Bitrix\Main\DB\ArrayResult;
16use Bitrix\Main\Entity;
18use Bitrix\Main\Loader;
19use Bitrix\Main\Localization\Loc;
20use Bitrix\Main\Result;
21use Bitrix\Main\Type\DateTime;
22use Bitrix\Im\Model\ConferenceTable;
114 return $this->password !==
'';
129 if (empty($this->users))
133 $this->users = array_map(
static function (
$user) {
136 'title' =>
$user[
'name'],
137 'avatar' =>
$user[
'avatar']
156 return self::BROADCAST_USER_LIMIT;
164 return (
int)Option::get(
'call',
'turn_server_max_users');
177 $presenters = \Bitrix\Im\Model\ConferenceUserRoleTable::getList(
179 'select' => [
'USER_ID'],
181 '=CONFERENCE_ID' => $this->
getId(),
182 '=ROLE' => self::ROLE_PRESENTER
187 foreach ($presenters as $presenter)
189 $result[] = (int)$presenter[
'USER_ID'];
200 foreach ($presenters as $presenter)
203 $result[] = array_change_key_case($presenterInfo, CASE_LOWER);
213 return in_array(
$userId, $presenters,
true);
218 return \Bitrix\Im\Model\ConferenceUserRoleTable::add(
220 'CONFERENCE_ID' => $this->
getId(),
221 'USER_ID' => $userId,
222 'ROLE' => self::ROLE_PRESENTER
229 return \Bitrix\Im\Model\ConferenceUserRoleTable::delete(
231 'CONFERENCE_ID' => $this->
getId(),
245 return $this->
getStatus() === static::STATE_FINISHED;
251 if (!($this->startDate instanceof
DateTime))
253 return self::STATE_FINISHED;
257 $startTimestamp = $this->startDate->getTimestamp();
260 if ($startTimestamp > $now)
262 return self::STATE_NOT_STARTED;
265 return self::STATE_FINISHED;
275 if (Loader::includeModule(
'bitrix24'))
277 $isAdmin = CBitrix24::IsPortalAdmin(
$userId);
281 $user = new \CUser();
292 if (Loader::includeModule(
'bitrix24'))
294 $isAdmin = CBitrix24::IsPortalAdmin(
$userId);
298 $user = new \CUser();
316 if (isset(
$fields[
'TITLE']) &&
$fields[
'TITLE'] !== $this->chatName)
323 $result[
'VIDEOCONF'][
'PASSWORD'] =
$fields[
'VIDEOCONF'][
'PASSWORD'];
328 $result[
'VIDEOCONF'][
'INVITATION'] =
$fields[
'VIDEOCONF'][
'INVITATION'];
331 $newBroadcastMode = isset(
$fields[
'VIDEOCONF'][
'PRESENTERS']) &&
count(
$fields[
'VIDEOCONF'][
'PRESENTERS']) > 0;
334 $result[
'VIDEOCONF'][
'IS_BROADCAST'] = $newBroadcastMode ===
true ?
'Y' :
'N';
337 if ($newBroadcastMode)
340 $result[
'NEW_PRESENTERS'] = array_diff(
$fields[
'VIDEOCONF'][
'PRESENTERS'], $currentPresenters);
341 $result[
'DELETED_PRESENTERS'] = array_diff($currentPresenters,
$fields[
'VIDEOCONF'][
'PRESENTERS']);
346 $currentUsers = array_map(
static function(
$user){
350 $result[
'NEW_USERS'] = array_diff(
$fields[
'USERS'], $currentUsers);
351 $result[
'DELETED_USERS'] = array_diff($currentUsers,
$fields[
'USERS']);
361 if (!static::isEnvironmentConfigured())
365 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_ENVIRONMENT_CONFIG'),
366 'ENVIRONMENT_CONFIG_ERROR'
371 $validationResult = static::validateFields(
$fields);
372 if (!$validationResult->isSuccess())
374 return $result->addErrors($validationResult->getErrors());
376 $updateData = $validationResult->getData()[
'FIELDS'];
382 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_ID_NOT_PROVIDED'),
383 'CONFERENCE_ID_EMPTY'
389 if (empty($updateData))
393 $updateData[
'ID'] =
$fields[
'ID'];
395 if (!isset(
$fields[
'PASSWORD']))
397 unset($updateData[
'VIDEOCONF'][
'PASSWORD']);
401 $chat = new \CIMChat(
$USER->GetID());
404 if ($updateData[
'TITLE'])
406 $renameResult = $chat->Rename($this->
getChatId(), $updateData[
'TITLE']);
412 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_RENAMING_CHAT'),
413 'CONFERENCE_RENAMING_ERROR'
418 $this->chatName = $updateData[
'TITLE'];
422 if (isset($updateData[
'NEW_USERS']))
427 $currentUserCount = \CIMChat::getUserCount($this->chatId);
428 $newUserCount = $currentUserCount +
count($updateData[
'NEW_USERS']);
429 if (isset($updateData[
'DELETED_USERS']))
431 $newUserCount -=
count($updateData[
'DELETED_USERS']);
434 if ($newUserCount > $userLimit)
438 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_MAX_USERS'),
444 foreach ($updateData[
'NEW_USERS'] as $newUser)
446 $addingResult = $chat->AddUser($this->
getChatId(), $newUser);
452 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_ADDING_USERS'),
461 if (isset($updateData[
'DELETED_USERS']))
463 foreach ($updateData[
'DELETED_USERS'] as $deletedUser)
465 $addingResult = $chat->DeleteUser($this->
getChatId(), $deletedUser);
471 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_DELETING_USERS'),
472 'DELETING_USER_ERROR'
480 if (isset($updateData[
'VIDEOCONF']))
482 if (isset($updateData[
'VIDEOCONF'][
'IS_BROADCAST']))
484 \CIMChat::SetChatParams($this->
getChatId(), [
485 'ENTITY_DATA_1' => $updateData[
'VIDEOCONF'][
'IS_BROADCAST'] ===
'Y'? self::BROADCAST_MODE:
''
489 $updateResult = ConferenceTable::update($updateData[
'ID'], $updateData[
'VIDEOCONF']);
491 if (!$updateResult->isSuccess())
493 return $result->addErrors($updateResult->getErrors());
498 if (isset($updateData[
'NEW_PRESENTERS']) && !empty($updateData[
'NEW_PRESENTERS']))
501 foreach ($updateData[
'NEW_PRESENTERS'] as $newPresenter)
504 $setManagers[$newPresenter] =
true;
506 $chat->SetManagers($this->
getChatId(), $setManagers,
false);
509 if (isset($updateData[
'DELETED_PRESENTERS']) && !empty($updateData[
'DELETED_PRESENTERS']))
511 $removeManagers = [];
512 foreach ($updateData[
'DELETED_PRESENTERS'] as $deletedPresenter)
515 $removeManagers[$deletedPresenter] =
false;
517 $chat->SetManagers($this->
getChatId(), $removeManagers,
false);
521 if (isset($updateData[
'VIDEOCONF'][
'IS_BROADCAST']) && $updateData[
'VIDEOCONF'][
'IS_BROADCAST'] ===
'N')
524 foreach ($presentersList as $presenter)
531 $isPullNeeded = isset($updateData[
'VIDEOCONF'][
'IS_BROADCAST']) || isset($updateData[
'NEW_PRESENTERS']) || isset($updateData[
'DELETED_PRESENTERS']);
532 if ($isPullNeeded && Loader::includeModule(
"pull"))
534 $relations = \CIMChat::GetRelationById($this->
getChatId(),
false,
true,
false);
537 'command' =>
'conferenceUpdate',
540 'isBroadcast' => isset($updateData[
'VIDEOCONF'][
'IS_BROADCAST']) ? $updateData[
'VIDEOCONF'][
'IS_BROADCAST'] ===
'Y' :
'',
559 RelationTable::deleteByFilter([
'=CHAT_ID' => $this->
getChatId()]);
563 foreach ($presenters as $presenter)
565 $deleteRolesResult = ConferenceUserRoleTable::delete(
567 'CONFERENCE_ID' => $this->
getId(),
568 'USER_ID' => $presenter
572 if (!$deleteRolesResult->isSuccess())
574 return $result->addErrors($deleteRolesResult->getErrors());
579 $deleteConferenceResult = ConferenceTable::delete($this->
getId());
580 if (!$deleteConferenceResult->isSuccess())
582 return $result->addErrors($deleteConferenceResult->getErrors());
587 if (!$deleteAliasResult->isSuccess())
589 return $result->addErrors($deleteAliasResult->getErrors());
593 $accessProvider = new \Bitrix\Im\Access\ChatAuthProvider;
594 $accessProvider->deleteChatCodes((
int)$this->
getChatId());
601 $result = new \Bitrix\Im\V2\Result();
602 $validatedFields = [];
609 $validatedFields[
'TITLE'] =
$fields[
'TITLE'];
616 if (strlen(
$fields[
'PASSWORD']) < 3)
620 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_PASSWORD_LENGTH_NEW'),
621 'PASSWORD_SHORT_ERROR'
626 $validatedFields[
'VIDEOCONF'][
'PASSWORD'] =
$fields[
'PASSWORD'];
630 $validatedFields[
'VIDEOCONF'][
'PASSWORD'] =
$fields[
'VIDEOCONF'][
'PASSWORD'] ??
'';
633 if (isset(
$fields[
'INVITATION']) && is_string(
$fields[
'INVITATION']))
637 if (strlen(
$fields[
'INVITATION']) > 255)
641 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_INVITATION_LENGTH'),
642 'INVITATION_LONG_ERROR'
647 $validatedFields[
'VIDEOCONF'][
'INVITATION'] =
$fields[
'INVITATION'];
649 elseif (isset(
$fields[
'VIDEOCONF'][
'INVITATION']) && is_string(
$fields[
'VIDEOCONF'][
'INVITATION']))
651 $validatedFields[
'VIDEOCONF'][
'INVITATION'] =
$fields[
'VIDEOCONF'][
'INVITATION'];
656 $validatedFields[
'USERS'] = [];
659 $validatedFields[
'USERS'][] = (int)
$userId;
669 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_NO_PRESENTERS'),
670 'PRESENTERS_EMPTY_ERROR'
675 if (
count(
$fields[
'PRESENTERS']) > self::PRESENTERS_LIMIT)
679 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_TOO_MANY_PRESENTERS'),
680 'PRESENTERS_TOO_MANY_ERROR'
685 $validatedFields[
'VIDEOCONF'][
'IS_BROADCAST'] =
'Y';
686 $validatedFields[
'VIDEOCONF'][
'PRESENTERS'] = [];
689 $validatedFields[
'USERS'][] = (int)
$userId;
690 $validatedFields[
'VIDEOCONF'][
'PRESENTERS'][] = (int)
$userId;
695 $validatedFields[
'VIDEOCONF'][
'IS_BROADCAST'] =
'N';
698 if (isset(
$fields[
'ALIAS_DATA']))
700 if (static::isAliasCorrect(
$fields[
'ALIAS_DATA']))
702 $validatedFields[
'VIDEOCONF'][
'ALIAS_DATA'] =
$fields[
'ALIAS_DATA'];
708 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_ALIAS'),
716 if (isset(
$fields[
'VIDEOCONF'][
'ALIAS_DATA']))
718 $validatedFields[
'VIDEOCONF'][
'ALIAS_DATA'] =
$fields[
'VIDEOCONF'][
'ALIAS_DATA'];
729 $result->setData([
'FIELDS' => $validatedFields]);
743 $addData =
$result->getData()[
'FIELDS'];
745 $result = ChatFactory::getInstance()->addChat($addData);
750 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_CREATING'),
756 $chatResult =
$result->getResult();
758 'CHAT_ID' => $chatResult[
'CHAT_ID'],
759 'ALIAS_DATA' => $addData[
'VIDEOCONF'][
'ALIAS_DATA']
765 $result = new \Bitrix\Im\V2\Result();
767 if (!static::isEnvironmentConfigured()) {
770 Loc::getMessage(
'IM_CALL_CONFERENCE_ERROR_ENVIRONMENT_CONFIG'),
771 'ENVIRONMENT_CONFIG_ERROR'
776 $validationResult = static::validateFields(
$fields);
778 if (!$validationResult->isSuccess())
780 return $result->addErrors($validationResult->getErrors());
783 $addData = $validationResult->getData()[
'FIELDS'];
784 $addData[
'ENTITY_TYPE'] = static::ALIAS_TYPE;
785 $addData[
'ENTITY_DATA_1'] = $addData[
'VIDEOCONF'][
'IS_BROADCAST'] ===
'Y'? static::BROADCAST_MODE:
'';
787 if (isset(
$fields[
'AUTHOR_ID']))
789 $addData[
'AUTHOR_ID'] = (int)
$fields[
'AUTHOR_ID'];
794 $addData[
'AUTHOR_ID'] = $currentUser->getId();
798 if (!isset(
$fields[
'MANAGERS']))
800 $addData[
'MANAGERS'] = [];
801 if ($addData[
'VIDEOCONF'][
'IS_BROADCAST'] ===
'Y')
803 foreach ($addData[
'VIDEOCONF'][
'PRESENTERS'] as $presenter)
805 $addData[
'MANAGERS'][$presenter] =
true;
810 $result->setData([
'FIELDS' => $addData]);
817 $conferenceFields = ConferenceTable::getRow(
819 'select' => self::getDefaultSelectFields(),
820 'runtime' => self::getRuntimeChatField(),
821 'filter' => [
'=ALIAS.ALIAS' =>
$alias,
'=ALIAS.ENTITY_TYPE' => static::ALIAS_TYPE]
825 if (!$conferenceFields)
830 return static::createWithArray($conferenceFields);
835 $conferenceFields = ConferenceTable::getRow(
837 'select' => self::getDefaultSelectFields(),
838 'runtime' => self::getRuntimeChatField(),
839 'filter' => [
'=ID' =>
$id,
'=ALIAS.ENTITY_TYPE' => static::ALIAS_TYPE]
843 if (!$conferenceFields)
848 return static::createWithArray($conferenceFields);
873 $list = ConferenceTable::getList($queryParams);
875 while ($item = $list->fetch())
888 return [static::STATE_NOT_STARTED, static::STATE_ACTIVE, static::STATE_FINISHED];
899 'ALIAS_PRIMARY' =>
'ALIAS.ID',
900 'ALIAS_CODE' =>
'ALIAS.ALIAS',
901 'CHAT_ID' =>
'ALIAS.ENTITY_ID',
902 'HOST' =>
'CHAT.AUTHOR.ID',
903 'HOST_NAME' =>
'CHAT.AUTHOR.NAME',
904 'HOST_LAST_NAME' =>
'CHAT.AUTHOR.LAST_NAME',
905 'CHAT_NAME' =>
'CHAT.TITLE'
912 new Entity\ReferenceField(
913 'CHAT',
'Bitrix\Im\Model\ChatTable', [
'=this.CHAT_ID' =>
'ref.ID']
915 new Entity\ReferenceField(
916 'RELATION',
'Bitrix\Im\Model\RelationTable', [
'=this.CHAT_ID' =>
'ref.CHAT_ID'], [
'join_type' =>
'inner']
923 AliasTable::deleteByFilter(
931 return __METHOD__.
'();';
934 private static function isAliasCorrect($aliasData): bool
936 return isset($aliasData[
'ID'], $aliasData[
'ALIAS']) &&
Alias::getByIdAndCode($aliasData[
'ID'], $aliasData[
'ALIAS']);
939 private static function isEnvironmentConfigured(): bool
943 && \CPullOptions::GetPublishWebEnabled()
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static getByIdAndCode($id, $code)
static delete($id, $filter=self::FILTER_BY_ID)
const ENTITY_TYPE_VIDEOCONF
static addUnique(array $fields)
static getMaxCallServerParticipants()
static isCallServerEnabled()
const ERROR_BITRIX24_ONLY
const BROADCAST_USER_LIMIT
getChangedFields(array $fields)
static createWithArray(array $fields)
static validateFields(array $fields)
static getAll(array $queryParams)
static add(array $fields=[])
deletePresenter(int $userId)
static getDefaultSelectFields()
static getRuntimeChatField()
static prepareParamsForAdd(array $fields)
static getByAlias(string $alias)
static removeTemporaryAliases()
makePresenter(int $userId)
const ERROR_KICKED_FROM_CALL
const ERROR_USER_LIMIT_REACHED
const ERROR_DETECT_INTRANET_USER
static getUsers($chatId, $options=[])
static getOwnerById($dialogId)
static getDialogId(int $chatId, $userId=null)
static isBroadcastingEnabled()
static getInstance($userId=null)
static add($recipient, array $parameters, $channelType=\CPullChannel::TYPE_PRIVATE)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"