1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* The functions in this file deal with sending random complaints to a moderator. |
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\Controller; |
18
|
|
|
|
19
|
|
|
use ElkArte\AbstractController; |
20
|
|
|
use ElkArte\Errors\ErrorContext; |
21
|
|
|
use ElkArte\Exceptions\Exception; |
22
|
|
|
use ElkArte\Helper\DataValidator; |
23
|
|
|
use ElkArte\Helper\Util; |
24
|
|
|
use ElkArte\Languages\Txt; |
25
|
|
|
use ElkArte\VerificationControls\VerificationControlsIntegrate; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Allows for sending topics via email |
29
|
|
|
*/ |
30
|
|
|
class Emailmoderator extends AbstractController |
31
|
|
|
{ |
32
|
|
|
/** |
33
|
|
|
* This function initializes or sets up the necessary, for the other actions |
34
|
|
|
*/ |
35
|
|
|
public function pre_dispatch() |
36
|
|
|
{ |
37
|
|
|
global $context; |
38
|
|
|
|
39
|
|
|
// Don't index anything here. |
40
|
|
|
$context['robot_no_index'] = true; |
41
|
|
|
|
42
|
|
|
// Load the template. |
43
|
|
|
theme()->getTemplates()->load('Emailmoderator'); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Default action handler |
48
|
|
|
* |
49
|
|
|
* @see AbstractController::action_index |
50
|
|
|
*/ |
51
|
|
|
public function action_index() |
52
|
|
|
{ |
53
|
|
|
// just accept we haz a default action: action_reporttm() |
54
|
|
|
$this->action_reporttm(); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Report a post to the moderator... ask for a comment. |
59
|
|
|
* |
60
|
|
|
* what is does: |
61
|
|
|
* - Gathers data from the user to report abuse to the moderator(s). |
62
|
|
|
* - Uses the ReportToModerator template, main sub template. |
63
|
|
|
* - Requires the report_any permission. |
64
|
|
|
* - Uses action_reporttm2() if post data was sent. |
65
|
|
|
* - Accessed through ?action=reporttm. |
66
|
|
|
*/ |
67
|
|
|
public function action_reporttm() |
68
|
|
|
{ |
69
|
|
|
global $txt, $modSettings, $context; |
70
|
|
|
|
71
|
|
|
$context['robot_no_index'] = true; |
72
|
|
|
|
73
|
|
|
// You can't use this if it's off or you are not allowed to do it. |
74
|
|
|
isAllowedTo('report_any'); |
75
|
|
|
|
76
|
|
|
// No errors, yet. |
77
|
|
|
$report_errors = ErrorContext::context('report', 1); |
78
|
|
|
|
79
|
|
|
// ...or maybe some. |
80
|
|
|
$context['report_error'] = [ |
81
|
|
|
'errors' => $report_errors->prepareErrors(), |
82
|
|
|
'type' => $report_errors->getErrorType() == 0 ? 'minor' : 'serious', |
83
|
|
|
]; |
84
|
|
|
|
85
|
|
|
// If they're posting, it should be processed by action_reporttm2. |
86
|
|
|
if ((isset($this->_req->post->{$context['session_var']}) || isset($this->_req->post->save)) && !$report_errors->hasErrors()) |
87
|
|
|
{ |
88
|
|
|
$this->action_reporttm2(); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
// We need a message ID to check! |
92
|
|
|
if (empty($this->_req->query->msg) && empty($this->_req->post->msg)) |
93
|
|
|
{ |
94
|
|
|
throw new Exception('no_access', false); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
// Check the message's ID - don't want anyone reporting a post that does not exist |
98
|
|
|
require_once(SUBSDIR . '/Messages.subs.php'); |
99
|
|
|
$message_id = $this->_req->getPost('msg', 'intval', isset($this->_req->query->msg) ? (int) $this->_req->query->msg : 0); |
100
|
|
|
if (basicMessageInfo($message_id, true, true) === false) |
101
|
|
|
{ |
102
|
|
|
throw new Exception('no_board', false); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
// Do we need to show the visual verification image? |
106
|
|
|
$context['require_verification'] = $this->user->is_guest && !empty($modSettings['guests_report_require_captcha']); |
|
|
|
|
107
|
|
|
if ($context['require_verification']) |
108
|
|
|
{ |
109
|
|
|
$verificationOptions = [ |
110
|
|
|
'id' => 'report', |
111
|
|
|
]; |
112
|
|
|
$context['require_verification'] = VerificationControlsIntegrate::create($verificationOptions); |
113
|
|
|
$context['visual_verification_id'] = $verificationOptions['id']; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
// Show the inputs for the comment, etc. |
117
|
|
|
Txt::load('Post'); |
118
|
|
|
Txt::load('Errors'); |
119
|
|
|
|
120
|
|
|
$context['comment_body'] = $this->_req->getPost('comment', 'trim', ''); |
121
|
|
|
$context['email_address'] = $this->_req->getPost('email', 'trim', ''); |
122
|
|
|
|
123
|
|
|
// This is here so that the user could, in theory, be redirected back to the topic. |
124
|
|
|
$context['start'] = $this->_req->query->start; |
125
|
|
|
$context['message_id'] = $message_id; |
126
|
|
|
$context['page_title'] = $txt['report_to_mod']; |
127
|
|
|
$context['sub_template'] = 'report'; |
128
|
|
|
theme()->getTemplates()->load('Emailmoderator'); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Send the emails. |
133
|
|
|
* |
134
|
|
|
* - Sends off emails to all the moderators. |
135
|
|
|
* - Sends to administrators and global moderators. (1 and 2) |
136
|
|
|
* - Called by action_reporttm(), and thus has the same permission and setting requirements as it does. |
137
|
|
|
* - Accessed through ?action=reporttm when posting. |
138
|
|
|
*/ |
139
|
|
|
public function action_reporttm2() |
140
|
|
|
{ |
141
|
|
|
global $txt, $topic, $board, $modSettings, $language, $context; |
142
|
|
|
|
143
|
|
|
// You must have the proper permissions! |
144
|
|
|
isAllowedTo('report_any'); |
145
|
|
|
|
146
|
|
|
// Make sure they aren't spamming. |
147
|
|
|
spamProtection('reporttm'); |
148
|
|
|
|
149
|
|
|
require_once(SUBSDIR . '/Mail.subs.php'); |
150
|
|
|
|
151
|
|
|
// No errors, yet. |
152
|
|
|
$report_errors = ErrorContext::context('report', 1); |
153
|
|
|
|
154
|
|
|
// Check their session. |
155
|
|
|
if (checkSession('post', '', false) != '') |
156
|
|
|
{ |
157
|
|
|
$report_errors->addError('session_timeout'); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
// Make sure we have a comment and it's clean. |
161
|
|
|
if ($this->_req->getPost('comment', '\\ElkArte\\Helper\\Util::htmltrim', '') === '') |
162
|
|
|
{ |
163
|
|
|
$report_errors->addError('no_comment'); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$poster_comment = strtr(Util::htmlspecialchars($this->_req->post->comment), ["\r" => '', "\t" => '']); |
167
|
|
|
|
168
|
|
|
if (Util::strlen($poster_comment) > 254) |
169
|
|
|
{ |
170
|
|
|
$report_errors->addError('post_too_long'); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
// Guests need to provide their address! |
174
|
|
|
if ($this->user->is_guest) |
175
|
|
|
{ |
176
|
|
|
if (!DataValidator::is_valid($this->_req->post, ['email' => 'valid_email'], ['email' => 'trim'])) |
177
|
|
|
{ |
178
|
|
|
empty($this->_req->post->email) ? $report_errors->addError('no_email') : $report_errors->addError('bad_email'); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
isBannedEmail($this->_req->post->email, 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title'])); |
182
|
|
|
|
183
|
|
|
$this->user->email = htmlspecialchars($this->_req->post->email, ENT_COMPAT, 'UTF-8'); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
// Could they get the right verification code? |
187
|
|
|
if ($this->user->is_guest && !empty($modSettings['guests_report_require_captcha'])) |
188
|
|
|
{ |
189
|
|
|
$verificationOptions = [ |
190
|
|
|
'id' => 'report', |
191
|
|
|
]; |
192
|
|
|
$context['require_verification'] = VerificationControlsIntegrate::create($verificationOptions, true); |
193
|
|
|
|
194
|
|
|
if (is_array($context['require_verification'])) |
195
|
|
|
{ |
196
|
|
|
foreach ($context['require_verification'] as $error) |
197
|
|
|
{ |
198
|
|
|
$report_errors->addError($error, 0); |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
// Any errors? |
204
|
|
|
if ($report_errors->hasErrors()) |
205
|
|
|
{ |
206
|
|
|
$this->action_reporttm(); |
207
|
|
|
|
208
|
|
|
return true; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
// Get the basic topic information, and make sure they can see it. |
212
|
|
|
$msg_id = (int) $this->_req->post->msg; |
213
|
|
|
$message = posterDetails($msg_id, $topic); |
214
|
|
|
|
215
|
|
|
if (empty($message)) |
216
|
|
|
{ |
217
|
|
|
throw new Exception('no_board', false); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
$poster_name = un_htmlspecialchars($message['real_name']) . ($message['real_name'] !== $message['poster_name'] ? ' (' . $message['poster_name'] . ')' : ''); |
221
|
|
|
$reporterName = un_htmlspecialchars($this->user->name) . ($this->user->name !== $this->user->username && $this->user->username != '' ? ' (' . $this->user->username . ')' : ''); |
222
|
|
|
$subject = un_htmlspecialchars($message['subject']); |
223
|
|
|
|
224
|
|
|
// Get a list of members with the moderate_board permission. |
225
|
|
|
require_once(SUBSDIR . '/Members.subs.php'); |
226
|
|
|
$moderators = membersAllowedTo('moderate_board', $board); |
227
|
|
|
$result = getBasicMemberData($moderators, ['preferences' => true, 'sort' => 'lngfile']); |
228
|
|
|
$mod_to_notify = []; |
229
|
|
|
foreach ($result as $row) |
230
|
|
|
{ |
231
|
|
|
if ($row['notify_types'] !== 4) |
232
|
|
|
{ |
233
|
|
|
$mod_to_notify[] = $row; |
234
|
|
|
} |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
// Check that moderators do exist! |
238
|
|
|
if (empty($mod_to_notify)) |
239
|
|
|
{ |
240
|
|
|
throw new Exception('no_mods', false); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
// If we get here, I believe we should make a record of this, for historical significance, yabber. |
244
|
|
|
if (empty($modSettings['disable_log_report'])) |
245
|
|
|
{ |
246
|
|
|
require_once(SUBSDIR . '/Messages.subs.php'); |
247
|
|
|
$message['type'] = 'msg'; |
248
|
|
|
$id_report = recordReport($message, $poster_comment); |
249
|
|
|
|
250
|
|
|
// If we're just going to ignore these, then who gives a monkeys... |
251
|
|
|
if ($id_report === false) |
252
|
|
|
{ |
253
|
|
|
redirectexit('topic=' . $topic . '.msg' . $msg_id . '#msg' . $msg_id); |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
// Find out who the real moderators are - for mod preferences. |
258
|
|
|
require_once(SUBSDIR . '/Boards.subs.php'); |
259
|
|
|
$real_mods = getBoardModerators($board, true); |
260
|
|
|
|
261
|
|
|
// Send every moderator an email. |
262
|
|
|
foreach ($mod_to_notify as $row) |
|
|
|
|
263
|
|
|
{ |
264
|
|
|
// Maybe they don't want to know?! |
265
|
|
|
if (!empty($row['mod_prefs'])) |
266
|
|
|
{ |
267
|
|
|
[, , $pref_binary] = explode('|', $row['mod_prefs']); |
268
|
|
|
if (!($pref_binary & 1) && (!($pref_binary & 2) || !in_array($row['id_member'], $real_mods))) |
269
|
|
|
{ |
270
|
|
|
continue; |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
$replacements = [ |
275
|
|
|
'TOPICSUBJECT' => $subject, |
276
|
|
|
'POSTERNAME' => $poster_name, |
277
|
|
|
'REPORTERNAME' => $reporterName, |
278
|
|
|
'TOPICLINK' => getUrl('topic', ['topic' => $topic, 'start' => 'msg' . $msg_id, 'subject' => $subject]) . '#msg' . $msg_id, |
279
|
|
|
'REPORTLINK' => empty($id_report) ? '' : getUrl('action', ['action' => 'moderate', 'area' => 'reports', 'report' => $id_report]), |
280
|
|
|
'COMMENT' => $this->_req->post->comment, |
281
|
|
|
]; |
282
|
|
|
|
283
|
|
|
$emaildata = loadEmailTemplate('report_to_moderator', $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']); |
284
|
|
|
|
285
|
|
|
// Send it to the moderator. |
286
|
|
|
sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], $this->user->email, null, false, 2); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
// Keep track of when the mod reports get updated, that way we know when we need to look again. |
290
|
|
|
updateSettings(['last_mod_report_action' => time()]); |
291
|
|
|
|
292
|
|
|
// Back to the post we reported! |
293
|
|
|
redirectexit('reportsent;topic=' . $topic . '.msg' . $msg_id . '#msg' . $msg_id); |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
|