Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
chatconfigconverter.php
1<?php
2namespace Bitrix\Im\Update;
3
21
23{
24 public const OPTION_NAME = 'im_chat_config_converter';
25 protected static $moduleId = 'im';
26 private const ITERATION_LIMIT = 500;
27
28 private static $notifyDefaultSettings = [];
29 private static $generalDefaultSettings = [];
30
31 public function execute(array &$option)
32 {
33 if (!Loader::includeModule(self::$moduleId))
34 {
35 return false;
36 }
37
38 $configTruncate = Option::get(self::$moduleId, 'config_truncate', 'N');
39 if ($configTruncate !== 'Y')
40 {
41 Option::set(self::$moduleId, 'migration_to_new_settings', 'N');
42
43 $connection = Application::getConnection();
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");
48
49 Option::set(self::$moduleId, 'config_truncate', 'Y');
50 }
51
52 $params = Option::get(self::$moduleId, self::OPTION_NAME, '');
53 $params = ($params !== '' ? @unserialize($params, ['allowed_classes' => false]) : []);
54 $params = is_array($params) ? $params : [];
55
56 $unconvertedUsers = Option::get(self::$moduleId, 'unconverted_settings_users', '');
57 $unconvertedUsers = $unconvertedUsers !== '' ? @unserialize($unconvertedUsers, ['allowed_classes' => false]) : [];
58 $unconvertedUsers = is_array($unconvertedUsers) ? $unconvertedUsers : [];
59
60 if (empty($params))
61 {
62 Option::set(self::$moduleId, 'migration_to_new_settings', 'N');
63 Configuration::cleanAllCache();
64 $unconvertedUsers = [];
65
66 $isIntranetIncluded = Loader::includeModule('intranet');
67
68 $defaultGroupId = $this->getDefaultGroupId();
69 if (!$defaultGroupId)
70 {
71 $defaultGroupId = Configuration::createDefaultPreset();
72 }
73 elseif ($isIntranetIncluded)
74 {
75 $this->updateDefaultAccessCode($defaultGroupId);
76 }
77
78 $userCount = UserTable::getCount([
79 '=IS_REAL_USER' => 'Y'
80 ]);
81 $convertedUserCount = OptionUserTable::getCount();
82
83 $unconvertedUserCount = $userCount - $convertedUserCount;
84
85 if ($unconvertedUserCount < 1)
86 {
87 if (empty($unconvertedUsers))
88 {
89 Option::delete(self::$moduleId, ['name' => 'unconverted_settings_users']);
90 }
91
92 Option::set(self::$moduleId, 'migration_to_new_settings', 'Y');
93 Option::delete(self::$moduleId, ['name' => self::OPTION_NAME]);
94
95 return false;
96 }
97
98 $params = [
99 'lastId' => 0,
100 'number' => 0,
101 'defaultGroup' => $defaultGroupId,
102 'includeIntranet' => $isIntranetIncluded,
103 'count' => $unconvertedUserCount
104 ];
105 }
106
107 $query =
108 UserTable::query()
109 ->addSelect('ID')
110 ->registerRuntimeField(
111 'OPTION_USER',
112 new Reference(
113 'OPTION_USER',
114 OptionUserTable::class,
115 Join::on('this.ID', '=', 'ref.USER_ID'),
116 ['join_type' => Join::TYPE_LEFT]
117 )
118 )
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)
124 ;
125
126 $userIds = [];
127 foreach ($query->exec() as $row)
128 {
129 $userIds[] = (int)$row['ID'];
130 }
131
132 if (empty($userIds))
133 {
134 if (empty($unconvertedUsers))
135 {
136 Option::delete(self::$moduleId, ['name' => 'unconverted_settings_users']);
137 }
138
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]);
142
143 return false;
144 }
145
146 $lastKeyId = array_key_last($userIds);
147 $params['lastId'] = $userIds[$lastKeyId];
148
149 foreach ($userIds as $userId)
150 {
151 try
152 {
153 $groupId = $this->isUserGroupExist($userId);
154 if ($groupId)
155 {
156 $this->bindExistingGroupToUser($userId, $groupId, $params['defaultGroup']);
157
158 continue;
159 }
160 $notifySettings = \CUserOptions::GetOption('im', 'notify', [], $userId);
161 $generalSettings = \CUserOptions::GetOption('im', 'settings', [], $userId);
162
163 if (empty($notifySettings) && empty($generalSettings))
164 {
165 OptionUserTable::add([
166 'USER_ID' => $userId,
167 'NOTIFY_GROUP_ID' => $params['defaultGroup'],
168 'GENERAL_GROUP_ID' => $params['defaultGroup']
169 ]);
170 }
171 else
172 {
173 $this->createPersonalPreset($userId, $notifySettings, $generalSettings, $params['defaultGroup']);
174 }
175 $params['lastConvertedUser'] = $userId;
176 }
177 catch (\Exception $e)
178 {
179 $unconvertedUsers[] = $userId;
180 }
181 $params['number']++;
182 }
183
184 $option['count'] = $params['count'];
185 $option['progress'] = ($params['number'] * 100) / (int)$params['count'];
186 $option['steps'] = $params['number'];
187
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));
191
192 return true;
193
194 }
195
196 private function convertNotifySettings(array $oldUserSettings): array
197 {
198 if (empty(self::$notifyDefaultSettings))
199 {
200 self::$notifyDefaultSettings = Notification::getSimpleNotifySettings(General::getDefaultSettings());
201 }
202
203 $newFormatSettings = [];
204 foreach ($oldUserSettings as $name => $value)
205 {
206 [$type, $module, $event] = explode('|', $name, 3);
207
208 switch ($type)
209 {
210 case 'site':
211 $type = 1;
212 break;
213
214 case 'email':
215 $type = 2;
216 break;
217
218 case 'xmpp':
219 $type = 3;
220 break;
221
222 case 'push':
223 $type = 4;
224 break;
225 }
226 $newName = implode('|', ['no', $module, $event, $type]);
227
228 $newFormatSettings[] = [
229 'NAME' => $newName,
230 'VALUE' => $value ? 'Y' : 'N'
231 ];
232 }
233
234 $newSettings = \Bitrix\Im\Configuration\Notification::decodeSettings($newFormatSettings);
235 return array_replace_recursive(self::$notifyDefaultSettings, $newSettings);
236
237 }
238
239 private function convertGeneralSettings(array $oldUserSettings): array
240 {
241 if (empty(self::$generalDefaultSettings))
242 {
243 self::$generalDefaultSettings = General::getDefaultSettings();
244 }
245
246 return array_replace_recursive(self::$generalDefaultSettings, $oldUserSettings);
247 }
248
249 private function createDefaultPreset($includeIntranet): int
250 {
251 $defaultGroupId =
252 OptionGroupTable::add([
253 'NAME' => Configuration::DEFAULT_PRESET_NAME,
254 'SORT' => 0,
255 'CREATE_BY_ID' => 0,
256 ])
257 ->getId()
258 ;
259 $generalDefaultSettings = General::getDefaultSettings();
260 General::setSettings($defaultGroupId, $generalDefaultSettings);
261
262 $notifySettings = Notification::getSimpleNotifySettings($generalDefaultSettings);
263 Notification::setSettings($defaultGroupId, $notifySettings);
264
265
266 if ($includeIntranet)
267 {
268 $topDepartmentId = Department::getTopDepartmentId();
269 OptionAccessTable::add([
270 'GROUP_ID' => $defaultGroupId,
271 'ACCESS_CODE' => $topDepartmentId ? 'DR' . $topDepartmentId : 'AU'
272 ]);
273 }
274
275 return (int)$defaultGroupId;
276 }
277
278 private function createPersonalPreset($userId, $notifySettings, $generalSettings, $defaultGroupId): void
279 {
280 $userGroupId =
281 OptionGroupTable::add([
282 'USER_ID' => $userId,
283 'SORT' => Configuration::USER_PRESET_SORT,
284 'CREATE_BY_ID' => 0
285 ])
286 ->getId()
287 ;
288
289 $isSettingsChanged = false;
290
291 try
292 {
293 if (!empty($generalSettings))
294 {
295 $generalSettings = $this->convertGeneralSettings($generalSettings);
296 $row =
297 StatusTable::query()
298 ->addSelect('STATUS')
299 ->where('USER_ID', $userId)
300 ->fetch()
301 ;
302 if ($row)
303 {
304 $generalSettings['status'] = $row['STATUS'];
305 }
306
307 General::setSettings($userGroupId, $generalSettings);
308
309 if ($generalSettings['notifyScheme'] === 'simple' || empty($notifySettings))
310 {
311 $notifySettings = Notification::getSimpleNotifySettings($generalSettings);
312 }
313 else
314 {
315 $notifySettings = $this->convertNotifySettings($notifySettings);
316 }
317
318 Notification::setSettings($userGroupId, $notifySettings);
319 $isSettingsChanged = true;
320 }
321 }
322 catch (\Exception $exception) {}
323
324 OptionUserTable::add([
325 'USER_ID' => $userId,
326 'NOTIFY_GROUP_ID' => $isSettingsChanged ? $userGroupId : $defaultGroupId,
327 'GENERAL_GROUP_ID' => $isSettingsChanged ? $userGroupId : $defaultGroupId
328 ]);
329
330 OptionAccessTable::add([
331 'GROUP_ID' => $userGroupId,
332 'ACCESS_CODE' => 'U' . $userId
333 ]);
334 }
335
336 private function getDefaultGroupId()
337 {
338 $defaultGroupId =
339 OptionGroupTable::query()
340 ->addSelect('ID')
341 ->where('NAME', Configuration::DEFAULT_PRESET_NAME)
342 ->fetch();
343
344 return $defaultGroupId ? $defaultGroupId['ID'] : false;
345 }
346
347 private function updateDefaultAccessCode($defaultGroupId): void
348 {
349 $topDepartmentId = Department::getTopDepartmentId();
350 $accessCode = $topDepartmentId ? 'DR' . $topDepartmentId : 'AU';
351
352 OptionAccessTable::update($defaultGroupId, [
353 'ACCESS_CODE' => $accessCode
354 ]);
355 }
356
357 private function isUserGroupExist($userId)
358 {
359 $query =
360 OptionGroupTable::query()
361 ->addSelect('ID')
362 ->where('USER_ID', $userId);
363
364 $row = $query->fetch();
365 if (!$row)
366 {
367 return false;
368 }
369
370 return (int)$row['ID'];
371 }
372
373 private function bindExistingGroupToUser($userId, $groupId, $defaultGroupId): void
374 {
375 $notifyCount = OptionStateTable::getCount([
376 '=GROUP_ID' => $groupId,
377 '%=NAME' => 'no%'
378 ]);
379
380 $generalCount = OptionStateTable::getCount([
381 '=GROUP_ID' => $groupId,
382 '%=NAME' => 'se%'
383 ]);
384
385 $notifyGroupId = $notifyCount > 0 ? $groupId : $defaultGroupId;
386 $generalGroupId = $generalCount > 0 ? $groupId : $defaultGroupId;
387
388 if ($notifyGroupId === $groupId && $generalGroupId === $groupId)
389 {
390 $insertFields = [
391 'USER_ID' => $userId,
392 'GENERAL_GROUP_ID' => $generalGroupId,
393 'NOTIFY_GROUP_ID' => $notifyGroupId
394 ];
395 $updateFields = [
396 'GENERAL_GROUP_ID' => $generalGroupId,
397 'NOTIFY_GROUP_ID' => $notifyGroupId
398 ];
399
400 OptionUserTable::merge($insertFields, $updateFields);
401
402 return;
403 }
404
405 $generalSettings = \CUserOptions::GetOption('im', 'settings', [], $userId);
406
407 if ($generalGroupId === $defaultGroupId && !empty($generalSettings))
408 {
409 $generalGroupId = $groupId;
410 $generalSettings = $this->convertGeneralSettings($generalSettings);
411
412 General::setSettings($generalGroupId, $generalSettings);
413 }
414
415 if ($notifyGroupId === $defaultGroupId)
416 {
417 $notifySettings = \CUserOptions::GetOption('im', 'notify', [], $userId);
418
419 if ($generalSettings['notifyScheme'] === 'simple')
420 {
421 $generalSettings = $this->convertGeneralSettings($generalSettings);
422 $notifySettings = Notification::getSimpleNotifySettings($generalSettings);
423 }
424
425 if (!empty($notifySettings))
426 {
427 $notifyGroupId = $groupId;
428 $notifySettings = $this->convertNotifySettings($notifySettings);
429 Notification::setSettings($notifyGroupId, $notifySettings);
430 }
431 }
432
433 $insertFields = [
434 'USER_ID' => $userId,
435 'GENERAL_GROUP_ID' => $generalGroupId,
436 'NOTIFY_GROUP_ID' => $notifyGroupId
437 ];
438 $updateFields = [
439 'GENERAL_GROUP_ID' => $generalGroupId,
440 'NOTIFY_GROUP_ID' => $notifyGroupId
441 ];
442
443 OptionUserTable::merge($insertFields, $updateFields);
444 }
445
446}
static getConnection($name="")