1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Integration system for attachments into Post controller |
5
|
|
|
* |
6
|
|
|
* @package ElkArte Forum |
7
|
|
|
* @copyright ElkArte Forum contributors |
8
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
9
|
|
|
* |
10
|
|
|
* This file contains code covered by: |
11
|
|
|
* copyright: 2011 Simple Machines (http://www.simplemachines.org) |
12
|
|
|
* |
13
|
|
|
* @version 2.0 dev |
14
|
|
|
* |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
namespace ElkArte\Modules\Attachments; |
18
|
|
|
|
19
|
|
|
use ElkArte\Attachments\TemporaryAttachment; |
20
|
|
|
use ElkArte\Attachments\TemporaryAttachmentProcess; |
21
|
|
|
use ElkArte\Attachments\TemporaryAttachmentsList; |
22
|
|
|
use ElkArte\Errors\AttachmentErrorContext; |
23
|
|
|
use ElkArte\Errors\ErrorContext; |
24
|
|
|
use ElkArte\EventManager; |
25
|
|
|
use ElkArte\Helper\FileFunctions; |
26
|
|
|
use ElkArte\Modules\AbstractModule; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Class Attachments_Post_Module |
30
|
|
|
*/ |
31
|
|
|
class Post extends AbstractModule |
32
|
|
|
{ |
33
|
|
|
/** @var int The mode of attachments (disabled/enabled/show only). */ |
34
|
|
|
protected static $_attach_level = 0; |
35
|
|
|
|
36
|
|
|
/** @var AttachmentErrorContext The objects that keeps track of errors. */ |
37
|
|
|
protected $_attach_errors; |
38
|
|
|
|
39
|
|
|
/** @var int[] List of attachments ID already saved. */ |
40
|
|
|
protected $_saved_attach_id = []; |
41
|
|
|
|
42
|
|
|
/** @var bool If it is a new message or if it is an existing one edited. */ |
43
|
|
|
protected $_is_new_message = false; |
44
|
|
|
|
45
|
|
|
/** @var bool If temporary attachments should be ignored or not */ |
46
|
|
|
protected $ignore_temp = false; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* {@inheritDoc} |
50
|
|
|
*/ |
51
|
|
|
public static function hooks(EventManager $eventsManager) |
52
|
|
|
{ |
53
|
|
|
global $modSettings; |
54
|
|
|
|
55
|
|
|
if (!empty($modSettings['attachmentEnable'])) |
56
|
|
|
{ |
57
|
|
|
self::$_attach_level = (int) $modSettings['attachmentEnable']; |
58
|
|
|
|
59
|
|
|
return [ |
60
|
|
|
['prepare_post', [Post::class, 'prepare_post'], []], |
61
|
|
|
['prepare_context', [Post::class, 'prepare_context'], ['post_errors']], |
62
|
|
|
['finalize_post_form', [Post::class, 'finalize_post_form'], ['show_additional_options', 'board', 'topic']], |
63
|
|
|
['prepare_save_post', [Post::class, 'prepare_save_post'], ['post_errors']], |
64
|
|
|
['pre_save_post', [Post::class, 'pre_save_post'], ['msgOptions']], |
65
|
|
|
['after_save_post', [Post::class, 'after_save_post'], ['msgOptions']], |
66
|
|
|
]; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
return []; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Get the error handler ready for post attachments |
74
|
|
|
*/ |
75
|
|
|
public function prepare_post() |
76
|
|
|
{ |
77
|
|
|
$this->_initErrors(); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Set and activate the attachment error instance |
82
|
|
|
*/ |
83
|
|
|
protected function _initErrors() |
84
|
|
|
{ |
85
|
|
|
if ($this->_attach_errors === null) |
86
|
|
|
{ |
87
|
|
|
$this->_attach_errors = AttachmentErrorContext::context(); |
88
|
|
|
|
89
|
|
|
$this->_attach_errors->activate(); |
90
|
|
|
} |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Set up the errors for the template etc |
95
|
|
|
* |
96
|
|
|
* @param ErrorContext $post_errors |
97
|
|
|
*/ |
98
|
|
|
public function prepare_context($post_errors) |
99
|
|
|
{ |
100
|
|
|
global $context; |
101
|
|
|
|
102
|
|
|
// An array to hold all the attachments for this topic. |
103
|
|
|
$context['attachments']['current'] = []; |
104
|
|
|
|
105
|
|
|
if ($this->_attach_errors->hasErrors()) |
106
|
|
|
{ |
107
|
|
|
$post_errors->addError(['attachments_errors' => $this->_attach_errors]); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* This does lots of stuff, yes it does, in fact so much that trying to document a method like this |
113
|
|
|
* would be insane. What needs to be done, is fix this bowl of spaghetti. |
114
|
|
|
* |
115
|
|
|
* What it does: |
116
|
|
|
* |
117
|
|
|
* - Infuriates anyone trying to read the code or follow the execution path |
118
|
|
|
* - Causes hallucinations and sleepless nights |
119
|
|
|
* - Known to induce binge drinking |
120
|
|
|
* |
121
|
|
|
* @param bool $show_additional_options |
122
|
|
|
* @param int $board |
123
|
|
|
* @param int $topic |
124
|
|
|
*/ |
125
|
|
|
public function finalize_post_form(&$show_additional_options, $board, $topic) |
126
|
|
|
{ |
127
|
|
|
global $txt, $context, $modSettings; |
128
|
|
|
|
129
|
|
|
$context['attachments']['can']['post'] = self::$_attach_level === 1 && (allowedTo('post_attachment') || ($modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'))); |
130
|
|
|
$context['attachments']['ila_enabled'] = !empty($modSettings['attachment_inline_enabled']); |
131
|
|
|
|
132
|
|
|
// If you can't use attachments, this is easy |
133
|
|
|
if ($context['attachments']['can']['post'] === false) |
134
|
|
|
{ |
135
|
|
|
return; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
// Calculate the total size and number of attachments. |
139
|
|
|
$attachments = $this->_getCurrentSize(); |
140
|
|
|
|
141
|
|
|
// A bit of housekeeping first. |
142
|
|
|
$tmp_attachments = new TemporaryAttachmentsList(); |
143
|
|
|
if ($tmp_attachments->count() === 1) |
144
|
|
|
{ |
145
|
|
|
$tmp_attachments->unset(); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
// Adding/removing attachments to a new or existing post |
149
|
|
|
if ($tmp_attachments->hasAttachments()) |
150
|
|
|
{ |
151
|
|
|
// Is this a request to delete them? |
152
|
|
|
if (isset($_GET['delete_temp'])) |
153
|
|
|
{ |
154
|
|
|
$tmp_attachments->removeAll($this->user->id); |
|
|
|
|
155
|
|
|
$tmp_attachments->unset(); |
156
|
|
|
$this->_attach_errors->addError('temp_attachments_gone'); |
157
|
|
|
} |
158
|
|
|
// Hmm, coming in fresh and there are files in session. |
159
|
|
|
elseif ($context['current_action'] !== 'post2' || !empty($this->_req->getPost('from_qr'))) |
|
|
|
|
160
|
|
|
{ |
161
|
|
|
$this->_determineExistingFate($tmp_attachments, $board, $topic); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
// Process new attachments, skipping over existing |
165
|
|
|
if (!isset($context['ignore_temp_attachments']) && $tmp_attachments->getPostParam('files') === null) |
166
|
|
|
{ |
167
|
|
|
if ($tmp_attachments->hasSystemError()) |
168
|
|
|
{ |
169
|
|
|
if ($context['current_action'] !== 'post2') |
170
|
|
|
{ |
171
|
|
|
$txt['error_attach_initial_error'] = $txt['attach_no_upload'] . '<div class="attachmenterrors">' . $tmp_attachments->getSystemError() . '</div>'; |
172
|
|
|
$this->_attach_errors->addError('attach_initial_error'); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
$tmp_attachments->unset(); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
$prefix = $tmp_attachments->getTplName($this->user->id, ''); |
179
|
|
|
|
180
|
|
|
/** @var TemporaryAttachment $attachment */ |
181
|
|
|
foreach ($tmp_attachments as $attachID => $attachment) |
182
|
|
|
{ |
183
|
|
|
// Initial errors (such as missing directory), we can recover |
184
|
|
|
if ($attachID !== 'initial_error' && strpos($attachID, (string) $prefix) === false) |
185
|
|
|
{ |
186
|
|
|
continue; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
// Show any errors which might have occurred. |
190
|
|
|
if ($attachment->hasErrors()) |
191
|
|
|
{ |
192
|
|
|
if ($context['current_action'] !== 'post2') |
193
|
|
|
{ |
194
|
|
|
$txt['error_attach_errors'] = empty($txt['error_attach_errors']) ? '<br />' : ''; |
195
|
|
|
$txt['error_attach_errors'] .= sprintf($txt['attach_warning'], $attachment->getName()) . '<div class="attachmenterrors">'; |
196
|
|
|
foreach ($attachment->getErrors() as $error) |
197
|
|
|
{ |
198
|
|
|
$txt['error_attach_errors'] .= (is_array($error) ? vsprintf($txt[$error[0]], $error[1]) : $txt[$error]) . '<br />'; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
$txt['error_attach_errors'] .= '</div>'; |
202
|
|
|
$this->_attach_errors->addError('attach_errors'); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
// Take out the trash. |
206
|
|
|
$tmp_attachments->removeById($attachID, false); |
207
|
|
|
|
208
|
|
|
continue; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
// More housekeeping. |
212
|
|
|
if ($attachment->fileExists() === false) |
213
|
|
|
{ |
214
|
|
|
$tmp_attachments->removeById($attachID, false); |
215
|
|
|
continue; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
$attachments['quantity']++; |
219
|
|
|
$attachments['total_size'] += $attachment['size']; |
220
|
|
|
|
221
|
|
|
if (!isset($context['files_in_session_warning'])) |
222
|
|
|
{ |
223
|
|
|
$context['files_in_session_warning'] = $txt['attached_files_in_session']; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
$context['attachments']['current'][] = [ |
227
|
|
|
'name' => '<span class="underline">' . htmlspecialchars($attachment['name'], ENT_COMPAT, 'UTF-8') . '</span>', |
228
|
|
|
'size' => $attachment['size'], |
229
|
|
|
'id' => $attachment['public_attachid'], |
230
|
|
|
'unchecked' => false, |
231
|
|
|
'approved' => 1, |
232
|
|
|
]; |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
// If there are attachment errors. Let's show a list to the user. |
238
|
|
|
if ($this->_attach_errors->hasErrors()) |
239
|
|
|
{ |
240
|
|
|
theme()->getTemplates()->load('Errors'); |
241
|
|
|
|
242
|
|
|
$errors = $this->_attach_errors->prepareErrors(); |
243
|
|
|
|
244
|
|
|
foreach ($errors as $key => $error) |
245
|
|
|
{ |
246
|
|
|
$context['attachment_error_keys'][] = $key . '_error'; |
247
|
|
|
$context[$key . '_error'] = $error; |
248
|
|
|
} |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
// If they've unchecked an attachment, they may still want to attach that many |
252
|
|
|
// more files, but don't allow more than num_allowed_attachments. |
253
|
|
|
$context['attachments']['num_allowed'] = empty($modSettings['attachmentNumPerPostLimit']) ? 50 : min($modSettings['attachmentNumPerPostLimit'] - count($context['attachments']['current']), $modSettings['attachmentNumPerPostLimit']); |
254
|
|
|
$context['attachments']['can']['post_unapproved'] = allowedTo('post_attachment'); |
255
|
|
|
$context['attachments']['total_size'] = $attachments['total_size'] ?? 0; |
256
|
|
|
$context['attachments']['quantity'] = $attachments['quantity'] ?? 0; |
257
|
|
|
$context['attachments']['restrictions'] = []; |
258
|
|
|
if (!empty($modSettings['attachmentCheckExtensions'])) |
259
|
|
|
{ |
260
|
|
|
$context['attachments']['allowed_extensions'] = strtr(strtolower($modSettings['attachmentExtensions']), [',' => ', ']); |
261
|
|
|
} |
262
|
|
|
else |
263
|
|
|
{ |
264
|
|
|
$context['attachments']['allowed_extensions'] = ''; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
$context['attachments']['template'] = 'template_add_new_attachments'; |
268
|
|
|
|
269
|
|
|
$attachmentRestrictionTypes = ['attachmentNumPerPostLimit', 'attachmentPostLimit', 'attachmentSizeLimit']; |
270
|
|
|
foreach ($attachmentRestrictionTypes as $type) |
271
|
|
|
{ |
272
|
|
|
if (!empty($modSettings[$type])) |
273
|
|
|
{ |
274
|
|
|
$context['attachments']['restrictions'][] = $type === 'attachmentNumPerPostLimit' |
275
|
|
|
? sprintf($txt['attach_restrict_' . $type], comma_format($modSettings[$type], 0)) |
276
|
|
|
: sprintf($txt['attach_restrict_' . $type], byte_format($modSettings[$type] * 1024)); |
277
|
|
|
|
278
|
|
|
// Show some numbers. |
279
|
|
|
if ($type === 'attachmentNumPerPostLimit') |
280
|
|
|
{ |
281
|
|
|
$context['attachments']['restrictions'][] = sprintf($txt['attach_remaining'], '<span id="' . $type . '">' . ($modSettings['attachmentNumPerPostLimit'] - $attachments['quantity']) . '</span>'); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
if ($type === 'attachmentPostLimit') |
285
|
|
|
{ |
286
|
|
|
$context['attachments']['restrictions'][] = sprintf($txt['attach_available'], '<span id="' . $type . '">' . byte_format(max(($modSettings['attachmentPostLimit'] * 1024) - $attachments['total_size'], 0)) . '</span>'); |
287
|
|
|
} |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
$show_additional_options = $show_additional_options || $tmp_attachments->hasPostData(); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* Sets up the current number of attachment files and size. Will account |
296
|
|
|
* for any that are currently in session |
297
|
|
|
* |
298
|
|
|
* @return array |
299
|
|
|
*/ |
300
|
|
|
private function _getCurrentSize() |
301
|
|
|
{ |
302
|
|
|
global $context; |
303
|
|
|
|
304
|
|
|
$attachments = []; |
305
|
|
|
$attachments['total_size'] = 0; |
306
|
|
|
$attachments['quantity'] = 0; |
307
|
|
|
|
308
|
|
|
// If this isn't a new post, check the current attachments. |
309
|
|
|
if (isset($_REQUEST['msg'])) |
310
|
|
|
{ |
311
|
|
|
$attachments['quantity'] = count($context['attachments']['current']); |
312
|
|
|
foreach ($context['attachments']['current'] as $attachment) |
313
|
|
|
{ |
314
|
|
|
$attachments['total_size'] += $attachment['size']; |
315
|
|
|
} |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
return $attachments; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* If we have loose attachments, this will determine where they best belong and |
323
|
|
|
* provides the proper action for the user to deal with them. |
324
|
|
|
* |
325
|
|
|
* @param TemporaryAttachmentsList $tmp_attachments |
326
|
|
|
* @param int $board |
327
|
|
|
* @param int $topic |
328
|
|
|
*/ |
329
|
|
|
private function _determineExistingFate($tmp_attachments, $board, $topic) |
330
|
|
|
{ |
331
|
|
|
global $context, $txt, $scripturl; |
332
|
|
|
|
333
|
|
|
$msg = $this->_req->getRequest('msg', 'intval', ''); |
334
|
|
|
$last_msg = $this->_req->getRequest('last_msg', 'intval', ''); |
335
|
|
|
|
336
|
|
|
// Let's be nice and see if they belong here first. |
337
|
|
|
if ((empty($msg) && $tmp_attachments->belongToBoard($board)) |
338
|
|
|
|| (!empty($msg) && $tmp_attachments->belongToMsg($msg))) |
339
|
|
|
{ |
340
|
|
|
// See if any files still exist before showing the warning message and the files attached. |
341
|
|
|
if ($tmp_attachments->filesExist($this->user->id)) |
|
|
|
|
342
|
|
|
{ |
343
|
|
|
$this->_attach_errors->addError('temp_attachments_new'); |
344
|
|
|
$context['files_in_session_warning'] = $txt['attached_files_in_session']; |
345
|
|
|
} |
346
|
|
|
} |
347
|
|
|
else |
348
|
|
|
{ |
349
|
|
|
// Since, they don't belong here. Let's inform the user that they exist.. |
350
|
|
|
if (!empty($topic)) |
351
|
|
|
{ |
352
|
|
|
$delete_url = $scripturl . '?action=post' . (empty($msg) ? ('') : ';msg=' . $msg) . (empty($last_msg) ? ('') : ';last_msg=' . $last_msg) . ';topic=' . $topic . ';delete_temp'; |
353
|
|
|
} |
354
|
|
|
else |
355
|
|
|
{ |
356
|
|
|
$delete_url = $scripturl . '?action=post;board=' . $board . ';delete_temp'; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
// Compile a list of the files to show the user. |
360
|
|
|
$file_list = $tmp_attachments->getFileNames($this->user->id); |
361
|
|
|
$file_list = '<div class="attachments">' . implode('<br />', $file_list) . '</div>'; |
362
|
|
|
|
363
|
|
|
$context['ignore_temp_attachments'] = true; |
364
|
|
|
if ($tmp_attachments->areLostAttachments()) |
365
|
|
|
{ |
366
|
|
|
$this->_attach_errors->addError(['temp_attachments_lost', [$delete_url, $file_list]]); |
367
|
|
|
} |
368
|
|
|
else |
369
|
|
|
{ |
370
|
|
|
// We have a message id, so we can link back to the old topic they were trying to edit.. |
371
|
|
|
$goback_url = $scripturl . '?action=post;msg=' . $tmp_attachments->getPostParam('msg') . ($tmp_attachments->getPostParam('last_msg') === null ? '' : ';last_msg=' . $tmp_attachments->getPostParam('last_msg')) . ';topic=' . $tmp_attachments->getPostParam('topic') . ';additionalOptions'; |
372
|
|
|
$this->_attach_errors->addError(['temp_attachments_found', [$delete_url, $goback_url, $file_list]]); |
373
|
|
|
} |
374
|
|
|
} |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
/** |
378
|
|
|
* Save attachments when the post is saved |
379
|
|
|
* |
380
|
|
|
* @param ErrorContext $post_errors |
381
|
|
|
*/ |
382
|
|
|
public function prepare_save_post($post_errors) |
383
|
|
|
{ |
384
|
|
|
$this->_initErrors(); |
385
|
|
|
|
386
|
|
|
$msg = isset($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : 0; |
387
|
|
|
$this->saveAttachments($msg); |
388
|
|
|
|
389
|
|
|
if ($this->_attach_errors->hasErrors()) |
390
|
|
|
{ |
391
|
|
|
$post_errors->addError(['attachments_errors' => $this->_attach_errors]); |
392
|
|
|
} |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
/** |
396
|
|
|
* Handles both the saving and removing of attachments on post save |
397
|
|
|
* |
398
|
|
|
* @param int $msg |
399
|
|
|
*/ |
400
|
|
|
protected function saveAttachments($msg) |
401
|
|
|
{ |
402
|
|
|
global $context, $modSettings; |
403
|
|
|
|
404
|
|
|
// First check to see if they are trying to delete any current attachments. |
405
|
|
|
if (isset($_POST['attach_del'])) |
406
|
|
|
{ |
407
|
|
|
require_once(SUBSDIR . '/Attachments.subs.php'); |
408
|
|
|
$keep_temp = []; |
409
|
|
|
$keep_ids = []; |
410
|
|
|
$tmp_attachments = new TemporaryAttachmentsList(); |
411
|
|
|
$prefix = $tmp_attachments->getTplName($this->user->id, ''); |
|
|
|
|
412
|
|
|
|
413
|
|
|
foreach ($_POST['attach_del'] as $public_id) |
414
|
|
|
{ |
415
|
|
|
$attachID = $tmp_attachments->getIdFromPublic($public_id); |
416
|
|
|
|
417
|
|
|
if (strpos($attachID, (string) $prefix) !== false) |
418
|
|
|
{ |
419
|
|
|
$keep_temp[] = $attachID; |
420
|
|
|
} |
421
|
|
|
else |
422
|
|
|
{ |
423
|
|
|
$keep_ids[] = (int) $attachID; |
424
|
|
|
} |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
$tmp_attachments->removeExcept($keep_temp, $this->user->id); |
428
|
|
|
|
429
|
|
|
// Editing a message, remove attachments they no longer wanted to keep |
430
|
|
|
if (!empty($msg)) |
431
|
|
|
{ |
432
|
|
|
require_once(SUBSDIR . '/ManageAttachments.subs.php'); |
433
|
|
|
$attachmentQuery = [ |
434
|
|
|
'attachment_type' => 0, |
435
|
|
|
'id_msg' => (int) $msg, |
436
|
|
|
'not_id_attach' => $keep_ids, |
437
|
|
|
]; |
438
|
|
|
removeAttachments($attachmentQuery); |
439
|
|
|
} |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
// Then try to upload any attachments. |
443
|
|
|
$context['attachments']['can']['post'] = self::$_attach_level === 1 && (allowedTo('post_attachment') || ($modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'))); |
444
|
|
|
if ($context['attachments']['can']['post'] && empty($this->_req->getPost('from_qr'))) |
445
|
|
|
{ |
446
|
|
|
require_once(SUBSDIR . '/Attachments.subs.php'); |
447
|
|
|
$processAttachments = new TemporaryAttachmentProcess(); |
448
|
|
|
$this->ignore_temp = $processAttachments->processAttachments((int) $msg); |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* Saves all valid attachments that were uploaded |
454
|
|
|
* |
455
|
|
|
* @param array $msgOptions |
456
|
|
|
*/ |
457
|
|
|
public function pre_save_post(&$msgOptions) |
458
|
|
|
{ |
459
|
|
|
global $context, $modSettings; |
460
|
|
|
|
461
|
|
|
$this->_is_new_message = empty($msgOptions['id']); |
462
|
|
|
$tmp_attachments = new TemporaryAttachmentsList(); |
463
|
|
|
$prefix = $tmp_attachments->getTplName($this->user->id, ''); |
|
|
|
|
464
|
|
|
|
465
|
|
|
// ...or attach a new file... |
466
|
|
|
if (empty($this->ignore_temp) |
467
|
|
|
&& $context['attachments']['can']['post'] |
468
|
|
|
&& $tmp_attachments->hasAttachments() |
469
|
|
|
&& empty($this->_req->getPost('from_qr'))) |
470
|
|
|
{ |
471
|
|
|
$this->_saved_attach_id = []; |
472
|
|
|
|
473
|
|
|
foreach ($tmp_attachments->toArray() as $attachID => $attachment) |
474
|
|
|
{ |
475
|
|
|
if ($attachID !== 'initial_error' && strpos($attachID, (string) $prefix) === false) |
476
|
|
|
{ |
477
|
|
|
continue; |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
// If there was an initial error just show that message. |
481
|
|
|
if ($attachID === 'initial_error') |
482
|
|
|
{ |
483
|
|
|
$tmp_attachments->unset(); |
484
|
|
|
break; |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
// No errors, then try to create the attachment |
488
|
|
|
if (empty($attachment['errors'])) |
489
|
|
|
{ |
490
|
|
|
// Load the attachmentOptions array with the data needed to create an attachment |
491
|
|
|
$attachmentOptions = [ |
492
|
|
|
'post' => $this->_req->getRequest('msg', 'intval', 0), |
493
|
|
|
'poster' => $this->user->id, |
494
|
|
|
'name' => $attachment['name'], |
495
|
|
|
'tmp_name' => $attachment['tmp_name'], |
496
|
|
|
'size' => $attachment['size'] ?? 0, |
497
|
|
|
'mime_type' => $attachment['type'] ?? '', |
498
|
|
|
'id_folder' => $attachment['id_folder'] ?? 0, |
499
|
|
|
'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'), |
500
|
|
|
'errors' => [], |
501
|
|
|
]; |
502
|
|
|
|
503
|
|
|
if (createAttachment($attachmentOptions)) |
504
|
|
|
{ |
505
|
|
|
$this->_saved_attach_id[] = $attachmentOptions['id']; |
506
|
|
|
if (!empty($attachmentOptions['thumb'])) |
507
|
|
|
{ |
508
|
|
|
$this->_saved_attach_id[] = $attachmentOptions['thumb']; |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
$msgOptions['body'] = preg_replace('~\[attachurl(?:.*?)]' . $attachment['public_attachid'] . '\[/attachurl]~', '[attachurl]' . $attachmentOptions['id'] . '[/attachurl]', $msgOptions['body']); |
512
|
|
|
$msgOptions['body'] = preg_replace('~\[attach(.*?)]' . $attachment['public_attachid'] . '\[/attach]~', '[attach$1]' . $attachmentOptions['id'] . '[/attach]', $msgOptions['body']); |
513
|
|
|
} |
514
|
|
|
} |
515
|
|
|
// We have errors on this file, build out the issues for display to the user |
516
|
|
|
else |
517
|
|
|
{ |
518
|
|
|
FileFunctions::instance()->delete($attachment['tmp_name']); |
519
|
|
|
} |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
// Clean up any post_tmp_.*?(_thumb)? items |
523
|
|
|
$tmp_attachments->removeAll($this->user->id); |
524
|
|
|
$tmp_attachments->unset(); |
525
|
|
|
} |
526
|
|
|
|
527
|
|
|
if (empty($this->_saved_attach_id)) |
528
|
|
|
{ |
529
|
|
|
return; |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
if ($msgOptions['icon'] !== 'xx') |
533
|
|
|
{ |
534
|
|
|
return; |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
$msgOptions['icon'] = 'clip'; |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
/** |
541
|
|
|
* Assigns saved attachments to the message id they were saved with |
542
|
|
|
* |
543
|
|
|
* @param array $msgOptions |
544
|
|
|
*/ |
545
|
|
|
public function after_save_post($msgOptions) |
546
|
|
|
{ |
547
|
|
|
if (!$this->_is_new_message) |
548
|
|
|
{ |
549
|
|
|
return; |
550
|
|
|
} |
551
|
|
|
|
552
|
|
|
if (empty($this->_saved_attach_id)) |
553
|
|
|
{ |
554
|
|
|
return; |
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
bindMessageAttachments($msgOptions['id'], $this->_saved_attach_id); |
558
|
|
|
} |
559
|
|
|
} |
560
|
|
|
|