/** * Removes a participant from a conversation. */ public function removeParticipant() { $this->conversation->removeParticipant($this->parameters['userID']); $this->conversation->updateParticipantSummary(); ConversationModificationLogHandler::getInstance()->removeParticipant($this->conversation->getDecoratedObject(), $this->parameters['userID']); // reset storage UserStorageHandler::getInstance()->reset(array($this->parameters['userID']), 'unreadConversationCount'); return array('userID' => $this->parameters['userID']); }
/** * @see \wcf\system\importer\IImporter::import() */ public function import($oldID, array $data, array $additionalData = array()) { $oldUserID = $data['userID']; $data['userID'] = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.user', $data['userID']); // check existing conversation if (is_numeric($oldID)) { $existingConversation = new Conversation($oldID); if (!$existingConversation->conversationID) { $data['conversationID'] = $oldID; } } $conversation = ConversationEditor::create($data); ImportHandler::getInstance()->saveNewID('com.woltlab.wcf.conversation', $oldID, $conversation->conversationID); // add author if (empty($data['isDraft'])) { ImportHandler::getInstance()->getImporter('com.woltlab.wcf.conversation.user')->import(0, array('conversationID' => $oldID, 'participantID' => $oldUserID, 'username' => $data['username'], 'hideConversation' => 0, 'isInvisible' => 0, 'lastVisitTime' => $data['time']), array('labelIDs' => array())); } return $conversation->conversationID; }
/** * Rebuilds the conversation data of the relevant conversations. */ public function rebuild() { if (empty($this->objects)) { $this->readObjects(); } // collect number of messages for each conversation $conditionBuilder = new PreparedStatementConditionBuilder(); $conditionBuilder->add('conversation_message.conversationID IN (?)', array($this->objectIDs)); $sql = "SELECT\t\tconversationID, COUNT(messageID) AS messages, SUM(attachments) AS attachments\n\t\t\tFROM\t\twcf" . WCF_N . "_conversation_message conversation_message\n\t\t\t" . $conditionBuilder . "\n\t\t\tGROUP BY\tconversationID"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditionBuilder->getParameters()); $objectIDs = array(); while ($row = $statement->fetchArray()) { if (!$row['messages']) { continue; } $objectIDs[] = $row['conversationID']; $conversationEditor = new ConversationEditor(new Conversation(null, array('conversationID' => $row['conversationID']))); $conversationEditor->update(array('attachments' => $row['attachments'], 'replies' => $row['messages'] - 1)); $conversationEditor->updateFirstMessage(); $conversationEditor->updateLastMessage(); } // delete conversations without messages $deleteConversationIDs = array_diff($this->objectIDs, $objectIDs); if (!empty($deleteConversationIDs)) { $conversationAction = new ConversationAction($deleteConversationIDs, 'delete'); $conversationAction->executeAction(); } }
/** * @see \wcf\system\worker\IWorker::execute() */ public function execute() { $this->objectList->getConditionBuilder()->add('conversation.conversationID BETWEEN ? AND ?', array($this->limit * $this->loopCount + 1, $this->limit * $this->loopCount + $this->limit)); parent::execute(); // prepare statements $sql = "SELECT\t\tmessageID, time, userID, username\n\t\t\tFROM\t\twcf" . WCF_N . "_conversation_message\n\t\t\tWHERE\t\tconversationID = ?\n\t\t\tORDER BY\ttime"; $firstMessageStatement = WCF::getDB()->prepareStatement($sql, 1); $sql = "SELECT\t\ttime, userID, username\n\t\t\tFROM\t\twcf" . WCF_N . "_conversation_message\n\t\t\tWHERE\t\tconversationID = ?\n\t\t\tORDER BY\ttime DESC"; $lastMessageStatement = WCF::getDB()->prepareStatement($sql, 1); $sql = "SELECT\tCOUNT(*) AS messages,\n\t\t\t\tSUM(attachments) AS attachments\n\t\t\tFROM\twcf" . WCF_N . "_conversation_message\n\t\t\tWHERE\tconversationID = ?"; $statsStatement = WCF::getDB()->prepareStatement($sql); $sql = "SELECT\tCOUNT(*) AS participants\n\t\t\tFROM\twcf" . WCF_N . "_conversation_to_user conversation_to_user\n\t\t\tWHERE\tconversation_to_user.conversationID = ?\n\t\t\t\tAND conversation_to_user.hideConversation <> ?\n\t\t\t\tAND conversation_to_user.participantID <> ?\n\t\t\t\tAND conversation_to_user.isInvisible = ?"; $participantCounterStatement = WCF::getDB()->prepareStatement($sql); $sql = "SELECT\t\tconversation_to_user.participantID AS userID, conversation_to_user.hideConversation, user_table.username\n\t\t\tFROM\t\twcf" . WCF_N . "_conversation_to_user conversation_to_user\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_user user_table\n\t\t\tON\t\t(user_table.userID = conversation_to_user.participantID)\n\t\t\tWHERE\t\tconversation_to_user.conversationID = ?\n\t\t\t\t\tAND conversation_to_user.participantID <> ?\n\t\t\t\t\tAND conversation_to_user.isInvisible = ?\n\t\t\tORDER BY\tuser_table.username"; $participantStatement = WCF::getDB()->prepareStatement($sql, 5); $sql = "SELECT\tCOUNT(*) AS participants\n\t\t\tFROM\twcf" . WCF_N . "_conversation_to_user\n\t\t\tWHERE\tconversationID = ?\n\t\t\t\tAND participantID IS NOT NULL"; $existingParticipantStatement = WCF::getDB()->prepareStatement($sql, 5); $obsoleteConversations = array(); foreach ($this->objectList as $conversation) { $editor = new ConversationEditor($conversation); // check for obsolete conversations $obsolete = false; if ($conversation->isDraft) { if (!$conversation->userID) { $obsolete = true; } } else { $existingParticipantStatement->execute(array($conversation->conversationID)); $row = $existingParticipantStatement->fetchSingleRow(); if (!$row['participants']) { $obsolete = true; } } if ($obsolete) { $obsoleteConversations[] = $editor; continue; } // update data $data = array(); // get first post $firstMessageStatement->execute(array($conversation->conversationID)); if (($row = $firstMessageStatement->fetchSingleRow()) !== false) { $data['firstMessageID'] = $row['messageID']; $data['lastPostTime'] = $data['time'] = $row['time']; $data['userID'] = $row['userID']; $data['username'] = $row['username']; } // get last post $lastMessageStatement->execute(array($conversation->conversationID)); if (($row = $lastMessageStatement->fetchSingleRow()) !== false) { $data['lastPostTime'] = $row['time']; $data['lastPosterID'] = $row['userID']; $data['lastPoster'] = $row['username']; } // get stats $statsStatement->execute(array($conversation->conversationID)); $row = $statsStatement->fetchSingleRow(); $data['replies'] = $row['messages'] ? $row['messages'] - 1 : 0; $data['attachments'] = $row['attachments'] ?: 0; // get number of participants $participantCounterStatement->execute(array($conversation->conversationID, Conversation::STATE_LEFT, $conversation->userID, 0)); $row = $participantCounterStatement->fetchSingleRow(); $data['participants'] = $row['participants']; // get participant summary $participantStatement->execute(array($conversation->conversationID, $conversation->userID, 0)); $users = array(); while ($row = $participantStatement->fetchArray()) { $users[] = $row; } $data['participantSummary'] = serialize($users); $editor->update($data); } // delete obsolete conversations if (!empty($obsoleteConversations)) { $action = new ConversationAction($obsoleteConversations, 'delete'); $action->executeAction(); } }
/** * @see \wcf\data\AbstractDatabaseObjectAction::create() */ public function create() { // count attachments if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) { $this->parameters['data']['attachments'] = count($this->parameters['attachmentHandler']); } if (LOG_IP_ADDRESS) { // add ip address if (!isset($this->parameters['data']['ipAddress'])) { $this->parameters['data']['ipAddress'] = WCF::getSession()->ipAddress; } } else { // do not track ip address if (isset($this->parameters['data']['ipAddress'])) { unset($this->parameters['data']['ipAddress']); } } // create message $message = parent::create(); $messageEditor = new ConversationMessageEditor($message); // get conversation $conversation = isset($this->parameters['converation']) ? $this->parameters['converation'] : new Conversation($message->conversationID); $conversationEditor = new ConversationEditor($conversation); if (empty($this->parameters['isFirstPost'])) { // update last message $conversationEditor->addMessage($message); // fire notification event if (!$conversation->isDraft) { $notificationRecipients = array_diff($conversation->getParticipantIDs(true), array($message->userID)); // don't notify message author if (!empty($notificationRecipients)) { UserNotificationHandler::getInstance()->fireEvent('conversationMessage', 'com.woltlab.wcf.conversation.message.notification', new ConversationMessageUserNotificationObject($message), $notificationRecipients); } } $userConversation = Conversation::getUserConversation($conversation->conversationID, $message->userID); if ($userConversation !== null && $userConversation->isInvisible) { // make invisible participant visible $sql = "UPDATE\twcf" . WCF_N . "_conversation_to_user\n\t\t\t\t\tSET\tisInvisible = 0\n\t\t\t\t\tWHERE\tparticipantID = ?\n\t\t\t\t\t\tAND conversationID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($message->userID, $conversation->conversationID)); $conversationEditor->updateParticipantSummary(); $conversationEditor->updateParticipantCount(); } // reset visibility if it was hidden but not left $sql = "UPDATE\twcf" . WCF_N . "_conversation_to_user\n\t\t\t\tSET\thideConversation = ?\n\t\t\t\tWHERE\tconversationID = ?\n\t\t\t\t\tAND hideConversation = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(Conversation::STATE_DEFAULT, $conversation->conversationID, Conversation::STATE_HIDDEN)); } // reset storage UserStorageHandler::getInstance()->reset($conversation->getParticipantIDs(), 'unreadConversationCount'); // update search index SearchIndexManager::getInstance()->add('com.woltlab.wcf.conversation.message', $message->messageID, $message->message, !empty($this->parameters['isFirstPost']) ? $conversation->subject : '', $message->time, $message->userID, $message->username); // update attachments if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) { $this->parameters['attachmentHandler']->updateObjectID($message->messageID); } // save embedded objects if (MessageEmbeddedObjectManager::getInstance()->registerObjects('com.woltlab.wcf.conversation.message', $message->messageID, $message->message)) { $messageEditor->update(array('hasEmbeddedObjects' => 1)); } // clear quotes if (isset($this->parameters['removeQuoteIDs']) && !empty($this->parameters['removeQuoteIDs'])) { MessageQuoteManager::getInstance()->markQuotesForRemoval($this->parameters['removeQuoteIDs']); } MessageQuoteManager::getInstance()->removeMarkedQuotes(); // return new message return $message; }
/** * Updates the participant counts of the given conversations. * * @param array<integer> $conversationIDs */ public static function updateParticipantCounts(array $conversationIDs) { $conversationList = new ConversationList(); $conversationList->getConditionBuilder()->add('conversation.conversationID IN (?)', array($conversationIDs)); $conversationList->readObjects(); foreach ($conversationList as $conversation) { $editor = new ConversationEditor($conversation); $editor->updateParticipantCount(); } }
/** * delete conversation * * @param Object $oMbqEtPc * @param Integer $mode */ public function deleteConversation($oMbqEtPc = null, $mode = null) { $oConversation = $oMbqEtPc->mbqBind['oViewableConversation']->getDecoratedObject(); $conversationEditor = new ConversationEditor($oConversation); if ($mode == 1) { $hideConversation = Conversation::STATE_HIDDEN; } elseif ($mode == 2) { $hideConversation = Conversation::STATE_LEFT; } else { MbqError::alert('', 'Need valid mode.', '', MBQ_ERR_APP); } $objectIDs = array($oMbqEtPc->convId->oriValue); //ref wcf\data\conversation\ConversationAction::hideConversation() $sql = "UPDATE\twcf" . WCF_N . "_conversation_to_user\r\n\t\t\tSET\thideConversation = ?\r\n\t\t\tWHERE\tconversationID = ?\r\n\t\t\t\tAND participantID = ?"; $statement = WCF::getDB()->prepareStatement($sql); WCF::getDB()->beginTransaction(); foreach ($objectIDs as $conversationID) { $statement->execute(array($hideConversation, $conversationID, WCF::getUser()->userID)); } WCF::getDB()->commitTransaction(); // reset user's conversation counters if user leaves conversation // permanently if ($hideConversation == Conversation::STATE_LEFT) { UserStorageHandler::getInstance()->reset(array(WCF::getUser()->userID), 'conversationCount'); UserStorageHandler::getInstance()->reset(array(WCF::getUser()->userID), 'unreadConversationCount'); } // add modification log entry if ($hideConversation == Conversation::STATE_LEFT) { ConversationModificationLogHandler::getInstance()->leave($conversationEditor->getDecoratedObject()); } // unmark items ClipboardHandler::getInstance()->unmark($objectIDs, ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.conversation.conversation')); if ($hideConversation == Conversation::STATE_LEFT) { // update participant summary ConversationEditor::updateParticipantSummaries($objectIDs); // delete conversation if all users have left it $conditionBuilder = new PreparedStatementConditionBuilder(); $conditionBuilder->add('conversation.conversationID IN (?)', array($objectIDs)); $conditionBuilder->add('conversation_to_user.conversationID IS NULL'); $conversationIDs = array(); $sql = "SELECT\t\tDISTINCT conversation.conversationID\r\n\t\t\t\tFROM\t\twcf" . WCF_N . "_conversation conversation\r\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_conversation_to_user conversation_to_user\r\n\t\t\t\tON\t\t(conversation_to_user.conversationID = conversation.conversationID AND conversation_to_user.hideConversation <> " . Conversation::STATE_LEFT . ")\r\n\t\t\t\t" . $conditionBuilder; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditionBuilder->getParameters()); while ($row = $statement->fetchArray()) { $conversationIDs[] = $row['conversationID']; } if (!empty($conversationIDs)) { $action = new ConversationAction($conversationIDs, 'delete'); $action->executeAction(); } } }