* Namespace for conversations.
*
* @author Alexander Ebert
- * @copyright 2001-2011 WoltLab GmbH
+ * @copyright 2001-2013 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
*/
WCF.Conversation = { };
}
});
+/**
+ * Provides methods to remove participants from conversations.
+ *
+ * @see WCF.Action.Delete
+ */
+WCF.Conversation.RemoveParticipant = WCF.Action.Delete.extend({
+ /**
+ * conversation id
+ * @var integer
+ */
+ _conversationID: 0,
+
+ /**
+ * @see WCF.Action.Delete.init()
+ */
+ init: function(conversationID) {
+ this._conversationID = conversationID;
+ this._super('wcf\\data\\conversation\\ConversationAction', '.jsParticipant');
+ },
+
+ /**
+ * @see WCF.Action.Delete._sendRequest()
+ */
+ _sendRequest: function(object) {
+ this.proxy.setOption('data', {
+ actionName: 'removeParticipant',
+ className: this._className,
+ objectIDs: [ this._conversationID ],
+ parameters: {
+ userID: $(object).data('objectID')
+ }
+ });
+
+ this.proxy.sendRequest();
+ },
+
+ /**
+ * @see WCF.Action.Delete._success()
+ */
+ _success: function(data, textStatus, jqXHR) {
+ this.triggerEffect([ data.returnValues.userID ]);
+ }
+});
+
/**
* Namespace for label-related classes.
*/
);
}
+ /**
+ * Validates parameters to remove a participant from a conversation.
+ */
+ public function validateRemoveParticipant() {
+ $this->readInteger('userID');
+
+ // validate conversation
+ $this->conversation = $this->getSingleObject();
+ if (!$this->conversation->conversationID) {
+ throw new UserInputException('objectIDs');
+ }
+
+ // check ownership
+ if ($this->conversation->userID != WCF::getUser()->userID) {
+ throw new PermissionDeniedException();
+ }
+
+ // validate participants
+ if ($this->parameters['userID'] == WCF::getUser()->userID || !Conversation::isParticipant(array($this->conversation->conversationID)) || !Conversation::isParticipant(array($this->conversation->conversationID), $this->parameters['userID'])) {
+ throw new PermissionDeniedException();
+ }
+
+ }
+
+ /**
+ * 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']);
+
+ return array(
+ 'userID' => $this->parameters['userID']
+ );
+ }
+
/**
* Adds conversation modification data.
*
));
}
+ /**
+ * Removes a participant from this conversation.
+ *
+ * @param integer $userID
+ */
+ public function removeParticipant($userID) {
+ $sql = "DELETE FROM wcf".WCF_N."_conversation_to_user
+ WHERE conversationID = ?
+ AND participantID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $this->conversationID,
+ $userID
+ ));
+ }
+
/**
* Updates the participant summary of the given conversations.
*
}
unset($object);
}
+
+ /**
+ * Returns all log entries created before given point of time. Applicable entries
+ * will be returned and removed from collection.
+ *
+ * @param integer $time
+ * @return array<wcf\data\modification\log\ViewableConversationModificationLog>
+ */
+ public function getEntriesUntil($time) {
+ $entries = array();
+ foreach ($this->objects as $index => $entry) {
+ if ($entry->time < $time) {
+ $entries[] = $entry;
+ unset($this->objects[$index]);
+ }
+ }
+
+ if (!empty($entries)) {
+ $this->indexToObject = array_keys($this->objects);
+ }
+
+ return $entries;
+ }
}
<?php
namespace wcf\page;
+use wcf\data\modification\log\ConversationLogModificationLogList;
+
use wcf\data\conversation\label\ConversationLabel;
use wcf\data\conversation\message\ConversationMessage;
use wcf\data\conversation\Conversation;
public $conversationID = 0;
/**
- * conversation object
- * @var wcf\data\conversation\Conversation
+ * viewable conversation object
+ * @var wcf\data\conversation\ViewableConversation
*/
public $conversation = null;
*/
public $message = null;
+ /**
+ * modification log list object
+ * @var wcf\data\wcf\data\modification\log\ConversationLogModificationLogList
+ */
+ public $modificationLogList = null;
+
/**
* sidebar factory object
* @var wcf\system\message\sidebar\MessageSidebarFactory
'canViewPreview' => true
));
}
+
+ // get timeframe for modifications
+ $this->objectList->rewind();
+ $startTime = $this->objectList->current()->time;
+
+ $count = count($this->objectList);
+ if ($count == 1) {
+ $endTime = $startTime;
+ }
+ else {
+ $this->objectList->seek($count - 1);
+ $endTime = $this->objectList->current()->time;
+ }
+ $this->objectList->rewind();
+
+ // load modification log entries
+ $this->modificationLogList = new ConversationLogModificationLogList();
+ $this->modificationLogList->setConversation($this->conversation->getDecoratedObject());
+ $this->modificationLogList->getConditionBuilder()->add("modification_log.time BETWEEN ? AND ?", array($startTime, $endTime));
+ $this->modificationLogList->readObjects();
}
/**
WCF::getTPL()->assign(array(
'attachmentList' => $this->objectList->getAttachmentList(),
'labelList' => $this->labelList,
+ 'modificationLogList' => $this->modificationLogList,
'sidebarFactory' => $this->sidebarFactory,
'sortOrder' => $this->sortOrder,
'conversation' => $this->conversation,
<?php
namespace wcf\system\log\modification;
use wcf\data\conversation\Conversation;
+use wcf\data\user\User;
use wcf\data\user\UserList;
/**
* Handles conversation modification logs.
*
* @author Alexander Ebert
- * @copyright 2001-2012 WoltLab GmbH
+ * @copyright 2001-2013 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf.conversation
* @subpackage system.log.modification
$this->add($conversation, 'open');
}
+ /**
+ * Adds a log entry for a removed participant.
+ *
+ * @param wcf\data\conversation\Conversation $conversation
+ * @param integer $userID
+ */
+ public function removeParticipant(Conversation $conversation, $userID) {
+ $user = new User($userID);
+ $this->add($conversation, 'removeParticipant', array(
+ 'userID' => $userID,
+ 'username' => $user->username
+ ));
+ }
+
/**
* Adds a conversation modification log entry.
*
<item name="wcf.conversation.participants"><![CDATA[Teilnehmer]]></item>
<item name="wcf.conversation.participants.description"><![CDATA[Mehrere Teilnehmer können mit Komma getrennt angegeben werden.]]></item>
<item name="wcf.conversation.participants.error.mailboxIsFull"><![CDATA[{$errorData[username]} hat das zulässige Limit für Konversationen bereits erreicht und kann an keinen neuen Konversation teilnehmen.]]></item>
+ <item name="wcf.conversation.participants.removeParticipant"><![CDATA[Teilnehmer entfernen]]></item>
+ <item name="wcf.conversation.participants.removeParticipant.confirmMessage"><![CDATA[Möchten Sie „{$participant->username}“ wirklich aus dieser Konversation entfernen?]]></item>
<item name="wcf.conversation.quota"><![CDATA[Speicherplatz]]></item>
<item name="wcf.conversation.quota.description"><![CDATA[{#$conversationCount/$maxConversationCount*100}% belegt ({#$conversationCount} von {#$maxConversationCount})]]></item>
<item name="wcf.conversation.replies"><![CDATA[Antworten]]></item>
<item name="wcf.conversation.log.time"><![CDATA[Datum]]></item>
<item name="wcf.conversation.log.conversation.open"><![CDATA[Konversation geöffnet]]></item>
<item name="wcf.conversation.log.conversation.close"><![CDATA[Konversation geschlossen]]></item>
- <item name="wcf.conversation.log.conversation.addParticipants"><![CDATA[Neue Teilnehmer wurden hinzugefügt: {implode from=$additionalData[participants] item=participant}<a href="{link controller='User' id=$participant[userID] title=$participant[username]}{/link}">{$participant[username]}</a>{/implode}]]></item>
+ <item name="wcf.conversation.log.conversation.addParticipants"><![CDATA[Neue Teilnehmer wurden hinzugefügt: {implode from=$additionalData[participants] item=participant}<a href="{link controller='User' id=$participant[userID] title=$participant[username]}{/link}" class="userLink" data-user-id="{@$participant[userID]}">{$participant[username]}</a>{/implode}]]></item>
+ <item name="wcf.conversation.log.conversation.removeParticipant"><![CDATA[Ein Teilnehmer wurde entfernt: <a href="{link controller='User' id=$additionalData[userID] title=$additionalData[username]}{/link}" class="userLink" data-user-id="{@$additionalData[userID]}">{$additionalData[username]}</a>]]></item>
</category>
<category name="wcf.search">
{if !$conversation->isClosed}new WCF.Conversation.QuickReply($quoteManager);{/if}
new WCF.Moderation.Report.Content('com.woltlab.wcf.conversation.message', '.jsReportConversationMessage');
+ new WCF.Conversation.RemoveParticipant({@$conversation->conversationID});
});
//]]>
</script>
<ul class="containerBoxList tripleColumned conversationParticipantList">
{foreach from=$participants item=participant}
- <li>
+ <li class="jsParticipant">
<div class="box24">
<a href="{link controller='User' object=$participant}{/link}" class="framed">{@$participant->getAvatar()->getImageTag(24)}</a>
<hgroup>
- <h1><a href="{link controller='User' object=$participant}{/link}" class="userLink{if $participant->hideConversation == 2} conversationLeft{/if}" data-user-id="{@$participant->userID}">{$participant->username}</a>
- {if $participant->isInvisible}<small>({lang}wcf.conversation.invisible{/lang})</small>{/if}
+ <h1>
+ <a href="{link controller='User' object=$participant}{/link}" class="userLink{if $participant->hideConversation == 2} conversationLeft{/if}" data-user-id="{@$participant->userID}">{$participant->username}</a>
+ {if $participant->isInvisible}<small>({lang}wcf.conversation.invisible{/lang})</small>{/if}
+ {if ($conversation->userID == $__wcf->getUser()->userID) && ($participant->userID != $__wcf->getUser()->userID)}
+ <a class="jsDeleteButton jsTooltip" title="{lang}wcf.conversation.participants.removeParticipant{/lang}" data-confirm-message="{lang}wcf.conversation.participants.removeParticipant.confirmMessage{/lang}" data-object-id="{@$participant->userID}"><span class="icon icon16 icon-remove"></span></a>
+ {/if}
</h1>
<h2><dl class="plain inlineDataList">
<dt>{lang}wcf.conversation.lastVisitTime{/lang}</dt>
{foreach from=$objects item=message}
+ {assign var=__modificationLogTime value=$message->time}
+ {include file='conversationMessageListLog'}
+
{if !$conversation|isset && $container|isset}{assign var=conversation value=$container}{/if}
{assign var='objectID' value=$message->messageID}
{assign var='userProfile' value=$message->getUserProfile()}
</article>
</li>
{/foreach}
+
+{assign var=__modificationLogTime value=TIME_NOW}
+{include file='conversationMessageListLog'}
--- /dev/null
+{if $modificationLogList|isset}
+ {assign var=__modificationLogEntries value=$modificationLogList->getEntriesUntil($__modificationLogTime)}
+ {foreach from=$__modificationLogEntries item=modificationLogEntry}
+ <li class="marginTop jsModificationLogEntry">
+ <article class="message messageCollapsed">
+ <div class="messageHeader">
+ <div class="box24">
+ <span class="icon icon16 icon-tasks"></span>
+
+ <hgroup>
+ <h1>{@$modificationLogEntry}</h1>
+ <h2>
+ <a href="{link controller='User' id=$modificationLogEntry->userID title=$modificationLogEntry->username}{/link}" class="userLink" data-user-id="{@$modificationLogEntry->userID}">{$modificationLogEntry->username}</a>
+ -
+ {@$modificationLogEntry->time|time}
+ </h2>
+ </hgroup>
+ </div>
+ </div>
+ </article>
+ </li>
+ {/foreach}
+{/if}
\ No newline at end of file