Commit | Line | Data |
---|---|---|
18ec67a4 | 1 | <?php |
fea86294 | 2 | |
18ec67a4 | 3 | namespace wcf\system\clipboard\action; |
fea86294 | 4 | |
8191ae08 | 5 | use wcf\data\clipboard\action\ClipboardAction; |
03043c3c | 6 | use wcf\data\conversation\Conversation; |
f586b354 | 7 | use wcf\data\conversation\ConversationAction; |
18ec67a4 | 8 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
18ec67a4 AE |
9 | use 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 |
18 | class 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 | } |