|
|
@@ -35,4 +35,41 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // migrate AI chat threads
|
|
|
+ if ($this->oDb->isFieldExists('sys_agents_chat_history', 'thread_id')) {
|
|
|
+ $aRows = $this->oDb->getAll("SELECT `id`, `thread_id` FROM `sys_agents_chat_history` WHERE `thread_id` LIKE '%.%'");
|
|
|
+ foreach ($aRows as $aRow) {
|
|
|
+ $sThreadId = (string)$aRow['thread_id'];
|
|
|
+ $iColon = strrpos($sThreadId, ':');
|
|
|
+ $sSub = $iColon === false ? $sThreadId : substr($sThreadId, $iColon + 1);
|
|
|
+ $sPrefix = $iColon === false ? '' : substr($sThreadId, 0, $iColon + 1);
|
|
|
+ $iDot = strrpos($sSub, '.');
|
|
|
+ if ($iDot === false)
|
|
|
+ continue;
|
|
|
+ $sOwner = substr($sSub, 0, $iDot);
|
|
|
+ $sChat = substr($sSub, $iDot + 1);
|
|
|
+ if (!preg_match('/^[A-Za-z0-9_-]{8,64}$/', $sChat))
|
|
|
+ continue;
|
|
|
+ // Bare guest ids are 32 characters (genRndPwd) and may contain a dot.
|
|
|
+ // That is the session id itself, not a member `{profileId}.{chat}` partition.
|
|
|
+ $bMember = (strlen($sSub) !== 32 && strpos($sSub, '.') === $iDot && preg_match('/^[0-9]+$/', $sOwner));
|
|
|
+ $bGuest = (strlen($sOwner) === 32);
|
|
|
+ if (!$bMember && !$bGuest)
|
|
|
+ continue;
|
|
|
+ $sNew = $sPrefix . $sOwner . '#' . $sChat;
|
|
|
+ if ($sNew === $sThreadId)
|
|
|
+ continue;
|
|
|
+ $aTaken = $this->oDb->getRow("SELECT `id` FROM `sys_agents_chat_history` WHERE `thread_id` = :t LIMIT 1", [
|
|
|
+ 't' => $sNew,
|
|
|
+ ]);
|
|
|
+ if (!empty($aTaken['id']))
|
|
|
+ continue;
|
|
|
+ $this->oDb->query("UPDATE `sys_agents_chat_history` SET `thread_id` = :n WHERE `id` = :id AND `thread_id` = :o", [
|
|
|
+ 'n' => $sNew,
|
|
|
+ 'id' => (int)$aRow['id'],
|
|
|
+ 'o' => $sThreadId,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|