1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Part of the files dealing with preparing the content for display posts |
5
|
|
|
* via callbacks (Display, PM, Search). |
6
|
|
|
* |
7
|
|
|
* @package ElkArte Forum |
8
|
|
|
* @copyright ElkArte Forum contributors |
9
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
10
|
|
|
* |
11
|
|
|
* This file contains code covered by: |
12
|
|
|
* copyright: 2011 Simple Machines (http://www.simplemachines.org) |
13
|
|
|
* |
14
|
|
|
* @version 2.0 dev |
15
|
|
|
* |
16
|
|
|
*/ |
17
|
|
|
|
18
|
|
|
namespace ElkArte\MessagesCallback; |
19
|
|
|
|
20
|
|
|
use ElkArte\MembersList; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* DisplayRenderer |
24
|
|
|
* The class prepares the details of a message so that they can be used |
25
|
|
|
* to display it in the template. |
26
|
|
|
*/ |
27
|
|
|
class DisplayRenderer extends Renderer |
28
|
|
|
{ |
29
|
|
|
public const BEFORE_PREPARE_HOOK = 'integrate_before_prepare_display_context'; |
30
|
|
|
|
31
|
|
|
public const CONTEXT_HOOK = 'integrate_prepare_display_context'; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* {@inheritDoc} |
35
|
2 |
|
*/ |
36
|
|
|
protected function _setupPermissions() |
37
|
2 |
|
{ |
38
|
|
|
global $context, $modSettings; |
39
|
|
|
|
40
|
2 |
|
// Are you allowed to remove at least a single reply? |
41
|
|
|
$context['can_remove_post'] |= allowedTo('delete_own') |
42
|
|
|
&& (empty($modSettings['edit_disable_time']) || $this->_this_message['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()) |
43
|
2 |
|
&& (int) $this->_this_message['id_member'] === (int) $this->user->id; |
44
|
|
|
|
45
|
2 |
|
// Have you liked this post, can you? |
46
|
2 |
|
$this->_this_message['you_liked'] = !empty($context['likes'][$this->_this_message['id_msg']]['member']) |
47
|
2 |
|
&& isset($context['likes'][$this->_this_message['id_msg']]['member'][$this->user->id]); |
48
|
2 |
|
$this->_this_message['use_likes'] = allowedTo('like_posts') && empty($context['is_locked']) |
49
|
2 |
|
&& ($this->_this_message['id_member'] != $this->user->id || !empty($modSettings['likeAllowSelf'])) |
50
|
|
|
&& (empty($modSettings['likeMinPosts']) || $modSettings['likeMinPosts'] <= $this->user->posts); |
51
|
|
|
$this->_this_message['like_count'] = empty($context['likes'][$this->_this_message['id_msg']]['count']) ? 0 : $context['likes'][$this->_this_message['id_msg']]['count']; |
52
|
|
|
} |
53
|
|
|
|
54
|
2 |
|
/** |
55
|
|
|
* {@inheritDoc} |
56
|
2 |
|
*/ |
57
|
|
|
protected function _adjustAllMembers($member_context) |
58
|
2 |
|
{ |
59
|
2 |
|
global $context; |
60
|
2 |
|
|
61
|
|
|
$id_member = $this->_this_message[$this->_idx_mapper->id_member]; |
|
|
|
|
62
|
2 |
|
$this_member = MembersList::get($id_member); |
63
|
2 |
|
$this_member->loadContext(); |
64
|
|
|
|
65
|
2 |
|
$this_member['ip'] = $this->_this_message['poster_ip'] ?? ''; |
66
|
2 |
|
$this_member['show_profile_buttons'] = (!empty($this_member['can_view_profile']) |
67
|
|
|
|| (!empty($this_member['website']['url']) && !isset($context['disabled_fields']['website'])) |
68
|
|
|
|| $this_member['show_email'] |
69
|
|
|
|| $context['can_send_pm']); |
70
|
|
|
|
71
|
2 |
|
$context['id_msg'] = $this->_this_message['id_msg'] ?? ''; |
72
|
|
|
} |
73
|
2 |
|
|
74
|
|
|
/** |
75
|
2 |
|
* {@inheritDoc} |
76
|
|
|
*/ |
77
|
2 |
|
protected function _buildOutputArray() |
78
|
2 |
|
{ |
79
|
|
|
global $topic, $context, $modSettings, $txt; |
80
|
2 |
|
|
81
|
2 |
|
require_once(SUBSDIR . '/Attachments.subs.php'); |
82
|
2 |
|
|
83
|
2 |
|
$output = parent::_buildOutputArray(); |
84
|
2 |
|
$href = getUrl('topic', ['topic' => $topic, 'start' => 'msg' . $this->_this_message['id_msg'], 'subject' => $this->_this_message['subject']]) . '#msg' . $this->_this_message['id_msg']; |
85
|
|
|
$output += [ |
86
|
2 |
|
'href' => $href, |
87
|
2 |
|
'link' => '<a href="' . $href . '" rel="nofollow">' . $this->_this_message['subject'] . '</a>', |
88
|
2 |
|
'icon' => $this->_options->icon_sources->getIconValue($this->_this_message['icon']), |
|
|
|
|
89
|
2 |
|
'icon_url' => $this->_options->icon_sources->getIconURL($this->_this_message['icon']), |
90
|
|
|
'modified' => [ |
91
|
2 |
|
'time' => standardTime($this->_this_message['modified_time']), |
92
|
2 |
|
'html_time' => htmlTime($this->_this_message['modified_time']), |
93
|
2 |
|
'timestamp' => forum_time(true, $this->_this_message['modified_time']), |
94
|
2 |
|
'name' => $this->_this_message['modified_name'] |
95
|
2 |
|
], |
96
|
2 |
|
'new' => empty($this->_this_message['is_read']), |
97
|
2 |
|
'approved' => $this->_this_message['approved'], |
98
|
2 |
|
'first_new' => isset($context['start_from']) && $context['start_from'] == $this->_counter, |
99
|
2 |
|
'is_ignored' => !empty($modSettings['enable_buddylist']) && in_array($this->_this_message['id_member'], $context['user']['ignoreusers']), |
100
|
2 |
|
'is_message_author' => (int) $this->_this_message['id_member'] === (int) $this->user->id, |
101
|
2 |
|
'can_approve' => !$this->_this_message['approved'] && $context['can_approve'], |
102
|
2 |
|
'can_unapprove' => !empty($modSettings['postmod_active']) && $context['can_approve'] && $this->_this_message['approved'], |
103
|
2 |
|
'can_modify' => (!$context['is_locked'] || allowedTo('moderate_board')) && (allowedTo('modify_any') || (allowedTo('modify_replies') && $context['user']['started']) || (allowedTo('modify_own') && $this->_this_message['id_member'] == $this->user->id && (empty($modSettings['edit_disable_time']) || !$this->_this_message['approved'] || $this->_this_message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time()))), |
104
|
|
|
'can_remove' => allowedTo('delete_any') || (allowedTo('delete_replies') && $context['user']['started']) || (allowedTo('delete_own') && $this->_this_message['id_member'] == $this->user->id && (empty($modSettings['edit_disable_time']) || $this->_this_message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time())), |
105
|
|
|
'can_like' => $this->_this_message['use_likes'] && !$this->_this_message['you_liked'], |
106
|
|
|
'can_unlike' => $this->_this_message['use_likes'] && $this->_this_message['you_liked'], |
107
|
2 |
|
'like_counter' => $this->_this_message['like_count'], |
108
|
|
|
'likes_enabled' => !empty($modSettings['likes_enabled']) && ($this->_this_message['use_likes'] || ($this->_this_message['like_count'] != 0)), |
109
|
|
|
'classes' => [], |
110
|
|
|
]; |
111
|
|
|
|
112
|
2 |
|
if (!empty($output['modified']['name'])) |
113
|
|
|
{ |
114
|
|
|
$output['modified']['last_edit_text'] = sprintf($txt['last_edit_by'], $output['modified']['time'], $output['modified']['name'], standardTime($output['modified']['timestamp'])); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
if (!empty($output['member']['karma']['allow'])) |
118
|
|
|
{ |
119
|
|
|
$output['member']['karma'] += [ |
120
|
2 |
|
'applaud_url' => getUrl('action', ['action' => 'karma', 'sa' => 'applaud', 'uid' => $output['member']['id'], 'topic' => $context['current_topic'] . '.' . $context['start'], 'm' => $output['id'], '{session_data}']), |
121
|
|
|
'smite_url' => getUrl('action', ['action' => 'karma', 'sa' => 'smite', 'uid' => $output['member']['id'], 'topic' => $context['current_topic'] . '.' . $context['start'], 'm' => $output['id'], '{session_data}']) |
122
|
|
|
]; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
// Build the per post buttons! |
126
|
|
|
$output += $this->_buildPostButtons($output); |
127
|
|
|
|
128
|
|
|
return $output; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Generates the available button array suitable for consumption by template_button_strip |
133
|
|
|
* |
134
|
|
|
* @param array $output The output array containing post details. |
135
|
|
|
* |
136
|
|
|
* @return array The array containing all the post buttons. |
137
|
|
|
*/ |
138
|
|
|
protected function _buildPostButtons($output) |
139
|
|
|
{ |
140
|
|
|
global $context, $txt, $topic, $options, $board; |
141
|
|
|
|
142
|
|
|
$postButtons = [ |
143
|
|
|
// Can they reply? Have they turned on quick reply? |
144
|
|
|
'quote' => [ |
145
|
|
|
'text' => 'quote', |
146
|
|
|
'url' => empty($options['display_quick_reply']) ? getUrl('action', ['action' => 'post', 'topic' => $topic . '.' . $context['start'], 'quote' => $output['id'], 'last_msg' => $context['topic_last_message']]) : null, |
147
|
|
|
'custom' => empty($options['display_quick_reply']) ? '' : 'onclick="return oQuickReply.quote(' . $output['id'] . ');"', |
148
|
|
|
'class' => 'quote_button last', |
149
|
|
|
'icon' => 'quote', |
150
|
|
|
'enabled' => !empty($context['can_quote']), |
151
|
|
|
], |
152
|
|
|
// Can the user quick modify the contents of this post? Show the quick (inline) modify button. |
153
|
|
|
'quick_edit' => [ |
154
|
|
|
'text' => 'quick_edit', |
155
|
|
|
'url' => 'javascript:void(0);', |
156
|
|
|
'custom' => 'onclick="oQuickModify.modifyMsg(\'' . $output['id'] . '\')"', |
157
|
|
|
'icon' => 'modify', |
158
|
|
|
'enabled' => $output['can_modify'], |
159
|
|
|
], |
160
|
|
|
// Can they like/unlike or just view counts |
161
|
|
|
'react' => [ |
162
|
|
|
'text' => 'like_post', |
163
|
|
|
'url' => 'javascript:void(0);', |
164
|
|
|
'custom' => 'onclick="likePosts.prototype.likeUnlikePosts(event,' . $output['id'] . ',' . $context['current_topic'] . '); return false;"', |
165
|
|
|
'linkclass' => 'react_button', |
166
|
|
|
'icon' => 'thumbsup', |
167
|
|
|
'enabled' => $output['likes_enabled'] && $output['can_like'], |
168
|
|
|
'counter' => $output['like_counter'] ?? 0, |
169
|
|
|
], |
170
|
|
|
'unreact' => [ |
171
|
|
|
'text' => 'unlike_post', |
172
|
|
|
'url' => 'javascript:void(0);', |
173
|
|
|
'custom' => 'onclick="likePosts.prototype.likeUnlikePosts(event,' . $output['id'] . ',' . $context['current_topic'] . '); return false;"', |
174
|
|
|
'linkclass' => 'unreact_button', |
175
|
|
|
'icon' => 'thumbsdown', |
176
|
|
|
'enabled' => $output['likes_enabled'] && $output['can_unlike'], |
177
|
|
|
'counter' => $output['like_counter'] ?? 0, |
178
|
|
|
], |
179
|
|
|
'liked' => [ |
180
|
|
|
'text' => 'likes', |
181
|
|
|
'url' => 'javascript:void(0);', |
182
|
|
|
'custom' => 'onclick="this.blur();"', |
183
|
|
|
'icon' => 'thumbsup', |
184
|
|
|
'enabled' => $output['likes_enabled'] && !$output['can_unlike'] && !$output['can_like'], |
185
|
|
|
'counter' => $output['like_counter'] ?? 0, |
186
|
|
|
], |
187
|
|
|
// *** Submenu, aka "more", button items |
188
|
|
|
// |
189
|
|
|
// Can the user modify the contents of this post? |
190
|
|
|
'modify' => [ |
191
|
|
|
'text' => 'modify', |
192
|
|
|
'url' => getUrl('action', ['action' => 'post', 'msg' => $output['id'], 'topic' => $context['current_topic'] . '.' . $context['start']]), |
193
|
|
|
'icon' => 'modify', |
194
|
|
|
'enabled' => $output['can_modify'], |
195
|
|
|
'submenu' => true, |
196
|
|
|
], |
197
|
|
|
// How about... even... remove it entirely?! |
198
|
|
|
'remove_topic' => [ |
199
|
|
|
'text' => 'remove_topic', |
200
|
|
|
'url' => getUrl('action', ['action' => 'removetopic2', 'topic' => $topic . '.' . $context['start'], '{session_data}']), |
201
|
|
|
'custom' => 'onclick="return confirm(\'' . $txt['are_sure_remove_topic'] . '\');"', |
202
|
|
|
'icon' => 'warn', |
203
|
|
|
'enabled' => $context['can_delete'] && $context['topic_first_message'] === $output['id'], |
204
|
|
|
'submenu' => true, |
205
|
|
|
], |
206
|
|
|
// How about... remove the message |
207
|
|
|
'remove' => [ |
208
|
|
|
'text' => 'remove', |
209
|
|
|
'url' => getUrl('action', ['action' => 'deletemsg', 'topic' => $topic . '.' . $context['start'], 'msg' => $output['id'], '{session_data}']), |
210
|
|
|
'custom' => 'onclick="return confirm(\'' . $txt['remove_message'] . '?\');"', |
211
|
|
|
'icon' => 'delete', |
212
|
|
|
'enabled' => $output['can_remove'] && ($context['topic_first_message'] !== $output['id']), |
213
|
|
|
'submenu' => true, |
214
|
|
|
], |
215
|
|
|
// Can they quote to a new topic? @todo - This needs rethinking for GUI layout. |
216
|
|
|
'followup' => [ |
217
|
|
|
'text' => 'quote_new', |
218
|
|
|
'url' => getUrl('action', ['action' => 'post', 'board' => $board, 'quote' => $output['id'], 'followup' => $output['id']]), |
219
|
|
|
'icon' => 'quote', |
220
|
|
|
'enabled' => !empty($context['can_follow_up']), |
221
|
|
|
'submenu' => true, |
222
|
|
|
], |
223
|
|
|
// What about splitting it off the rest of the topic? |
224
|
|
|
'split' => [ |
225
|
|
|
'text' => 'split_topic', |
226
|
|
|
'url' => getUrl('action', ['action' => 'splittopics', 'topic' => $topic . '.0', 'at' => $output['id']]), |
227
|
|
|
'icon' => 'split', |
228
|
|
|
'enabled' => $context['can_split'] && !empty($context['real_num_replies']) && $context['topic_first_message'] !== $output['id'], |
229
|
|
|
'submenu' => true, |
230
|
|
|
], |
231
|
|
|
// Can we restore topics? |
232
|
|
|
'restore' => [ |
233
|
|
|
'text' => 'restore_message', |
234
|
|
|
'url' => getUrl('action', ['action' => 'restoretopic', 'msgs' => $output['id'], '{session_data}']), |
235
|
|
|
'icon' => 'recycle', |
236
|
|
|
'enabled' => $context['can_restore_msg'], |
237
|
|
|
'submenu' => true, |
238
|
|
|
], |
239
|
|
|
// Maybe we can approve it, maybe we should? |
240
|
|
|
'approve' => [ |
241
|
|
|
'text' => 'approve', |
242
|
|
|
'url' => getUrl('action', ['action' => 'moderate', 'area' => 'postmod', 'sa' => 'approve', 'topic' => $topic . '.' . $context['start'], 'msg' => $output['id'], '{session_data}']), |
243
|
|
|
'icon' => 'check', |
244
|
|
|
'enabled' => $output['can_approve'], |
245
|
|
|
'submenu' => true, |
246
|
|
|
], |
247
|
|
|
// Maybe we can unapprove it? |
248
|
|
|
'unapprove' => [ |
249
|
|
|
'text' => 'unapprove', |
250
|
|
|
'url' => getUrl('action', ['action' => 'moderate', 'area' => 'postmod', 'sa' => 'approve', 'topic' => $topic . '.' . $context['start'], 'msg' => $output['id'], '{session_data}']), |
251
|
|
|
'icon' => 'remove', |
252
|
|
|
'enabled' => $output['can_unapprove'], |
253
|
|
|
'submenu' => true, |
254
|
|
|
], |
255
|
|
|
// Maybe they want to report this post to the moderator(s)? |
256
|
|
|
'report' => [ |
257
|
|
|
'text' => 'report_to_mod', |
258
|
|
|
'url' => getUrl('action', ['action' => 'reporttm', 'topic' => $topic . '.' . $output['counter'], 'msg' => $output['id']]), |
259
|
|
|
'icon' => 'comment', |
260
|
|
|
'enabled' => $context['can_report_moderator'], |
261
|
|
|
'submenu' => true, |
262
|
|
|
], |
263
|
|
|
// Can we issue a warning because of this post? |
264
|
|
|
'warn' => [ |
265
|
|
|
'text' => 'issue_warning', |
266
|
|
|
'url' => getUrl('action', ['action' => 'profile', 'area' => 'issuewarning', 'u' => $output['member']['id'], 'msg' => $output['id']]), |
267
|
|
|
'icon' => 'warn', |
268
|
|
|
'enabled' => $context['can_issue_warning'] && !$output['is_message_author'] && !$output['member']['is_guest'], |
269
|
|
|
'submenu' => true, |
270
|
|
|
], |
271
|
|
|
// Quick Moderation Checkbox |
272
|
|
|
'inline_mod_check' => [ |
273
|
|
|
'id' => 'in_topic_mod_check_' . $output['id'], |
274
|
|
|
'class' => 'inline_mod_check hide', |
275
|
|
|
'enabled' => !empty($options['display_quick_mod']) && $output['can_remove'], |
276
|
|
|
'checkbox' => 'check', |
277
|
|
|
] |
278
|
|
|
]; |
279
|
|
|
|
280
|
|
|
// Drop any non-enabled ones |
281
|
|
|
$postButtons = array_filter($postButtons, static fn($button) => !isset($button['enabled']) || (bool) $button['enabled']); |
282
|
|
|
|
283
|
|
|
return ['postbuttons' => $postButtons]; |
284
|
|
|
} |
285
|
|
|
} |
286
|
|
|
|