Renamed WCF to WSC / Removed obsolete phpdoc tags
[GitHub/WoltLab/com.woltlab.wcf.conversation.git] / files / lib / system / clipboard / action / ConversationClipboardAction.class.php
1 <?php
2 namespace wcf\system\clipboard\action;
3 use wcf\data\clipboard\action\ClipboardAction;
4 use wcf\data\conversation\Conversation;
5 use wcf\data\conversation\ConversationAction;
6 use wcf\system\database\util\PreparedStatementConditionBuilder;
7 use wcf\system\WCF;
8
9 /**
10 * Prepares clipboard editor items for conversations.
11 *
12 * @author Alexander Ebert
13 * @copyright 2001-2016 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15 * @package WoltLabSuite\Core\System\Clipboard\Action
16 */
17 class ConversationClipboardAction extends AbstractClipboardAction {
18 /**
19 * @inheritDoc
20 */
21 protected $actionClassActions = ['close', 'markAsRead', 'open'];
22
23 /**
24 * list of conversations
25 * @var Conversation[]
26 */
27 public $conversations = null;
28
29 /**
30 * @inheritDoc
31 */
32 protected $supportedActions = ['assignLabel', 'close', 'leave', 'leavePermanently', 'markAsRead', 'open', 'restore'];
33
34 /**
35 * @inheritDoc
36 */
37 public function execute(array $objects, ClipboardAction $action) {
38 if ($this->conversations === null) {
39 // validate conversations
40 $this->validateParticipation($objects);
41 }
42
43 // check if no conversation was accessible
44 if (empty($this->conversations)) {
45 return null;
46 }
47
48 $item = parent::execute($objects, $action);
49
50 if ($item === null) {
51 return null;
52 }
53
54 switch ($action->actionName) {
55 case 'assignLabel':
56 // check if user has labels
57 $sql = "SELECT COUNT(*) AS count
58 FROM wcf".WCF_N."_conversation_label
59 WHERE userID = ?";
60 $statement = WCF::getDB()->prepareStatement($sql);
61 $statement->execute([WCF::getUser()->userID]);
62 $row = $statement->fetchArray();
63 if ($row['count'] == 0) {
64 return null;
65 }
66
67 $item->addParameter('objectIDs', array_keys($this->conversations));
68 break;
69
70 case 'leave':
71 $item->addInternalData('parameters', ['hideConversation' => 1]);
72 $item->addParameter('actionName', 'hideConversation');
73 $item->addParameter('className', $this->getClassName());
74 break;
75
76 case 'leavePermanently':
77 $item->addParameter('objectIDs', array_keys($this->conversations));
78 $item->addInternalData('parameters', ['hideConversation' => 2]);
79 $item->addParameter('actionName', 'hideConversation');
80 $item->addParameter('className', $this->getClassName());
81 break;
82
83 case 'markAsRead':
84 $item->addParameter('objectIDs', array_keys($this->conversations));
85 $item->addParameter('actionName', 'markAsRead');
86 $item->addParameter('className', $this->getClassName());
87 $item->addInternalData('confirmMessage', WCF::getLanguage()->getDynamicVariable('wcf.clipboard.item.com.woltlab.wcf.conversation.conversation.markAsRead.confirmMessage', [
88 'count' => $item->getCount()
89 ]));
90 break;
91
92 case 'restore':
93 $item->addInternalData('parameters', ['hideConversation' => 0]);
94 $item->addParameter('actionName', 'hideConversation');
95 $item->addParameter('className', $this->getClassName());
96 break;
97 }
98
99 return $item;
100 }
101
102 /**
103 * @inheritDoc
104 */
105 public function getClassName() {
106 return ConversationAction::class;
107 }
108
109 /**
110 * @inheritDoc
111 */
112 public function getTypeName() {
113 return 'com.woltlab.wcf.conversation.conversation';
114 }
115
116 /**
117 * Returns a list of conversations with user participation.
118 *
119 * @param Conversation[] $conversations
120 * @return Conversation[]
121 */
122 protected function validateParticipation(array $conversations) {
123 $conversationIDs = [];
124
125 // validate ownership
126 foreach ($conversations as $conversation) {
127 if ($conversation->userID != WCF::getUser()->userID) {
128 $conversationIDs[] = $conversation->conversationID;
129 }
130 }
131
132 // validate participation as non-owner
133 if (!empty($conversationIDs)) {
134 $conditions = new PreparedStatementConditionBuilder();
135 $conditions->add("conversationID IN (?)", [$conversationIDs]);
136 $conditions->add("participantID = ?", [WCF::getUser()->userID]);
137
138 $sql = "SELECT conversationID
139 FROM wcf".WCF_N."_conversation_to_user
140 ".$conditions;
141 $statement = WCF::getDB()->prepareStatement($sql);
142 $statement->execute($conditions->getParameters());
143 while (($row = $statement->fetchArray())) {
144 $index = array_search($row['conversationID'], $conversationIDs);
145 unset($conversationIDs[$index]);
146 }
147
148 // remove unaccessible conversations
149 if (!empty($conversationIDs)) {
150 foreach ($conversations as $index => $conversation) {
151 if (in_array($conversation->conversationID, $conversationIDs)) {
152 unset($conversations[$index]);
153 }
154 }
155 }
156 }
157
158 foreach ($conversations as $conversation) {
159 $this->conversations[$conversation->conversationID] = $conversation;
160 }
161 }
162
163 /**
164 * Validates if user may close the given conversations.
165 *
166 * @return integer[]
167 */
168 protected function validateClose() {
169 $conversationIDs = [];
170
171 foreach ($this->conversations as $conversation) {
172 if (!$conversation->isClosed && $conversation->userID == WCF::getUser()->userID) {
173 $conversationIDs[] = $conversation->conversationID;
174 }
175 }
176
177 return $conversationIDs;
178 }
179
180 /**
181 * Validates conversations available for leaving.
182 *
183 * @return integer[]
184 */
185 public function validateLeave() {
186 $tmpIDs = [];
187 foreach ($this->conversations as $conversation) {
188 $tmpIDs[] = $conversation->conversationID;
189 }
190
191 $conditions = new PreparedStatementConditionBuilder();
192 $conditions->add("conversationID IN (?)", [$tmpIDs]);
193 $conditions->add("participantID = ?", [WCF::getUser()->userID]);
194 $conditions->add("hideConversation <> ?", [1]);
195
196 $sql = "SELECT conversationID
197 FROM wcf".WCF_N."_conversation_to_user
198 ".$conditions;
199 $statement = WCF::getDB()->prepareStatement($sql);
200 $statement->execute($conditions->getParameters());
201
202 return $statement->fetchAll(\PDO::FETCH_COLUMN);
203 }
204
205 /**
206 * Validates conversations applicable for mark as read.
207 *
208 * @return integer[]
209 */
210 public function validateMarkAsRead() {
211 $conversationIDs = [];
212
213 $conditions = new PreparedStatementConditionBuilder();
214 $conditions->add("conversationID IN (?)", [array_keys($this->conversations)]);
215 $conditions->add("participantID = ?", [WCF::getUser()->userID]);
216
217 $sql = "SELECT conversationID, lastVisitTime
218 FROM wcf".WCF_N."_conversation_to_user
219 ".$conditions;
220 $statement = WCF::getDB()->prepareStatement($sql);
221 $statement->execute($conditions->getParameters());
222 $lastVisitTime = [];
223 while (($row = $statement->fetchArray())) {
224 $lastVisitTime[$row['conversationID']] = $row['lastVisitTime'];
225 }
226
227 foreach ($this->conversations as $conversation) {
228 if (isset($lastVisitTime[$conversation->conversationID]) && $lastVisitTime[$conversation->conversationID] < $conversation->lastPostTime) {
229 $conversationIDs[] = $conversation->conversationID;
230 }
231 }
232
233 return $conversationIDs;
234 }
235
236 /**
237 * Validates if user may open the given conversations.
238 *
239 * @return integer[]
240 */
241 protected function validateOpen() {
242 $conversationIDs = [];
243
244 foreach ($this->conversations as $conversation) {
245 if ($conversation->isClosed && $conversation->userID == WCF::getUser()->userID) {
246 $conversationIDs[] = $conversation->conversationID;
247 }
248 }
249
250 return $conversationIDs;
251 }
252
253 /**
254 * Validates conversations available for restore.
255 *
256 * @return integer[]
257 */
258 public function validateRestore() {
259 $tmpIDs = [];
260 foreach ($this->conversations as $conversation) {
261 $tmpIDs[] = $conversation->conversationID;
262 }
263
264 $conditions = new PreparedStatementConditionBuilder();
265 $conditions->add("conversationID IN (?)", [$tmpIDs]);
266 $conditions->add("participantID = ?", [WCF::getUser()->userID]);
267 $conditions->add("hideConversation <> ?", [0]);
268
269 $sql = "SELECT conversationID
270 FROM wcf".WCF_N."_conversation_to_user
271 ".$conditions;
272 $statement = WCF::getDB()->prepareStatement($sql);
273 $statement->execute($conditions->getParameters());
274
275 return $statement->fetchAll(\PDO::FETCH_COLUMN);
276 }
277 }