Скрипт очищает список недавних чатов Bitrix24 от «пустых» записей — контактов, которые отображаются в интерфейсе, но не содержат ни одного сообщения. Технически это строки в таблице b_im_recent с полями ITEM_TYPE = 'P' и ITEM_MID = 0.
Такие записи появляются, когда пользователи «открывали» диалог с коллегой, но ничего не написали. Со временем их накапливается много, и они мешают работе с чатами.
Режимы работы
?action=count— только считает и показывает примеры (безопасный режим, по умолчанию)?action=delete— удаляет все найденные записи и связанные пустые чаты
Скрипт
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
<?php /** * Скрипт удаления пустых записей из списка недавних чатов. * * Это записи в b_im_recent с ITEM_TYPE='P' (приватный контакт), * у которых ITEM_MID=0 (нет ни одного сообщения). * В интерфейсе они отображаются как пустые чаты с data-id="<USER_ID>". * * Запуск через браузер: * ?action=count — подсчёт (по умолчанию) * ?action=delete — удаление */ $_SERVER['DOCUMENT_ROOT'] = __DIR__; define('NO_KEEP_STATISTIC', true); define('NOT_CHECK_PERMISSIONS', true); define('BX_NO_ACCELERATOR_RESET', true); define('STOP_STATISTICS', true); define('NO_AGENT_CHECK', true); define('DisableEventsCheck', true); require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; use Bitrix\Main\Loader; use Bitrix\Main\Application; Loader::includeModule('im'); $action = isset($_GET['action']) ? $_GET['action'] : 'count'; header('Content-Type: text/plain; charset=utf-8'); function output($msg) { echo $msg . "\n"; flush(); } $connection = Application::getConnection(); // ============================================================ // 1. Записи в b_im_recent без сообщений (ITEM_MID = 0) // ============================================================ output("=== Пустые записи в списке недавних (b_im_recent) ===\n"); // Общее количество $row = $connection->query(" SELECT COUNT(*) as CNT FROM b_im_recent WHERE ITEM_TYPE = 'P' AND ITEM_MID = 0 ")->fetch(); $totalRecent = (int)$row['CNT']; output("Всего записей ITEM_TYPE='P', ITEM_MID=0: {$totalRecent}"); // Из них без созданного чата $row2 = $connection->query(" SELECT COUNT(*) as CNT FROM b_im_recent WHERE ITEM_TYPE = 'P' AND ITEM_MID = 0 AND ITEM_CID = 0 ")->fetch(); output(" - без чата (ITEM_CID=0): {$row2['CNT']}"); // Из них с чатом, но без сообщений $row3 = $connection->query(" SELECT COUNT(*) as CNT FROM b_im_recent WHERE ITEM_TYPE = 'P' AND ITEM_MID = 0 AND ITEM_CID > 0 ")->fetch(); output(" - с чатом, но без сообщений (ITEM_CID>0): {$row3['CNT']}"); if ($totalRecent === 0) { output("\nНечего удалять."); require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php'; exit; } // Показываем примеры if ($action === 'count') { output("\nПримеры (первые 30):"); $res = $connection->query(" SELECT r.USER_ID, r.ITEM_ID, r.ITEM_MID, r.ITEM_CID, r.DATE_MESSAGE, r.DATE_UPDATE FROM b_im_recent r WHERE r.ITEM_TYPE = 'P' AND r.ITEM_MID = 0 ORDER BY r.USER_ID, r.ITEM_ID LIMIT 30 "); while ($r = $res->fetch()) { output(" User {$r['USER_ID']} -> Contact {$r['ITEM_ID']} | ChatID: {$r['ITEM_CID']} | Date: {$r['DATE_MESSAGE']}"); } output("\nДля удаления: ?action=delete"); require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php'; exit; } // ============================================================ // Удаление // ============================================================ if ($action !== 'delete') { output("Неизвестное действие: {$action}. Используйте 'count' или 'delete'."); require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php'; exit; } output("\nУдаляем {$totalRecent} записей из b_im_recent...\n"); $connection->startTransaction(); try { // Также удаляем связанные пустые чаты (если были созданы, но без сообщений) $emptyChatIds = []; $res = $connection->query(" SELECT DISTINCT ITEM_CID FROM b_im_recent WHERE ITEM_TYPE = 'P' AND ITEM_MID = 0 AND ITEM_CID > 0 "); while ($r = $res->fetch()) { $emptyChatIds[] = (int)$r['ITEM_CID']; } // Удаляем записи из b_im_recent $connection->queryExecute(" DELETE FROM b_im_recent WHERE ITEM_TYPE = 'P' AND ITEM_MID = 0 "); output(" Удалено записей из b_im_recent: {$totalRecent}"); // Удаляем связанные пустые чаты if (!empty($emptyChatIds)) { $ids = implode(',', $emptyChatIds); $connection->queryExecute("DELETE FROM b_im_message_unread WHERE CHAT_ID IN ({$ids})"); $connection->queryExecute("DELETE FROM b_im_relation WHERE CHAT_ID IN ({$ids})"); $connection->queryExecute("DELETE FROM b_im_chat_index WHERE CHAT_ID IN ({$ids})"); $connection->queryExecute("DELETE FROM b_im_chat WHERE ID IN ({$ids}) AND MESSAGE_COUNT = 0"); output(" Удалено связанных пустых чатов: " . count($emptyChatIds)); } $connection->commitTransaction(); output("\n=== Готово, ошибок нет ==="); } catch (\Exception $e) { $connection->rollbackTransaction(); output("\n=== ОШИБКА: " . $e->getMessage() . " ==="); } // Очистка кеша if (defined('BX_COMP_MANAGED_CACHE')) { $GLOBALS['CACHE_MANAGER']->ClearByTag('im_chat'); $GLOBALS['CACHE_MANAGER']->ClearByTag('im_recent'); } require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php'; |
Что удаляется
- Записи из
b_im_recentсITEM_TYPE='P'иITEM_MID=0 - Связанные пустые чаты (
MESSAGE_COUNT = 0) из таблицb_im_chat,b_im_relation,b_im_message_unread,b_im_chat_index
Важно: всегда запускайте сначала с ?action=count, чтобы убедиться в корректности выборки. После удаления файл нужно убрать с сервера.
