26 private const ITERATION_LIMIT = 500;
28 private static $notifyDefaultSettings = [];
29 private static $generalDefaultSettings = [];
33 if (!Loader::includeModule(self::$moduleId))
38 $configTruncate = Option::get(self::$moduleId,
'config_truncate',
'N');
39 if ($configTruncate !==
'Y')
41 Option::set(self::$moduleId,
'migration_to_new_settings',
'N');
44 $connection->query(
"TRUNCATE TABLE b_im_option_user");
45 $connection->query(
"TRUNCATE TABLE b_im_option_state");
46 $connection->query(
"TRUNCATE TABLE b_im_option_access");
47 $connection->query(
"TRUNCATE TABLE b_im_option_group");
49 Option::set(self::$moduleId,
'config_truncate',
'Y');
52 $params = Option::get(self::$moduleId, self::OPTION_NAME,
'');
53 $params = ($params !==
'' ? @unserialize($params, [
'allowed_classes' =>
false]) : []);
54 $params = is_array($params) ? $params : [];
56 $unconvertedUsers = Option::get(self::$moduleId,
'unconverted_settings_users',
'');
57 $unconvertedUsers = $unconvertedUsers !==
'' ? @unserialize($unconvertedUsers, [
'allowed_classes' =>
false]) : [];
58 $unconvertedUsers = is_array($unconvertedUsers) ? $unconvertedUsers : [];
62 Option::set(self::$moduleId,
'migration_to_new_settings',
'N');
63 Configuration::cleanAllCache();
64 $unconvertedUsers = [];
66 $isIntranetIncluded = Loader::includeModule(
'intranet');
68 $defaultGroupId = $this->getDefaultGroupId();
71 $defaultGroupId = Configuration::createDefaultPreset();
73 elseif ($isIntranetIncluded)
75 $this->updateDefaultAccessCode($defaultGroupId);
78 $userCount = UserTable::getCount([
79 '=IS_REAL_USER' =>
'Y'
81 $convertedUserCount = OptionUserTable::getCount();
83 $unconvertedUserCount = $userCount - $convertedUserCount;
85 if ($unconvertedUserCount < 1)
87 if (empty($unconvertedUsers))
89 Option::delete(self::$moduleId, [
'name' =>
'unconverted_settings_users']);
92 Option::set(self::$moduleId,
'migration_to_new_settings',
'Y');
93 Option::delete(self::$moduleId, [
'name' => self::OPTION_NAME]);
101 'defaultGroup' => $defaultGroupId,
102 'includeIntranet' => $isIntranetIncluded,
103 'count' => $unconvertedUserCount
110 ->registerRuntimeField(
114 OptionUserTable::class,
115 Join::on(
'this.ID',
'=',
'ref.USER_ID'),
116 [
'join_type' => Join::TYPE_LEFT]
119 ->where(
'IS_REAL_USER',
'Y')
120 ->where(
'OPTION_USER.USER_ID',
null)
121 ->where(
'ID',
'>', $params[
'lastId'])
122 ->setOrder([
'ID' =>
'ASC'])
123 ->setLimit(self::ITERATION_LIMIT)
127 foreach ($query->exec() as $row)
129 $userIds[] = (int)$row[
'ID'];
134 if (empty($unconvertedUsers))
136 Option::delete(self::$moduleId, [
'name' =>
'unconverted_settings_users']);
139 Option::set(self::$moduleId,
'migration_to_new_settings',
'Y');
140 Option::delete(self::$moduleId, [
'name' =>
'last_converted_user']);
141 Option::delete(self::$moduleId, [
'name' => self::OPTION_NAME]);
146 $lastKeyId = array_key_last($userIds);
147 $params[
'lastId'] = $userIds[$lastKeyId];
149 foreach ($userIds as $userId)
153 $groupId = $this->isUserGroupExist($userId);
156 $this->bindExistingGroupToUser($userId, $groupId, $params[
'defaultGroup']);
160 $notifySettings = \CUserOptions::GetOption(
'im',
'notify', [], $userId);
161 $generalSettings = \CUserOptions::GetOption(
'im',
'settings', [], $userId);
163 if (empty($notifySettings) && empty($generalSettings))
165 OptionUserTable::add([
166 'USER_ID' => $userId,
167 'NOTIFY_GROUP_ID' => $params[
'defaultGroup'],
168 'GENERAL_GROUP_ID' => $params[
'defaultGroup']
173 $this->createPersonalPreset($userId, $notifySettings, $generalSettings, $params[
'defaultGroup']);
175 $params[
'lastConvertedUser'] = $userId;
179 $unconvertedUsers[] = $userId;
184 $option[
'count'] = $params[
'count'];
185 $option[
'progress'] = ($params[
'number'] * 100) / (
int)$params[
'count'];
186 $option[
'steps'] = $params[
'number'];
188 Option::set(self::$moduleId,
'last_converted_user', $params[
'lastConvertedUser']);
189 Option::set(self::$moduleId,
'unconverted_settings_users', serialize($unconvertedUsers));
190 Option::set(self::$moduleId, self::OPTION_NAME, serialize($params));
196 private function convertNotifySettings(array $oldUserSettings): array
198 if (empty(self::$notifyDefaultSettings))
200 self::$notifyDefaultSettings = Notification::getSimpleNotifySettings(General::getDefaultSettings());
203 $newFormatSettings = [];
204 foreach ($oldUserSettings as $name => $value)
206 [$type, $module, $event] = explode(
'|', $name, 3);
226 $newName = implode(
'|', [
'no', $module, $event, $type]);
228 $newFormatSettings[] = [
230 'VALUE' => $value ?
'Y' :
'N'
234 $newSettings = \Bitrix\Im\Configuration\Notification::decodeSettings($newFormatSettings);
235 return array_replace_recursive(self::$notifyDefaultSettings, $newSettings);
239 private function convertGeneralSettings(array $oldUserSettings): array
241 if (empty(self::$generalDefaultSettings))
243 self::$generalDefaultSettings = General::getDefaultSettings();
246 return array_replace_recursive(self::$generalDefaultSettings, $oldUserSettings);
249 private function createDefaultPreset($includeIntranet): int
252 OptionGroupTable::add([
253 'NAME' => Configuration::DEFAULT_PRESET_NAME,
259 $generalDefaultSettings = General::getDefaultSettings();
260 General::setSettings($defaultGroupId, $generalDefaultSettings);
262 $notifySettings = Notification::getSimpleNotifySettings($generalDefaultSettings);
263 Notification::setSettings($defaultGroupId, $notifySettings);
266 if ($includeIntranet)
268 $topDepartmentId = Department::getTopDepartmentId();
269 OptionAccessTable::add([
270 'GROUP_ID' => $defaultGroupId,
271 'ACCESS_CODE' => $topDepartmentId ?
'DR' . $topDepartmentId :
'AU'
275 return (
int)$defaultGroupId;
278 private function createPersonalPreset($userId, $notifySettings, $generalSettings, $defaultGroupId): void
281 OptionGroupTable::add([
282 'USER_ID' => $userId,
283 'SORT' => Configuration::USER_PRESET_SORT,
289 $isSettingsChanged =
false;
293 if (!empty($generalSettings))
295 $generalSettings = $this->convertGeneralSettings($generalSettings);
298 ->addSelect(
'STATUS')
299 ->where(
'USER_ID', $userId)
304 $generalSettings[
'status'] = $row[
'STATUS'];
307 General::setSettings($userGroupId, $generalSettings);
309 if ($generalSettings[
'notifyScheme'] ===
'simple' || empty($notifySettings))
311 $notifySettings = Notification::getSimpleNotifySettings($generalSettings);
315 $notifySettings = $this->convertNotifySettings($notifySettings);
318 Notification::setSettings($userGroupId, $notifySettings);
319 $isSettingsChanged =
true;
322 catch (\Exception $exception) {}
324 OptionUserTable::add([
325 'USER_ID' => $userId,
326 'NOTIFY_GROUP_ID' => $isSettingsChanged ? $userGroupId : $defaultGroupId,
327 'GENERAL_GROUP_ID' => $isSettingsChanged ? $userGroupId : $defaultGroupId
330 OptionAccessTable::add([
331 'GROUP_ID' => $userGroupId,
332 'ACCESS_CODE' =>
'U' . $userId
336 private function getDefaultGroupId()
339 OptionGroupTable::query()
341 ->where(
'NAME', Configuration::DEFAULT_PRESET_NAME)
344 return $defaultGroupId ? $defaultGroupId[
'ID'] :
false;
347 private function updateDefaultAccessCode($defaultGroupId): void
349 $topDepartmentId = Department::getTopDepartmentId();
350 $accessCode = $topDepartmentId ?
'DR' . $topDepartmentId :
'AU';
352 OptionAccessTable::update($defaultGroupId, [
353 'ACCESS_CODE' => $accessCode
357 private function isUserGroupExist($userId)
360 OptionGroupTable::query()
362 ->where(
'USER_ID', $userId);
364 $row = $query->fetch();
370 return (
int)$row[
'ID'];
373 private function bindExistingGroupToUser($userId, $groupId, $defaultGroupId): void
375 $notifyCount = OptionStateTable::getCount([
376 '=GROUP_ID' => $groupId,
380 $generalCount = OptionStateTable::getCount([
381 '=GROUP_ID' => $groupId,
385 $notifyGroupId = $notifyCount > 0 ? $groupId : $defaultGroupId;
386 $generalGroupId = $generalCount > 0 ? $groupId : $defaultGroupId;
388 if ($notifyGroupId === $groupId && $generalGroupId === $groupId)
392 'GENERAL_GROUP_ID' => $generalGroupId,
393 'NOTIFY_GROUP_ID' => $notifyGroupId
396 'GENERAL_GROUP_ID' => $generalGroupId,
397 'NOTIFY_GROUP_ID' => $notifyGroupId
400 OptionUserTable::merge($insertFields, $updateFields);
405 $generalSettings = \CUserOptions::GetOption(
'im',
'settings', [], $userId);
407 if ($generalGroupId === $defaultGroupId && !empty($generalSettings))
409 $generalGroupId = $groupId;
410 $generalSettings = $this->convertGeneralSettings($generalSettings);
412 General::setSettings($generalGroupId, $generalSettings);
415 if ($notifyGroupId === $defaultGroupId)
417 $notifySettings = \CUserOptions::GetOption(
'im',
'notify', [], $userId);
419 if ($generalSettings[
'notifyScheme'] ===
'simple')
421 $generalSettings = $this->convertGeneralSettings($generalSettings);
422 $notifySettings = Notification::getSimpleNotifySettings($generalSettings);
425 if (!empty($notifySettings))
427 $notifyGroupId = $groupId;
428 $notifySettings = $this->convertNotifySettings($notifySettings);
429 Notification::setSettings($notifyGroupId, $notifySettings);
435 'GENERAL_GROUP_ID' => $generalGroupId,
436 'NOTIFY_GROUP_ID' => $notifyGroupId
439 'GENERAL_GROUP_ID' => $generalGroupId,
440 'NOTIFY_GROUP_ID' => $notifyGroupId
443 OptionUserTable::merge($insertFields, $updateFields);