650 lines
22 KiB
PHP
Executable File
650 lines
22 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Get version of xuanxuan.
|
|
*
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getXuanxuanVersion()
|
|
{
|
|
return !empty($this->config->xuanxuan->global->version) ? $this->config->xuanxuan->global->version : '1.0';
|
|
}
|
|
|
|
/**
|
|
* Upgrade xuanxuan.
|
|
*
|
|
* @param string $fromVersion
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function upgradeXuanxuan($fromVersion)
|
|
{
|
|
switch($fromVersion)
|
|
{
|
|
case '1.0' : $this->execSQL($this->getUpgradeFile('xuanxuan1.0'));
|
|
case '1.1.0' :
|
|
case '1.1.1' : $this->execSQL($this->getUpgradeFile('xuanxuan1.1.1'));
|
|
case '1.3.0' : $this->execSQL($this->getUpgradeFile('xuanxuan1.3.0'));
|
|
case '1.4.0' : $this->execSQL($this->getUpgradeFile('xuanxuan1.4.0'));
|
|
$this->processMessageStatus();
|
|
case '1.5.0' :
|
|
case '1.6.0' : $this->execSQL($this->getUpgradeFile('xuanxuan1.6.0'));
|
|
case '2.0.0' : $this->execSQL($this->getUpgradeFile('xuanxuan2.0.0'));
|
|
case '2.1.0' : $this->execSQL($this->getUpgradeFile('xuanxuan2.1.0'));
|
|
case '2.2.0' :
|
|
$this->processUserStatus();
|
|
$this->processXuanxuanKey();
|
|
case '2.3.0' : $this->execSQL($this->getUpgradeFile('xuanxuan2.3.0'));
|
|
case '2.4.0' : $this->execSQL($this->getUpgradeFile('xuanxuan2.4.0'));
|
|
$this->changeMessageStatusTable();
|
|
case '2.5.0' : $this->execSQL($this->getUpgradeFile('xuanxuan2.5.0'));
|
|
case '2.5.1' :
|
|
case '2.5.2' :
|
|
case '2.5.3' :
|
|
case '2.5.4' :
|
|
case '2.5.5' :
|
|
case '2.5.6' :
|
|
case '2.5.7' : $this->execSQL($this->getUpgradeFile('xuanxuan2.5.7'));
|
|
case '3.0.0-beta.1' : $this->execSQL($this->getUpgradeFile('xuanxuan3.0.0-beta.1'));
|
|
case '3.0 beta2' :
|
|
case '3.0-beta3' : $this->execSQL($this->getUpgradeFile('xuanxuan3.0-beta3'));
|
|
case '3.0.beta4' :
|
|
case '3.0' :
|
|
case '3.1' :
|
|
case '3.1.1' : $this->execSQL($this->getUpgradeFile('xuanxuan3.1.1'));
|
|
case '3.2' :
|
|
case '3.2.1' :
|
|
case '3.2.2' :
|
|
case '3.2.3' : $this->execSQL($this->getUpgradeFile('xuanxuan3.2.3'));
|
|
case '3.3' :
|
|
$this->execSQL($this->getUpgradeFile('xuanxuan3.3'));
|
|
$this->updateLastMessage();
|
|
$this->updateUserDevice();
|
|
case '4.0.beta1' :
|
|
case '4.0.beta2' : $this->execSQL($this->getUpgradeFile('xuanxuan4.0.beta2'));
|
|
case '4.0.beta3' :
|
|
$this->execSQL($this->getUpgradeFile('xuanxuan4.0.beta3'));
|
|
$this->dropOrderFromMessagePartitions();
|
|
case '4.0' : $this->execSQL($this->getUpgradeFile('xuanxuan4.0'));
|
|
case '4.1.beta' :
|
|
case '4.1' :
|
|
case '4.2' : $this->execSQL($this->getUpgradeFile('xuanxuan4.2'));
|
|
case '4.3' :
|
|
case '4.4' : $this->execSQL($this->getUpgradeFile('xuanxuan4.4'));
|
|
case '4.4.1' :
|
|
case '4.5.beta1' :
|
|
case '4.5' :
|
|
case '4.6' : $this->execSQL($this->getUpgradeFile('xuanxuan4.6'));
|
|
case '4.7' :
|
|
case '5.0' :
|
|
case '5.1' : $this->execSQL($this->getUpgradeFile('xuanxuan5.1'));
|
|
case '5.2' :
|
|
case '5.3' :
|
|
case '5.3.1' :
|
|
case '5.3.2' :
|
|
case '5.4' :
|
|
case '5.5' : $this->execSQL($this->getUpgradeFile('xuanxuan5.5'));
|
|
case '5.6' :
|
|
$this->execSQL($this->getUpgradeFile('xuanxuan5.6'));
|
|
$this->addMessageIndexColumns();
|
|
$this->reindexMessages();
|
|
$this->populateLastReadMessageIndex();
|
|
case '6.0.beta' : $this->fixChatsWithoutLastRead();
|
|
case '6.0' : $this->transferDeletedUserGroups();
|
|
case '6.0.1' : $this->execSQL($this->getUpgradeFile('xuanxuan6.0.1'));
|
|
case '6.1' :
|
|
case '6.2' :
|
|
case '6.3' :
|
|
$this->setOwnedByForGroups();
|
|
$this->recoverCreatedDates();
|
|
$this->setPartitionedMessageIndex();
|
|
case '6.4' : $this->execSQL($this->getUpgradeFile('xuanxuan6.4'));
|
|
case '6.5' :
|
|
$this->execSQL($this->getUpgradeFile('xuanxuan6.5'));
|
|
$this->setMuteForHiddenGroups();
|
|
$this->notifyGroupHiddenUsers();
|
|
case '6.6' : $this->execSQL($this->getUpgradeFile('xuanxuan6.6'));
|
|
case '7.0' :
|
|
case '7.1' : $this->execSQL($this->getUpgradeFile('xuanxuan7.1'));
|
|
case '7.2.beta' : $this->execSQL($this->getUpgradeFile('xuanxuan7.2.beta'));
|
|
case '7.2' :
|
|
default : $this->loadModel('setting')->setItem('system.xuanxuan.global.version', isset($this->config->product) && $this->config->product == 'xxb' ? $this->config->version : $this->config->xuanxuan->version);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Change status of table user to clientStatus.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function processUserStatus()
|
|
{
|
|
$hasStatus = false;
|
|
$hasClientStatus = false;
|
|
|
|
$fields = $this->dbh->query('DESC ' . TABLE_USER)->fetchAll();
|
|
foreach($fields as $field)
|
|
{
|
|
if($field->Field == 'status') $hasStatus = true;
|
|
if($field->Field == 'clientStatus') $hasClientStatus = true;
|
|
}
|
|
|
|
if($hasStatus && !$hasClientStatus)
|
|
{
|
|
try
|
|
{
|
|
$this->dbh->exec('ALTER TABLE ' . TABLE_USER . "CHANGE `status` `clientStatus` enum('online', 'away', 'busy', 'offline') NOT NULL DEFAULT 'offline'");
|
|
}
|
|
catch (PDOException $e)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Process message status.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function processMessageStatus()
|
|
{
|
|
$table = $this->dbh->query("SHOW TABLES LIKE '{$this->config->db->prefix}im_usermessage'")->fetch();
|
|
if(empty($table)) return false;
|
|
|
|
$userMessages = array();
|
|
$messagesList = $this->dao->select('*')->from($this->config->db->prefix . 'im_usermessage')->fetchAll();
|
|
foreach($messagesList as $messages)
|
|
{
|
|
$user = $messages->user;
|
|
$messages = json_decode($messages->message);
|
|
foreach($messages as $message)
|
|
{
|
|
if(isset($userMessages[$user][$message->gid])) continue;
|
|
|
|
$data = new stdClass();
|
|
$data->user = $user;
|
|
$data->gid = $message->gid;
|
|
$data->status = 'waiting';
|
|
$this->dao->insert(TABLE_IM_MESSAGESTATUS)->data($data)->exec();
|
|
|
|
$userMessages[$user][$message->gid] = $message->gid;
|
|
}
|
|
}
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Process key of xuanxuan.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function processXuanxuanKey()
|
|
{
|
|
$this->loadModel('setting')->setItem('system.common.xuanxuan.key', $this->config->xuanxuan->key);
|
|
$this->setting->deleteItems('owner=system&module=xuanxuan&key=key');
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Fix the history and Change messagestatus table.
|
|
* @return bool
|
|
*/
|
|
public function changeMessageStatusTable()
|
|
{
|
|
$prefix = $this->config->db->prefix;
|
|
$errorTable = $this->dbh->query("show tables like '{$prefix}im_messsagestatus'")->fetch();
|
|
if(!empty($errorTable)) $this->dbh->query("RENAME TABLE `{$prefix}im_messsagestatus` TO `{$prefix}im_messagestatus`");
|
|
$needUpdate = false;
|
|
$fields = $this->dbh->query('DESC ' . TABLE_IM_MESSAGESTATUS)->fetchAll();
|
|
foreach($fields as $field)
|
|
{
|
|
if($field->Field == 'gid')
|
|
{
|
|
$needUpdate = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!$needUpdate) return false;
|
|
|
|
$gids = $this->dao->select('gid')->from(TABLE_IM_MESSAGESTATUS)->where('status')->ne('sent')->fetchPairs('gid');
|
|
if(!empty($gids))
|
|
{
|
|
$messages = $this->dao->select('gid, id')->from(TABLE_IM_MESSAGE)->where('gid')->in($gids)->fetchPairs();
|
|
foreach($messages as $gid => $message)
|
|
{
|
|
$this->dao->update(TABLE_IM_MESSAGESTATUS)->set('message')->eq($message)->where('gid')->eq($gid)->exec();
|
|
}
|
|
}
|
|
$this->dao->delete()->from(TABLE_IM_MESSAGESTATUS)->where('status')->eq('sent')->exec();
|
|
|
|
$userIndex = $this->dbh->query("show index from " . TABLE_IM_MESSAGESTATUS . " where Key_name = 'user'")->fetch();
|
|
if($userIndex) $this->dbh->exec('ALTER TABLE ' . TABLE_IM_MESSAGESTATUS . ' DROP INDEX `user`;');
|
|
$this->dbh->exec('ALTER TABLE ' . TABLE_IM_MESSAGESTATUS . ' DROP `gid`;');
|
|
$this->dbh->exec('ALTER TABLE ' . TABLE_IM_MESSAGESTATUS . ' ADD UNIQUE INDEX `user` (`user`, `message`);');
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Update lastMessage of im_chat table.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function updateLastMessage()
|
|
{
|
|
$prefix = $this->config->db->prefix;
|
|
$lastMessageData = array();
|
|
$lastMessages = $this->dbh->query("SELECT MAX({$prefix}im_message.id),{$prefix}im_chat.id FROM {$prefix}im_message LEFT JOIN {$prefix}im_chat ON {$prefix}im_message.cgid = {$prefix}im_chat.gid GROUP BY {$prefix}im_chat.gid;")->fetchAll();
|
|
if(empty($lastMessages)) return true;
|
|
foreach($lastMessages as $lastMessage)
|
|
{
|
|
$cid = $lastMessage->id;
|
|
$mid = $lastMessage->{"MAX({$prefix}im_message.id)"};
|
|
if(empty($cid) || empty($mid)) continue;
|
|
$lastMessageData[] = "($cid,$mid)";
|
|
}
|
|
if(empty($lastMessageData)) return true;
|
|
$query = "INSERT INTO `{$prefix}im_chat` (`id`,`lastMessage`) VALUES " . join(',', $lastMessageData) . " ON DUPLICATE KEY UPDATE `lastMessage`=VALUES(`lastMessage`)";
|
|
$this->dbh->query($query);
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Move data into im_userdevice table.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function updateUserDevice()
|
|
{
|
|
$prefix = $this->config->db->prefix;
|
|
$userDeviceData = array();
|
|
$userDevices = $this->dbh->query("SELECT " . TABLE_CONFIG . ".`value`," . TABLE_USER . ".`id` FROM " . TABLE_CONFIG . " LEFT JOIN " . TABLE_USER . " ON " . TABLE_CONFIG . ".`owner` = " . TABLE_USER . ".`account` WHERE " . TABLE_CONFIG . ".`section` = 'lastLogin' AND " . TABLE_CONFIG . ".`key` = 'desktop' GROUP BY " . TABLE_CONFIG . ".`owner`;")->fetchAll();
|
|
if(empty($userDevices)) return true;
|
|
foreach($userDevices as $userDevice)
|
|
{
|
|
$user = $userDevice->id;
|
|
$lastLogin = $userDevice->value;
|
|
if(empty($user) || empty($lastLogin)) continue;
|
|
$userDeviceData[] = "($user,'$lastLogin','$lastLogin')";
|
|
}
|
|
if(empty($userDeviceData)) return true;
|
|
$query = "INSERT INTO `{$prefix}im_userdevice` (`user`,`lastLogin`,`lastLogout`) VALUES " . join(',', $userDeviceData);
|
|
$this->dbh->query($query);
|
|
$this->dbh->query("DELETE FROM " . TABLE_CONFIG . " WHERE `section` = 'lastLogin';");
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Drop order column from all message partition tables.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function dropOrderFromMessagePartitions()
|
|
{
|
|
$tables = $this->dbh->query("SHOW TABLES LIKE '{$this->config->db->prefix}im_message\_%'")->fetchAll();
|
|
$tables = array_filter(array_map(function($table) {
|
|
$tableName = current(array_values((array)$table));
|
|
if(!preg_match("/{$this->config->db->prefix}im_message_[a-z]+/", $tableName)) return $tableName;
|
|
}, $tables));
|
|
|
|
if(empty($tables)) return true;
|
|
|
|
$query = '';
|
|
foreach($tables as $table)
|
|
{
|
|
$query .= "ALTER TABLE `$table` DROP COLUMN `order`;";
|
|
}
|
|
$this->dbh->query($query);
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Add `index` column to all message partition tables.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function addMessageIndexColumns()
|
|
{
|
|
$prefix = $this->config->db->prefix;
|
|
$tables = $this->dbh->query("SHOW TABLES LIKE '{$prefix}im_message\_%'")->fetchAll();
|
|
$tables = array_filter(array_map(function($table) use ($prefix)
|
|
{
|
|
$tableName = current(array_values((array)$table));
|
|
if(!preg_match("/{$prefix}im_message_[a-z]+/", $tableName)) return $tableName;
|
|
},
|
|
$tables
|
|
));
|
|
if(empty($tables)) return true;
|
|
|
|
$query = '';
|
|
foreach($tables as $table) $query .= "ALTER TABLE `$table` ADD `index` int(11) unsigned DEFAULT 0 AFTER `date`;";
|
|
|
|
$this->dbh->query($query);
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Re-index messages.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function reindexMessages()
|
|
{
|
|
/** @var array[] $chatTablePairs Associations of chats and partition tables, without main table. */
|
|
$chatTablePairs = array();
|
|
|
|
ini_set('memory_limit', -1);
|
|
set_time_limit(0);
|
|
|
|
/* Fetch chat and message partition table associations. */
|
|
$chatTableData = $this->dao->select('gid,tableName')->from(TABLE_IM_CHAT_MESSAGE_INDEX)->orderBy('id_asc')->fetchAll();
|
|
foreach($chatTableData as $chatTable)
|
|
{
|
|
if(isset($chatTablePairs[$chatTable->gid]))
|
|
{
|
|
$chatTablePairs[$chatTable->gid][] = $chatTable->tableName;
|
|
continue;
|
|
}
|
|
$chatTablePairs[$chatTable->gid] = array($chatTable->tableName);
|
|
}
|
|
|
|
/* Append all non-partitioned chats. */
|
|
$allChats = $this->dao->select('gid')->from(TABLE_IM_CHAT)->fetchPairs();
|
|
$nonPartitionedChats = array_diff(array_values($allChats), array_keys($chatTablePairs));
|
|
foreach($nonPartitionedChats as $chat) $chatTablePairs[$chat] = array();
|
|
|
|
/* Do index. */
|
|
foreach($chatTablePairs as $chat => $tables)
|
|
{
|
|
$result = $this->doIndex($chat, $tables);
|
|
if(!$result) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Index messages of chat in partition tables and main table.
|
|
*
|
|
* @param string $chat
|
|
* @param array $tables
|
|
* @return bool
|
|
*/
|
|
public function doIndex($chat, $tables)
|
|
{
|
|
$messageIndex = 0;
|
|
$tables[] = str_replace('`', '', TABLE_IM_MESSAGE);
|
|
foreach($tables as $table)
|
|
{
|
|
$idIndices = array();
|
|
|
|
$ids = $this->dao->select('id')->from("`$table`")->where('cgid')->eq($chat)->fetchAll('id');
|
|
$ids = array_keys($ids);
|
|
if(empty($ids)) continue;
|
|
|
|
for($index = 1; $index <= count($ids); $index++) $idIndices[$ids[$index - 1]] = $index + $messageIndex;
|
|
|
|
$queryData = array();
|
|
foreach($idIndices as $id => $index) $queryData[] = "WHEN $id THEN $index";
|
|
|
|
$query = "UPDATE `$table` SET `index` = (CASE `id` " . join(' ', $queryData) . " END) WHERE `id` IN(" . join(',', $ids) . ");";
|
|
$this->dao->query($query);
|
|
|
|
$messageIndex = max(array_values($idIndices));
|
|
}
|
|
$this->dao->update(TABLE_IM_CHAT)->set('lastMessageIndex')->eq($messageIndex)->where('gid')->eq($chat)->exec();
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Set lastReadMessageIndex into table im_chatuser.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function populateLastReadMessageIndex()
|
|
{
|
|
$lastReadMessages = $this->dao->select('lastReadMessage')->from(TABLE_IM_CHATUSER)->where('lastReadMessage')->ne(0)->fetchAll('lastReadMessage');
|
|
$lastReadMessages = array_keys($lastReadMessages);
|
|
if(empty($lastReadMessages)) return true;
|
|
|
|
ini_set('memory_limit', -1);
|
|
set_time_limit(0);
|
|
|
|
$messages = $this->loadModel('im')->messageGetList('', $lastReadMessages, null, '', '', false);
|
|
if(empty($messages)) return;
|
|
|
|
$queryData = array();
|
|
foreach($messages as $message) $queryData[] = "WHEN {$message->id} THEN {$message->index}";
|
|
|
|
$query = "UPDATE " . TABLE_IM_CHATUSER . " SET `lastReadMessageIndex` = (CASE `lastReadMessage` " . join(' ', $queryData) . " END) WHERE `id` IN(" . join(',', $lastReadMessages) . ");";
|
|
$this->dao->query($query);
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Set index range for chats in chat partition index table.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function setPartitionedMessageIndex()
|
|
{
|
|
ini_set('memory_limit', -1);
|
|
set_time_limit(0);
|
|
|
|
/* Fetch chat and message partition table associations with message range. */
|
|
$chatTableData = $this->dao->select('gid, tableName, start, end')->from(TABLE_IM_CHAT_MESSAGE_INDEX)
|
|
->where('startIndex')->eq(0)
|
|
->orWhere('endIndex')->eq(0)
|
|
->orderBy('id_asc')
|
|
->fetchAll();
|
|
|
|
/* Sort ranges by table. */
|
|
$tableRanges = array();
|
|
foreach($chatTableData as $chatTable)
|
|
{
|
|
if(isset($tableRanges[$chatTable->tableName]))
|
|
{
|
|
$tableRanges[$chatTable->tableName]->start[] = $chatTable->start;
|
|
$tableRanges[$chatTable->tableName]->end[] = $chatTable->end;
|
|
continue;
|
|
}
|
|
$tableRanges[$chatTable->tableName] = (object)array('start' => array($chatTable->start), 'end' => array($chatTable->end));
|
|
}
|
|
|
|
/* Query corresponding message indice. */
|
|
foreach($tableRanges as $tableName => $tableRange)
|
|
{
|
|
$ids = array_merge($tableRange->start, $tableRange->end);
|
|
$ids = array_unique($ids);
|
|
$indexPairs = $this->dao->select('id, `index`')->from("`$tableName`")
|
|
->where('id')->in($ids)
|
|
->fetchPairs('id');
|
|
$tableRanges[$tableName]->indexPairs = $indexPairs;
|
|
}
|
|
|
|
/* Set startIndice and endIndice. */
|
|
foreach($tableRanges as $tableRange)
|
|
{
|
|
$queryData = array();
|
|
foreach($tableRange->start as $id) $queryData[] = "WHEN $id THEN {$tableRange->indexPairs[$id]}";
|
|
$query = "UPDATE " . TABLE_IM_CHAT_MESSAGE_INDEX . " SET `startIndex` = (CASE `start` " . join(' ', $queryData) . " END) WHERE `start` IN(" . join(',', $tableRange->start) . ");";
|
|
$this->dao->query($query);
|
|
|
|
$queryData = array();
|
|
foreach($tableRange->end as $id) $queryData[] = "WHEN $id THEN {$tableRange->indexPairs[$id]}";
|
|
$query = "UPDATE " . TABLE_IM_CHAT_MESSAGE_INDEX . " SET `endIndex` = (CASE `end` " . join(' ', $queryData) . " END) WHERE `end` IN(" . join(',', $tableRange->end) . ");";
|
|
$this->dao->query($query);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fix chats without lastReadMessage.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function fixChatsWithoutLastRead()
|
|
{
|
|
$zeroLastReadChats = $this->dao->select('cgid')->from(TABLE_IM_CHATUSER)->where('lastReadMessage')->eq(0)->fetchAll('cgid');
|
|
$zeroLastReadChats = array_keys($zeroLastReadChats);
|
|
if(empty($zeroLastReadChats)) return true;
|
|
|
|
ini_set('memory_limit', -1);
|
|
set_time_limit(0);
|
|
|
|
$lastMessages = $this->dao->select('MAX(`index`), cgid')->from(TABLE_IM_MESSAGE)->where('cgid')->in($zeroLastReadChats)->groupBy('cgid')->fetchAll('cgid');
|
|
if(empty($lastMessages)) return true;
|
|
|
|
$maxIndex = 'MAX(`index`)';
|
|
$queryData = array();
|
|
foreach($lastMessages as $cgid => $lastMessage) $queryData[] = "WHEN '{$cgid}' THEN {$lastMessage->$maxIndex}";
|
|
|
|
$query = "UPDATE " . TABLE_IM_CHATUSER . " SET `lastReadMessageIndex` = (CASE `cgid` " . join(' ', $queryData) . " END) WHERE `cgid` IN('" . join("','", array_keys($lastMessages)) . "');";
|
|
$this->dao->query($query);
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/*
|
|
*Transfer chat groups if users were deleted
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function transferDeletedUserGroups()
|
|
{
|
|
$deletedUsers = $this->dao->select('id')
|
|
->from(TABLE_USER)
|
|
->where('deleted')->eq('1')
|
|
->fetchAll();
|
|
if(!empty($deletedUsers))
|
|
{
|
|
$this->loadModel('im');
|
|
foreach($deletedUsers as $user)
|
|
{
|
|
$this->im->chatTransferAllFromUser($user->id);
|
|
}
|
|
}
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Set ownedBy for group chats without it.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function setOwnedByForGroups()
|
|
{
|
|
$this->dao->update(TABLE_IM_CHAT)->set('ownedBy = createdBy')->where('ownedBy')->eq('')->exec();
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Recover created date for chats.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function recoverCreatedDates()
|
|
{
|
|
$chats = $this->dao->select('gid, id')->from(TABLE_IM_CHAT)
|
|
->where('createdDate')->eq('0000-00-00 00:00:00')
|
|
->fetchPairs('gid');
|
|
|
|
$createdDateData = array();
|
|
|
|
/* Try query earliest message date indexed. */
|
|
$indexedMinDates = $this->dao->select('gid, MIN(startDate)')->from(TABLE_IM_CHAT_MESSAGE_INDEX)
|
|
->where('gid')->in(array_keys($chats))
|
|
->groupBy('gid')
|
|
->fetchPairs('gid');
|
|
|
|
/* Then try query earliest message date non-indexed from master table. */
|
|
$queryChats = array_diff(array_keys($chats), array_keys($indexedMinDates));
|
|
$minDates = $this->dao->select('cgid, MIN(date)')->from(TABLE_IM_MESSAGE)
|
|
->where('cgid')->in($queryChats)
|
|
->groupBy('cgid')
|
|
->fetchPairs('cgid');
|
|
|
|
$knownMinDates = array_merge($indexedMinDates, $minDates);
|
|
|
|
$remainingChats = $chats;
|
|
foreach($chats as $cgid => $cid)
|
|
{
|
|
if(isset($knownMinDates[$cgid]))
|
|
{
|
|
$createdDateData[$cid] = $knownMinDates[$cgid];
|
|
unset($remainingChats[$cgid]);
|
|
}
|
|
}
|
|
|
|
/* Use other dates for chats without messages. */
|
|
$chatDates = $this->dao->select('id, gid, editedDate, lastActiveTime, dismissDate')->from(TABLE_IM_CHAT)
|
|
->where('gid')->in(array_keys($remainingChats))
|
|
->fetchAll('gid');
|
|
$chatDates = array_map(function($chatDate)
|
|
{
|
|
$dates = array_filter(array($chatDate->editedDate, $chatDate->lastActiveTime, $chatDate->dismissDate), function($date)
|
|
{
|
|
return $date != '0000-00-00 00:00:00';
|
|
});
|
|
$minDate = min($dates);
|
|
return $minDate;
|
|
}, $chatDates);
|
|
|
|
$knownMinDates = array_merge($knownMinDates, $chatDates);
|
|
|
|
$queryData = array();
|
|
foreach($knownMinDates as $gid => $date) $queryData[] = "WHEN {$chats[$gid]} THEN '{$date}'";
|
|
|
|
$query = "UPDATE " . TABLE_IM_CHAT . " SET `createdDate` = (CASE `id` " . join(' ', $queryData) . " END) WHERE `id` IN(" . join(",", array_values($chats)) . ");";
|
|
$this->dao->query($query);
|
|
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Set mute and freeze for hidden groups.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function setMuteForHiddenGroups()
|
|
{
|
|
$this->dao->update(TABLE_IM_CHATUSER)->set('hide')->eq('0')->set('mute')->eq('1')->set('freeze')->eq('1')->where('hide')->eq('1')->andWhere('quit')->eq('0000-00-00 00:00:00')->exec();
|
|
return !dao::isError();
|
|
}
|
|
|
|
/**
|
|
* Notify users who have hide the group.
|
|
*
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function notifyGroupHiddenUsers()
|
|
{
|
|
$noticeUsers = $this->dao->select('user')->from(TABLE_IM_CHATUSER)->where('hide')->eq('1')->andWhere('quit')->eq('0000-00-00 00:00:00')->groupBy('user')->fetchAll();
|
|
$sender = new stdClass();
|
|
$sender->avatar = commonModel::getSysURL() . '/www/favicon.ico';
|
|
$sender->id = 'upgradeArchive';
|
|
$sender->realname = $this->lang->upgrade->archiveChangeNoticeTitle;
|
|
$this->loadModel('im')->messageCreateNotify(array_keys($noticeUsers), '', '', $this->lang->upgrade->archiveChangeNoticeContent, 'text', '', array(), $sender);
|
|
return !dao::isError();
|
|
}
|