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