|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Handles the retrieving and display of a users posts, attachments, stats, permissions |
|
5
|
|
|
* warnings and the like |
|
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\Controller; |
|
19
|
|
|
|
|
20
|
|
|
use BBC\ParserWrapper; |
|
21
|
|
|
use ElkArte\AbstractController; |
|
22
|
|
|
use ElkArte\Action; |
|
23
|
|
|
use ElkArte\Exceptions\Exception; |
|
24
|
|
|
use ElkArte\MembersList; |
|
25
|
|
|
use ElkArte\MessagesDelete; |
|
26
|
|
|
use ElkArte\Themes\ThemeLoader; |
|
27
|
|
|
use ElkArte\Util; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Access all profile summary areas for a user including overall summary, |
|
31
|
|
|
* post listing, attachment listing, user statistics user permissions, user warnings |
|
32
|
|
|
*/ |
|
33
|
|
|
class ProfileInfo extends AbstractController |
|
34
|
|
|
{ |
|
35
|
|
|
/** |
|
36
|
|
|
* Member id for the profile being worked with |
|
37
|
|
|
* |
|
38
|
|
|
* @var int |
|
39
|
|
|
*/ |
|
40
|
|
|
private $_memID = 0; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* The \ElkArte\Member object is stored here to avoid some global |
|
44
|
|
|
* |
|
45
|
|
|
* @var \ElkArte\Member |
|
46
|
|
|
*/ |
|
47
|
|
|
private $_profile = null; |
|
48
|
|
|
|
|
49
|
|
|
/** |
|
50
|
|
|
* Holds the current summary tabs to load |
|
51
|
|
|
* |
|
52
|
|
|
* @var array |
|
53
|
|
|
*/ |
|
54
|
|
|
private $_summary_areas; |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* Called before all other methods when coming from the dispatcher or |
|
58
|
|
|
* action class. |
|
59
|
|
|
* |
|
60
|
|
|
* - If you initiate the class outside of those methods, call this method. |
|
61
|
|
|
* or setup the class yourself or fall awaits. |
|
62
|
2 |
|
*/ |
|
63
|
|
|
public function pre_dispatch() |
|
64
|
2 |
|
{ |
|
65
|
|
|
global $context; |
|
66
|
2 |
|
|
|
67
|
|
|
require_once(SUBSDIR . '/Profile.subs.php'); |
|
68
|
2 |
|
|
|
69
|
2 |
|
$this->_memID = currentMemberID(); |
|
70
|
|
|
$this->_profile = MembersList::get($this->_memID); |
|
71
|
2 |
|
|
|
72
|
|
|
if (!isset($context['user']['is_owner'])) |
|
73
|
|
|
{ |
|
74
|
|
|
$context['user']['is_owner'] = (int) $this->_memID === (int) $this->user->id; |
|
75
|
|
|
} |
|
76
|
2 |
|
|
|
77
|
2 |
|
// Attempt to load the member's profile data. |
|
78
|
|
|
if ($this->_profile->isEmpty()) |
|
79
|
|
|
{ |
|
80
|
|
|
throw new Exception('not_a_user', false); |
|
81
|
|
|
} |
|
82
|
|
|
$this->_profile->loadContext(); |
|
83
|
|
|
|
|
84
|
|
|
ThemeLoader::loadLanguageFile('Profile'); |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* Intended as entry point which delegates to methods in this class... |
|
89
|
|
|
* |
|
90
|
|
|
* - But here, today, for now, the methods are mainly called from other places |
|
91
|
|
|
* like menu picks and the like. |
|
92
|
|
|
*/ |
|
93
|
|
|
public function action_index() |
|
94
|
|
|
{ |
|
95
|
|
|
global $context; |
|
96
|
|
|
|
|
97
|
|
|
// What do we do, do you even know what you do? |
|
98
|
|
|
$subActions = array( |
|
99
|
|
|
'buddies' => array($this, 'action_profile_buddies'), |
|
100
|
|
|
'recent' => array($this, 'action_profile_recent'), |
|
101
|
|
|
'summary' => array('controller' => '\\ElkArte\\Controller\\Profile', 'function' => 'action_index'), |
|
102
|
|
|
); |
|
103
|
|
|
|
|
104
|
|
|
// Action control |
|
105
|
|
|
$action = new Action('profile_info'); |
|
106
|
|
|
|
|
107
|
|
|
// By default we want the summary |
|
108
|
|
|
$subAction = $action->initialize($subActions, 'summary'); |
|
109
|
|
|
|
|
110
|
|
|
// Final bits |
|
111
|
|
|
$context['sub_action'] = $subAction; |
|
112
|
|
|
|
|
113
|
|
|
// Call the right function for this sub-action. |
|
114
|
2 |
|
$action->dispatch($subAction); |
|
115
|
|
|
} |
|
116
|
2 |
|
|
|
117
|
|
|
/** |
|
118
|
|
|
* View the user profile summary. |
|
119
|
2 |
|
* |
|
120
|
|
|
* @uses ProfileInfo template |
|
121
|
|
|
*/ |
|
122
|
|
|
public function action_summary() |
|
123
|
2 |
|
{ |
|
124
|
|
|
global $context, $modSettings; |
|
125
|
2 |
|
|
|
126
|
2 |
|
theme()->getTemplates()->load('ProfileInfo'); |
|
127
|
|
|
ThemeLoader::loadLanguageFile('Profile'); |
|
128
|
|
|
|
|
129
|
2 |
|
// Set a canonical URL for this page. |
|
130
|
|
|
$context['canonical_url'] = getUrl('action', ['action' => 'profile', 'u' => $this->_memID]); |
|
131
|
|
|
|
|
132
|
2 |
|
// Are there things we don't show? |
|
133
|
|
|
$context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array(); |
|
134
|
|
|
|
|
135
|
2 |
|
// Menu tab |
|
136
|
|
|
$context[$context['profile_menu_name']]['tab_data'] = array(); |
|
137
|
|
|
|
|
138
|
2 |
|
// Profile summary tabs, like Summary, Recent, Buddies |
|
139
|
|
|
$this->_register_summarytabs(); |
|
140
|
|
|
|
|
141
|
2 |
|
// Load in everything we know about the user to preload the summary tab |
|
142
|
2 |
|
$this->_define_user_values(); |
|
143
|
|
|
$this->_load_summary(); |
|
144
|
|
|
|
|
145
|
2 |
|
// To finish this off, custom profile fields. |
|
146
|
|
|
loadCustomFields($this->_memID); |
|
147
|
|
|
|
|
148
|
2 |
|
// To make tabs work, we need jQueryUI |
|
149
|
2 |
|
$modSettings['jquery_include_ui'] = true; |
|
150
|
2 |
|
theme()->addInlineJavascript('start_tabs();', true); |
|
151
|
2 |
|
loadCSSFile('jquery.ui.tabs.css'); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* Prepares the tabs for the profile summary page |
|
156
|
|
|
* |
|
157
|
|
|
* What it does: |
|
158
|
|
|
* |
|
159
|
|
|
* - Tab information for use in the summary page |
|
160
|
|
|
* - Each tab template defines a div, the value of which are the template(s) to load in that div |
|
161
|
|
|
* - array(array(1, 2), array(3, 4)) <div>template 1, template 2</div><div>template 3 template 4</div> |
|
162
|
|
|
* - Templates are named template_profile_block_YOURNAME |
|
163
|
|
|
* - Tabs with href defined will not preload/create any page divs but instead be loaded via ajax |
|
164
|
2 |
|
*/ |
|
165
|
|
|
private function _register_summarytabs() |
|
166
|
2 |
|
{ |
|
167
|
|
|
global $txt, $context, $modSettings; |
|
168
|
2 |
|
|
|
169
|
1 |
|
$context['summarytabs'] = array( |
|
170
|
2 |
|
'summary' => array( |
|
171
|
|
|
'name' => $txt['summary'], |
|
172
|
|
|
'templates' => array( |
|
173
|
|
|
array('summary', 'user_info'), |
|
174
|
|
|
array('contact', 'other_info'), |
|
175
|
|
|
array('user_customprofileinfo', 'moderation'), |
|
176
|
|
|
), |
|
177
|
|
|
'active' => true, |
|
178
|
|
|
), |
|
179
|
2 |
|
'recent' => array( |
|
180
|
|
|
'name' => $txt['profile_recent_activity'], |
|
181
|
|
|
'templates' => array('posts', 'topics', 'attachments'), |
|
182
|
2 |
|
'active' => true, |
|
183
|
|
|
'href' => getUrl('action', ['action' => 'profileInfo', 'sa' => 'recent;xml', 'u' => $this->_memID, '{session_data}']), |
|
184
|
|
|
), |
|
185
|
2 |
|
'buddies' => array( |
|
186
|
|
|
'name' => $txt['buddies'], |
|
187
|
2 |
|
'templates' => array('buddies'), |
|
188
|
2 |
|
'active' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'], |
|
189
|
|
|
'href' => getUrl('action', ['action' => 'profileInfo', 'sa' => 'buddies;xml', 'u' => $this->_memID, '{session_data}']), |
|
190
|
|
|
) |
|
191
|
|
|
); |
|
192
|
|
|
|
|
193
|
2 |
|
// Let addons add or remove to the tabs array |
|
194
|
|
|
call_integration_hook('integrate_profile_summary', array($this->_memID)); |
|
195
|
|
|
|
|
196
|
2 |
|
// Go forward with whats left after integration adds or removes |
|
197
|
2 |
|
$summary_areas = ''; |
|
198
|
|
|
foreach ($context['summarytabs'] as $id => $tab) |
|
199
|
|
|
{ |
|
200
|
2 |
|
// If the tab is active we add it |
|
201
|
|
|
if ($tab['active'] !== true) |
|
202
|
|
|
{ |
|
203
|
|
|
unset($context['summarytabs'][$id]); |
|
204
|
|
|
} |
|
205
|
|
|
else |
|
206
|
|
|
{ |
|
207
|
2 |
|
// All the active templates, used to prevent processing data we don't need |
|
208
|
|
|
foreach ($tab['templates'] as $template) |
|
209
|
2 |
|
{ |
|
210
|
|
|
$summary_areas .= is_array($template) ? implode(',', $template) : ',' . $template; |
|
211
|
|
|
} |
|
212
|
|
|
} |
|
213
|
|
|
} |
|
214
|
2 |
|
|
|
215
|
2 |
|
$this->_summary_areas = explode(',', $summary_areas); |
|
216
|
|
|
} |
|
217
|
|
|
|
|
218
|
|
|
/** |
|
219
|
|
|
* Sets in to context what we know about a given user |
|
220
|
|
|
* |
|
221
|
|
|
* - Defines various user permissions for profile views |
|
222
|
2 |
|
*/ |
|
223
|
|
|
private function _define_user_values() |
|
224
|
2 |
|
{ |
|
225
|
|
|
global $context, $modSettings, $txt; |
|
226
|
|
|
|
|
227
|
|
|
// Set up the context stuff and load the user. |
|
228
|
2 |
|
$context += array( |
|
229
|
2 |
|
'page_title' => sprintf($txt['profile_of_username'], $this->_profile['name']), |
|
|
|
|
|
|
230
|
2 |
|
'can_send_pm' => allowedTo('pm_send'), |
|
231
|
2 |
|
'can_send_email' => allowedTo('send_email_to_members'), |
|
232
|
2 |
|
'can_have_buddy' => allowedTo('profile_identity_own') && !empty($modSettings['enable_buddylist']), |
|
233
|
2 |
|
'can_issue_warning' => featureEnabled('w') && allowedTo('issue_warning') && !empty($modSettings['warning_enable']), |
|
234
|
|
|
'can_view_warning' => featureEnabled('w') && (allowedTo('issue_warning') && !$context['user']['is_owner']) || (!empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $context['user']['is_owner'])) |
|
235
|
|
|
); |
|
236
|
|
|
|
|
237
|
2 |
|
// @critical: potential problem here |
|
238
|
2 |
|
$context['member'] = $this->_profile; |
|
239
|
2 |
|
$context['member']->loadContext(); |
|
240
|
|
|
$context['member']['id'] = $this->_memID; |
|
241
|
|
|
|
|
242
|
2 |
|
// Is the signature even enabled on this forum? |
|
243
|
2 |
|
$context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1; |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
/** |
|
247
|
|
|
* Loads the information needed to create the profile summary view |
|
248
|
2 |
|
*/ |
|
249
|
|
|
private function _load_summary() |
|
250
|
|
|
{ |
|
251
|
2 |
|
// Load all areas of interest in to context for template use |
|
252
|
2 |
|
$this->_determine_warning_level(); |
|
253
|
2 |
|
$this->_determine_posts_per_day(); |
|
254
|
2 |
|
$this->_determine_age_birth(); |
|
255
|
2 |
|
$this->_determine_member_ip(); |
|
256
|
2 |
|
$this->_determine_member_action(); |
|
257
|
2 |
|
$this->_determine_member_activation(); |
|
258
|
2 |
|
$this->_determine_member_bans(); |
|
259
|
|
|
} |
|
260
|
|
|
|
|
261
|
|
|
/** |
|
262
|
|
|
* If they have been disciplined, show the warning level for those that can see it. |
|
263
|
2 |
|
*/ |
|
264
|
|
|
private function _determine_warning_level() |
|
265
|
2 |
|
{ |
|
266
|
|
|
global $modSettings, $context, $txt; |
|
267
|
|
|
|
|
268
|
2 |
|
// See if they have broken any warning levels... |
|
269
|
|
|
if (!empty($modSettings['warning_mute']) && $modSettings['warning_mute'] <= $context['member']['warning']) |
|
270
|
|
|
{ |
|
271
|
|
|
$context['warning_status'] = $txt['profile_warning_is_muted']; |
|
272
|
2 |
|
} |
|
273
|
|
|
elseif (!empty($modSettings['warning_moderate']) && $modSettings['warning_moderate'] <= $context['member']['warning']) |
|
274
|
|
|
{ |
|
275
|
|
|
$context['warning_status'] = $txt['profile_warning_is_moderation']; |
|
276
|
2 |
|
} |
|
277
|
|
|
elseif (!empty($modSettings['warning_watch']) && $modSettings['warning_watch'] <= $context['member']['warning']) |
|
278
|
|
|
{ |
|
279
|
|
|
$context['warning_status'] = $txt['profile_warning_is_watch']; |
|
280
|
2 |
|
} |
|
281
|
|
|
} |
|
282
|
|
|
|
|
283
|
|
|
/** |
|
284
|
|
|
* Gives their spam level as a posts per day kind of statistic |
|
285
|
2 |
|
*/ |
|
286
|
|
|
private function _determine_posts_per_day() |
|
287
|
2 |
|
{ |
|
288
|
|
|
global $context, $txt; |
|
289
|
|
|
|
|
290
|
2 |
|
// They haven't even been registered for a full day!? |
|
291
|
2 |
|
$days_registered = (int) ((time() - $this->_profile['registered_raw']) / (3600 * 24)); |
|
292
|
|
|
if (empty($this->_profile['date_registered']) || $days_registered < 1) |
|
293
|
2 |
|
{ |
|
294
|
|
|
$context['member']['posts_per_day'] = $txt['not_applicable']; |
|
295
|
|
|
} |
|
296
|
|
|
else |
|
297
|
|
|
{ |
|
298
|
|
|
$context['member']['posts_per_day'] = comma_format($context['member']['real_posts'] / $days_registered, 3); |
|
299
|
2 |
|
} |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
/** |
|
303
|
|
|
* Show age and birthday data if applicable. |
|
304
|
2 |
|
*/ |
|
305
|
|
|
private function _determine_age_birth() |
|
306
|
2 |
|
{ |
|
307
|
|
|
global $context, $txt; |
|
308
|
|
|
|
|
309
|
2 |
|
// Set the age... |
|
310
|
|
|
if (empty($context['member']['birth_date'])) |
|
311
|
|
|
{ |
|
312
|
|
|
$context['member']['age'] = $txt['not_applicable']; |
|
313
|
|
|
$context['member']['today_is_birthday'] = false; |
|
314
|
|
|
} |
|
315
|
|
|
else |
|
316
|
2 |
|
{ |
|
317
|
2 |
|
list ($birth_year, $birth_month, $birth_day) = sscanf($context['member']['birth_date'], '%d-%d-%d'); |
|
318
|
2 |
|
$datearray = getdate(forum_time()); |
|
319
|
2 |
|
$context['member']['age'] = $birth_year <= 4 ? $txt['not_applicable'] : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] === $birth_month && $datearray['mday'] >= $birth_day)) ? 0 : 1); |
|
320
|
|
|
$context['member']['today_is_birthday'] = $datearray['mon'] === $birth_month && $datearray['mday'] === $birth_day; |
|
321
|
|
|
|
|
322
|
2 |
|
} |
|
323
|
|
|
} |
|
324
|
|
|
|
|
325
|
|
|
/** |
|
326
|
|
|
* Show IP and hostname information for the users current IP of record. |
|
327
|
2 |
|
*/ |
|
328
|
|
|
private function _determine_member_ip() |
|
329
|
2 |
|
{ |
|
330
|
|
|
global $context, $modSettings; |
|
331
|
2 |
|
|
|
332
|
|
|
if (allowedTo('moderate_forum')) |
|
333
|
|
|
{ |
|
334
|
2 |
|
// Make sure it's a valid ip address; otherwise, don't bother... |
|
335
|
|
|
if (filter_var($this->_profile['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false && empty($modSettings['disableHostnameLookup'])) |
|
336
|
|
|
{ |
|
337
|
|
|
$context['member']['hostname'] = host_from_ip($this->_profile['ip']); |
|
|
|
|
|
|
338
|
|
|
} |
|
339
|
|
|
else |
|
340
|
2 |
|
{ |
|
341
|
|
|
$context['member']['hostname'] = ''; |
|
342
|
|
|
} |
|
343
|
2 |
|
|
|
344
|
|
|
$context['can_see_ip'] = true; |
|
345
|
|
|
} |
|
346
|
|
|
else |
|
347
|
|
|
{ |
|
348
|
|
|
$context['can_see_ip'] = false; |
|
349
|
2 |
|
} |
|
350
|
|
|
} |
|
351
|
|
|
|
|
352
|
|
|
/** |
|
353
|
|
|
* Determines what action user is "doing" at the time of the summary view |
|
354
|
2 |
|
*/ |
|
355
|
|
|
private function _determine_member_action() |
|
356
|
2 |
|
{ |
|
357
|
|
|
global $context, $modSettings; |
|
358
|
2 |
|
|
|
359
|
|
|
if (!empty($modSettings['who_enabled']) && $context['member']['online']['is_online']) |
|
360
|
|
|
{ |
|
361
|
|
|
include_once(SUBSDIR . '/Who.subs.php'); |
|
362
|
|
|
$action = determineActions($this->_profile['url']); |
|
363
|
|
|
ThemeLoader::loadLanguageFile('index'); |
|
364
|
|
|
|
|
365
|
|
|
if ($action !== false) |
|
|
|
|
|
|
366
|
|
|
{ |
|
367
|
|
|
$context['member']['action'] = $action; |
|
368
|
|
|
} |
|
369
|
2 |
|
} |
|
370
|
|
|
} |
|
371
|
|
|
|
|
372
|
|
|
/** |
|
373
|
|
|
* Checks if hte member is activated |
|
374
|
|
|
* |
|
375
|
|
|
* - Creates a link if the viewing member can activate a user |
|
376
|
2 |
|
*/ |
|
377
|
|
|
private function _determine_member_activation() |
|
378
|
2 |
|
{ |
|
379
|
|
|
global $context, $txt; |
|
380
|
|
|
|
|
381
|
2 |
|
// If the user is awaiting activation, and the viewer has permission - setup some activation context messages. |
|
382
|
|
|
if ($context['member']['is_activated'] % 10 !== 1 && allowedTo('moderate_forum')) |
|
383
|
|
|
{ |
|
384
|
|
|
$context['activate_type'] = $context['member']['is_activated']; |
|
385
|
|
|
|
|
386
|
|
|
// What should the link text be? |
|
387
|
|
|
$context['activate_link_text'] = in_array($context['member']['is_activated'], array(3, 4, 5, 13, 14, 15)) |
|
388
|
|
|
? $txt['account_approve'] |
|
389
|
|
|
: $txt['account_activate']; |
|
390
|
|
|
|
|
391
|
|
|
// Should we show a custom message? |
|
392
|
|
|
$context['activate_message'] = isset($txt['account_activate_method_' . $context['member']['is_activated'] % 10]) |
|
393
|
|
|
? $txt['account_activate_method_' . $context['member']['is_activated'] % 10] |
|
394
|
|
|
: $txt['account_not_activated']; |
|
395
|
|
|
|
|
396
|
|
|
$context['activate_url'] = getUrl('action', ['action' => 'profile;save', 'area' => 'activateaccount', 'u' => $this->_memID, '{session_data}', $context['profile-aa' . $this->_memID . '_token_var'] => $context['profile-aa' . $this->_memID . '_token']]); |
|
397
|
2 |
|
} |
|
398
|
|
|
} |
|
399
|
|
|
|
|
400
|
|
|
/** |
|
401
|
|
|
* Checks if a member has been banned |
|
402
|
2 |
|
*/ |
|
403
|
|
|
private function _determine_member_bans() |
|
404
|
2 |
|
{ |
|
405
|
|
|
global $context; |
|
406
|
|
|
|
|
407
|
2 |
|
// How about, are they banned? |
|
408
|
|
|
if (allowedTo('moderate_forum')) |
|
409
|
2 |
|
{ |
|
410
|
|
|
require_once(SUBSDIR . '/Bans.subs.php'); |
|
411
|
2 |
|
|
|
412
|
2 |
|
$hostname = !empty($context['member']['hostname']) ? $context['member']['hostname'] : ''; |
|
413
|
2 |
|
$email = !empty($context['member']['email']) ? $context['member']['email'] : ''; |
|
414
|
|
|
$context['member']['bans'] = BanCheckUser($this->_memID, $hostname, $email); |
|
415
|
|
|
|
|
416
|
2 |
|
// Can they edit the ban? |
|
417
|
|
|
$context['can_edit_ban'] = allowedTo('manage_bans'); |
|
418
|
2 |
|
} |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
/** |
|
422
|
|
|
* Show all posts by the current user. |
|
423
|
|
|
* |
|
424
|
|
|
* @todo This function needs to be split up properly. |
|
425
|
|
|
*/ |
|
426
|
|
|
public function action_showPosts() |
|
427
|
|
|
{ |
|
428
|
|
|
global $txt, $modSettings, $context, $board; |
|
429
|
|
|
|
|
430
|
|
|
// Some initial context. |
|
431
|
|
|
$context['start'] = $this->_req->getQuery('start', 'intval', 0); |
|
432
|
|
|
$context['current_member'] = $this->_memID; |
|
433
|
|
|
|
|
434
|
|
|
// What are we viewing |
|
435
|
|
|
$action = $this->_req->getQuery('sa', 'trim', ''); |
|
436
|
|
|
$action_title = array('messages' => 'Messages', 'attach' => 'Attachments', 'topics' => 'Topics', 'unwatchedtopics' => 'Unwatched'); |
|
437
|
|
|
$action_title = isset($action_title[$action]) ? $action_title[$action] : 'Posts'; |
|
438
|
|
|
|
|
439
|
|
|
theme()->getTemplates()->load('ProfileInfo'); |
|
440
|
|
|
|
|
441
|
|
|
// Create the tabs for the template. |
|
442
|
|
|
$context[$context['profile_menu_name']]['tab_data'] = array( |
|
443
|
|
|
'title' => $txt['show' . $action_title], |
|
444
|
|
|
'description' => sprintf($txt['showGeneric_help'], $txt['show' . $action_title]), |
|
445
|
|
|
'class' => 'profile', |
|
446
|
|
|
'tabs' => array( |
|
447
|
|
|
'messages' => array(), |
|
448
|
|
|
'topics' => array(), |
|
449
|
|
|
'unwatchedtopics' => array(), |
|
450
|
|
|
'attach' => array(), |
|
451
|
|
|
), |
|
452
|
|
|
); |
|
453
|
|
|
|
|
454
|
|
|
// Set the page title |
|
455
|
|
|
$context['page_title'] = $txt['showPosts'] . ' - ' . $this->_profile['real_name']; |
|
|
|
|
|
|
456
|
|
|
|
|
457
|
|
|
// Is the load average too high to allow searching just now? |
|
458
|
|
|
if (!empty($modSettings['loadavg_show_posts']) && $modSettings['current_load'] >= $modSettings['loadavg_show_posts']) |
|
459
|
|
|
{ |
|
460
|
|
|
throw new Exception('loadavg_show_posts_disabled', false); |
|
461
|
|
|
} |
|
462
|
|
|
|
|
463
|
|
|
// If we're specifically dealing with attachments use that function! |
|
464
|
|
|
if ($action === 'attach') |
|
465
|
|
|
{ |
|
466
|
|
|
return $this->action_showAttachments(); |
|
|
|
|
|
|
467
|
|
|
} |
|
468
|
|
|
|
|
469
|
|
|
// Instead, if we're dealing with unwatched topics (and the feature is enabled) use that other function. |
|
470
|
|
|
if ($action === 'unwatchedtopics' && $modSettings['enable_unwatch']) |
|
471
|
|
|
{ |
|
472
|
|
|
return $this->action_showUnwatched(); |
|
|
|
|
|
|
473
|
|
|
} |
|
474
|
|
|
|
|
475
|
|
|
// Are we just viewing topics? |
|
476
|
|
|
$context['is_topics'] = $action === 'topics'; |
|
477
|
|
|
|
|
478
|
|
|
// If just deleting a message, do it and then redirect back. |
|
479
|
|
|
if (isset($this->_req->query->delete) && !$context['is_topics']) |
|
480
|
|
|
{ |
|
481
|
|
|
checkSession('get'); |
|
482
|
|
|
|
|
483
|
|
|
// We can be lazy, since removeMessage() will check the permissions for us. |
|
484
|
|
|
$remover = new MessagesDelete($modSettings['recycle_enable'], $modSettings['recycle_board']); |
|
485
|
|
|
$remover->removeMessage((int) $this->_req->query->delete); |
|
486
|
|
|
|
|
487
|
|
|
// Back to... where we are now ;). |
|
488
|
|
|
redirectexit('action=profile;u=' . $this->_memID . ';area=showposts;start=' . $context['start']); |
|
489
|
|
|
} |
|
490
|
|
|
|
|
491
|
|
|
$msgCount = $context['is_topics'] ? count_user_topics($this->_memID, $board) : count_user_posts($this->_memID, $board); |
|
492
|
|
|
|
|
493
|
|
|
list ($min_msg_member, $max_msg_member) = findMinMaxUserMessage($this->_memID, $board); |
|
494
|
|
|
$range_limit = ''; |
|
495
|
|
|
$maxIndex = (int) $modSettings['defaultMaxMessages']; |
|
496
|
|
|
|
|
497
|
|
|
// Make sure the starting place makes sense and construct our friend the page index. |
|
498
|
|
|
$context['page_index'] = constructPageIndex('{scripturl}?action=profile;u=' . $this->_memID . ';area=showposts' . ($context['is_topics'] ? ';sa=topics' : ';sa=messages') . (!empty($board) ? ';board=' . $board : ''), $context['start'], $msgCount, $maxIndex); |
|
499
|
|
|
$context['current_page'] = $context['start'] / $maxIndex; |
|
500
|
|
|
|
|
501
|
|
|
// Reverse the query if we're past 50% of the pages for better performance. |
|
502
|
|
|
$start = $context['start']; |
|
503
|
|
|
$reverse = $this->_req->getQuery('start', 'intval', 0) > $msgCount / 2; |
|
504
|
|
|
if ($reverse) |
|
505
|
|
|
{ |
|
506
|
|
|
$maxIndex = $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] + 1 && $msgCount > $context['start'] ? $msgCount - $context['start'] : (int) $modSettings['defaultMaxMessages']; |
|
507
|
|
|
$start = $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] + 1 || $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] ? 0 : $msgCount - $context['start'] - $modSettings['defaultMaxMessages']; |
|
508
|
|
|
} |
|
509
|
|
|
|
|
510
|
|
|
// Guess the range of messages to be shown to help minimize what the query needs to do |
|
511
|
|
|
if ($msgCount > 1000) |
|
512
|
|
|
{ |
|
513
|
|
|
$margin = floor(($max_msg_member - $min_msg_member) * (($start + $modSettings['defaultMaxMessages']) / $msgCount) + .1 * ($max_msg_member - $min_msg_member)); |
|
514
|
|
|
|
|
515
|
|
|
// Make a bigger margin for topics only. |
|
516
|
|
|
if ($context['is_topics']) |
|
517
|
|
|
{ |
|
518
|
|
|
$margin *= 5; |
|
519
|
|
|
$range_limit = $reverse ? 't.id_first_msg < ' . ($min_msg_member + $margin) : 't.id_first_msg > ' . ($max_msg_member - $margin); |
|
520
|
|
|
} |
|
521
|
|
|
else |
|
522
|
|
|
{ |
|
523
|
|
|
$range_limit = $reverse ? 'm.id_msg < ' . ($min_msg_member + $margin) : 'm.id_msg > ' . ($max_msg_member - $margin); |
|
524
|
|
|
} |
|
525
|
|
|
} |
|
526
|
|
|
|
|
527
|
|
|
// Find this user's posts or topics started |
|
528
|
|
|
if ($context['is_topics']) |
|
529
|
|
|
{ |
|
530
|
|
|
$rows = load_user_topics($this->_memID, $start, $maxIndex, $range_limit, $reverse, $board); |
|
531
|
|
|
} |
|
532
|
|
|
else |
|
533
|
|
|
{ |
|
534
|
|
|
$rows = load_user_posts($this->_memID, $start, $maxIndex, $range_limit, $reverse, $board); |
|
535
|
|
|
} |
|
536
|
|
|
|
|
537
|
|
|
// Start counting at the number of the first message displayed. |
|
538
|
|
|
$counter = $reverse ? $context['start'] + $maxIndex + 1 : $context['start']; |
|
539
|
|
|
$context['posts'] = array(); |
|
540
|
|
|
$board_ids = array('own' => array(), 'any' => array()); |
|
541
|
|
|
$bbc_parser = ParserWrapper::instance(); |
|
542
|
|
|
foreach ($rows as $row) |
|
543
|
|
|
{ |
|
544
|
|
|
// Censor.... |
|
545
|
|
|
$row['body'] = censor($row['body']); |
|
546
|
|
|
$row['subject'] = censor($row['subject']); |
|
547
|
|
|
|
|
548
|
|
|
// Do the code. |
|
549
|
|
|
$row['body'] = $bbc_parser->parseMessage($row['body'], $row['smileys_enabled']); |
|
550
|
|
|
|
|
551
|
|
|
// And the array... |
|
552
|
|
|
$context['posts'][$counter += $reverse ? -1 : 1] = array( |
|
553
|
|
|
'body' => $row['body'], |
|
554
|
|
|
'counter' => $counter, |
|
555
|
|
|
'alternate' => $counter % 2, |
|
556
|
|
|
'category' => array( |
|
557
|
|
|
'name' => $row['cname'], |
|
558
|
|
|
'id' => $row['id_cat'] |
|
559
|
|
|
), |
|
560
|
|
|
'board' => array( |
|
561
|
|
|
'name' => $row['bname'], |
|
562
|
|
|
'id' => $row['id_board'], |
|
563
|
|
|
'link' => '<a href="' . getUrl('board', ['board' => $row['id_board'], 'start' => 0, 'name' => $row['bname']]) .'">' . $row['bname'] . '</a>', |
|
564
|
|
|
), |
|
565
|
|
|
'topic' => array( |
|
566
|
|
|
'id' => $row['id_topic'], |
|
567
|
|
|
'link' => '<a href="' . getUrl('topic', ['topic' => $row['id_topic'], 'msg' => $row['id_msg'], 'subject' => $row['subject'], 'start' => '0', 'hash' => '#msg' . $row['id_msg']]) . '">' . $row['subject'] . '</a>', |
|
568
|
|
|
), |
|
569
|
|
|
'subject' => $row['subject'], |
|
570
|
|
|
'start' => 'msg' . $row['id_msg'], |
|
571
|
|
|
'time' => standardTime($row['poster_time']), |
|
572
|
|
|
'html_time' => htmlTime($row['poster_time']), |
|
573
|
|
|
'timestamp' => forum_time(true, $row['poster_time']), |
|
574
|
|
|
'id' => $row['id_msg'], |
|
575
|
|
|
'tests' => array( |
|
576
|
|
|
'can_reply' => false, |
|
577
|
|
|
'can_mark_notify' => false, |
|
578
|
|
|
'can_delete' => false, |
|
579
|
|
|
), |
|
580
|
|
|
'delete_possible' => ($row['id_first_msg'] != $row['id_msg'] || $row['id_last_msg'] == $row['id_msg']) && (empty($modSettings['edit_disable_time']) || $row['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()), |
|
581
|
|
|
'approved' => $row['approved'], |
|
582
|
|
|
|
|
583
|
|
|
'buttons' => array( |
|
584
|
|
|
// How about... even... remove it entirely?! |
|
585
|
|
|
'remove' => array( |
|
586
|
|
|
'href' => getUrl('action', ['action' => 'deletemsg', 'msg' => $row['id_msg'], 'topic' => $row['id_topic'] . ';profile', 'u' => $context['member']['id'], 'start' => $context['start'], '{session_data}']), |
|
587
|
|
|
'text' => $txt['remove'], |
|
588
|
|
|
'test' => 'can_delete', |
|
589
|
|
|
'custom' => 'onclick="return confirm(' . JavaScriptEscape($txt['remove_message'] . '?') . ');"', |
|
590
|
|
|
), |
|
591
|
|
|
// Can we request notification of topics? |
|
592
|
|
|
'notify' => array( |
|
593
|
|
|
'href' => getUrl('action', ['action' => 'notify', 'topic' => $row['id_topic'], 'msg' => $row['id_msg']]), |
|
594
|
|
|
'text' => $txt['notify'], |
|
595
|
|
|
'test' => 'can_mark_notify', |
|
596
|
|
|
), |
|
597
|
|
|
// If they *can* reply? |
|
598
|
|
|
'reply' => array( |
|
599
|
|
|
'href' => getUrl('action', ['action' => 'post', 'topic' => $row['id_topic'], 'msg' => $row['id_msg']]), |
|
600
|
|
|
'text' => $txt['reply'], |
|
601
|
|
|
'test' => 'can_reply', |
|
602
|
|
|
), |
|
603
|
|
|
// If they *can* quote? |
|
604
|
|
|
'quote' => array( |
|
605
|
|
|
'href' => getUrl('action', ['action' => 'post', 'topic' => $row['id_topic'], 'msg' => $row['id_msg'], 'quote' => $row['id_msg']]), |
|
606
|
|
|
'text' => $txt['quote'], |
|
607
|
|
|
'test' => 'can_quote', |
|
608
|
|
|
), |
|
609
|
|
|
) |
|
610
|
|
|
); |
|
611
|
|
|
|
|
612
|
|
|
if ($this->user->id == $row['id_member_started']) |
|
613
|
|
|
{ |
|
614
|
|
|
$board_ids['own'][$row['id_board']][] = $counter; |
|
615
|
|
|
} |
|
616
|
|
|
$board_ids['any'][$row['id_board']][] = $counter; |
|
617
|
|
|
} |
|
618
|
|
|
|
|
619
|
|
|
// All posts were retrieved in reverse order, get them right again. |
|
620
|
|
|
if ($reverse) |
|
621
|
|
|
{ |
|
622
|
|
|
$context['posts'] = array_reverse($context['posts'], true); |
|
623
|
|
|
} |
|
624
|
|
|
|
|
625
|
|
|
// These are all the permissions that are different from board to board.. |
|
626
|
|
|
if ($context['is_topics']) |
|
627
|
|
|
{ |
|
628
|
|
|
$permissions = array( |
|
629
|
|
|
'own' => array( |
|
630
|
|
|
'post_reply_own' => 'can_reply', |
|
631
|
|
|
), |
|
632
|
|
|
'any' => array( |
|
633
|
|
|
'post_reply_any' => 'can_reply', |
|
634
|
|
|
'mark_any_notify' => 'can_mark_notify', |
|
635
|
|
|
) |
|
636
|
|
|
); |
|
637
|
|
|
} |
|
638
|
|
|
else |
|
639
|
|
|
{ |
|
640
|
|
|
$permissions = array( |
|
641
|
|
|
'own' => array( |
|
642
|
|
|
'post_reply_own' => 'can_reply', |
|
643
|
|
|
'delete_own' => 'can_delete', |
|
644
|
|
|
), |
|
645
|
|
|
'any' => array( |
|
646
|
|
|
'post_reply_any' => 'can_reply', |
|
647
|
|
|
'mark_any_notify' => 'can_mark_notify', |
|
648
|
|
|
'delete_any' => 'can_delete', |
|
649
|
|
|
) |
|
650
|
|
|
); |
|
651
|
|
|
} |
|
652
|
|
|
|
|
653
|
|
|
// For every permission in the own/any lists... |
|
654
|
|
|
foreach ($permissions as $type => $list) |
|
655
|
|
|
{ |
|
656
|
|
|
foreach ($list as $permission => $allowed) |
|
657
|
|
|
{ |
|
658
|
|
|
// Get the boards they can do this on... |
|
659
|
|
|
$boards = boardsAllowedTo($permission); |
|
660
|
|
|
|
|
661
|
|
|
// Hmm, they can do it on all boards, can they? |
|
662
|
|
|
if (!empty($boards) && $boards[0] == 0) |
|
663
|
|
|
{ |
|
664
|
|
|
$boards = array_keys($board_ids[$type]); |
|
665
|
|
|
} |
|
666
|
|
|
|
|
667
|
|
|
// Now go through each board they can do the permission on. |
|
668
|
|
|
foreach ($boards as $board_id) |
|
669
|
|
|
{ |
|
670
|
|
|
// There aren't any posts displayed from this board. |
|
671
|
|
|
if (!isset($board_ids[$type][$board_id])) |
|
672
|
|
|
{ |
|
673
|
|
|
continue; |
|
674
|
|
|
} |
|
675
|
|
|
|
|
676
|
|
|
// Set the permission to true ;). |
|
677
|
|
|
foreach ($board_ids[$type][$board_id] as $counter) |
|
678
|
|
|
{ |
|
679
|
|
|
$context['posts'][$counter]['tests'][$allowed] = true; |
|
680
|
|
|
} |
|
681
|
|
|
} |
|
682
|
|
|
} |
|
683
|
|
|
} |
|
684
|
|
|
|
|
685
|
|
|
// Clean up after posts that cannot be deleted and quoted. |
|
686
|
|
|
$quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])); |
|
687
|
|
|
foreach ($context['posts'] as $counter => $dummy) |
|
688
|
|
|
{ |
|
689
|
|
|
$context['posts'][$counter]['tests']['can_delete'] &= $context['posts'][$counter]['delete_possible']; |
|
690
|
|
|
$context['posts'][$counter]['tests']['can_quote'] = $context['posts'][$counter]['tests']['can_reply'] && $quote_enabled; |
|
691
|
|
|
} |
|
692
|
|
|
} |
|
693
|
|
|
|
|
694
|
|
|
/** |
|
695
|
|
|
* Show all the attachments of a user. |
|
696
|
|
|
*/ |
|
697
|
|
|
public function action_showAttachments() |
|
698
|
|
|
{ |
|
699
|
|
|
global $txt, $modSettings, $context; |
|
700
|
|
|
|
|
701
|
|
|
// OBEY permissions! |
|
702
|
|
|
$boardsAllowed = boardsAllowedTo('view_attachments'); |
|
703
|
|
|
|
|
704
|
|
|
// Make sure we can't actually see anything... |
|
705
|
|
|
if (empty($boardsAllowed)) |
|
706
|
|
|
{ |
|
707
|
|
|
$boardsAllowed = array(-1); |
|
708
|
|
|
} |
|
709
|
|
|
|
|
710
|
|
|
// This is all the information required to list attachments. |
|
711
|
|
|
$listOptions = array( |
|
712
|
|
|
'id' => 'profile_attachments', |
|
713
|
|
|
'title' => $txt['showAttachments'] . ($context['user']['is_owner'] ? '' : ' - ' . $context['member']['name']), |
|
714
|
|
|
'items_per_page' => $modSettings['defaultMaxMessages'], |
|
715
|
|
|
'no_items_label' => $txt['show_attachments_none'], |
|
716
|
|
|
'base_href' => getUrl('action', ['action' => 'profile', 'area' => 'showposts', 'sa' => 'attach', 'u' => $this->_memID]), |
|
717
|
|
|
'default_sort_col' => 'filename', |
|
718
|
|
|
'get_items' => array( |
|
719
|
|
|
'function' => function ($start, $items_per_page, $sort, $boardsAllowed) { |
|
720
|
|
|
return $this->list_getAttachments($start, $items_per_page, $sort, $boardsAllowed); |
|
721
|
|
|
}, |
|
722
|
|
|
'params' => array( |
|
723
|
|
|
$boardsAllowed, |
|
724
|
|
|
), |
|
725
|
|
|
), |
|
726
|
|
|
'get_count' => array( |
|
727
|
|
|
'function' => function ($boardsAllowed) { |
|
728
|
|
|
return $this->list_getNumAttachments($boardsAllowed); |
|
729
|
|
|
}, |
|
730
|
|
|
'params' => array( |
|
731
|
|
|
$boardsAllowed, |
|
732
|
|
|
), |
|
733
|
|
|
), |
|
734
|
|
|
'data_check' => array( |
|
735
|
|
|
'class' => function ($data) { |
|
736
|
|
|
return $data['approved'] ? '' : 'approvebg'; |
|
737
|
|
|
}, |
|
738
|
|
|
), |
|
739
|
|
|
'columns' => array( |
|
740
|
|
|
'filename' => array( |
|
741
|
|
|
'header' => array( |
|
742
|
|
|
'value' => $txt['show_attach_filename'], |
|
743
|
|
|
'class' => 'lefttext grid25', |
|
744
|
|
|
), |
|
745
|
|
|
'data' => array( |
|
746
|
|
|
'db' => 'filename', |
|
747
|
|
|
), |
|
748
|
|
|
'sort' => array( |
|
749
|
|
|
'default' => 'a.filename', |
|
750
|
|
|
'reverse' => 'a.filename DESC', |
|
751
|
|
|
), |
|
752
|
|
|
), |
|
753
|
|
|
'thumb' => array( |
|
754
|
|
|
'header' => array( |
|
755
|
|
|
'value' => '', |
|
756
|
|
|
), |
|
757
|
|
|
'data' => array( |
|
758
|
|
|
'function' => function ($rowData) { |
|
759
|
|
|
if ($rowData['is_image'] && !empty($rowData['id_thumb'])) |
|
760
|
|
|
{ |
|
761
|
|
|
return '<img src="' . getUrl('action', ['action' => 'dlattach', 'attach' => $rowData['id_thumb'] . ';image']) .'" />'; |
|
762
|
|
|
} |
|
763
|
|
|
|
|
764
|
|
|
return '<img src="' . getUrl('action', ['action' => 'dlattach', 'attach' => $rowData['id'] . ';thumb']) . '" />'; |
|
765
|
|
|
}, |
|
766
|
|
|
'class' => 'centertext recent_attachments', |
|
767
|
|
|
), |
|
768
|
|
|
'sort' => array( |
|
769
|
|
|
'default' => 'a.filename', |
|
770
|
|
|
'reverse' => 'a.filename DESC', |
|
771
|
|
|
), |
|
772
|
|
|
), |
|
773
|
|
|
'downloads' => array( |
|
774
|
|
|
'header' => array( |
|
775
|
|
|
'value' => $txt['show_attach_downloads'], |
|
776
|
|
|
), |
|
777
|
|
|
'data' => array( |
|
778
|
|
|
'db' => 'downloads', |
|
779
|
|
|
'comma_format' => true, |
|
780
|
|
|
), |
|
781
|
|
|
'sort' => array( |
|
782
|
|
|
'default' => 'a.downloads', |
|
783
|
|
|
'reverse' => 'a.downloads DESC', |
|
784
|
|
|
), |
|
785
|
|
|
), |
|
786
|
|
|
'subject' => array( |
|
787
|
|
|
'header' => array( |
|
788
|
|
|
'value' => $txt['message'], |
|
789
|
|
|
'class' => 'lefttext grid30', |
|
790
|
|
|
), |
|
791
|
|
|
'data' => array( |
|
792
|
|
|
'db' => 'subject', |
|
793
|
|
|
), |
|
794
|
|
|
'sort' => array( |
|
795
|
|
|
'default' => 'm.subject', |
|
796
|
|
|
'reverse' => 'm.subject DESC', |
|
797
|
|
|
), |
|
798
|
|
|
), |
|
799
|
|
|
'posted' => array( |
|
800
|
|
|
'header' => array( |
|
801
|
|
|
'value' => $txt['show_attach_posted'], |
|
802
|
|
|
'class' => 'lefttext', |
|
803
|
|
|
), |
|
804
|
|
|
'data' => array( |
|
805
|
|
|
'db' => 'posted', |
|
806
|
|
|
'timeformat' => true, |
|
807
|
|
|
), |
|
808
|
|
|
'sort' => array( |
|
809
|
|
|
'default' => 'm.poster_time', |
|
810
|
|
|
'reverse' => 'm.poster_time DESC', |
|
811
|
|
|
), |
|
812
|
|
|
), |
|
813
|
|
|
), |
|
814
|
|
|
); |
|
815
|
|
|
|
|
816
|
|
|
// Create the request list. |
|
817
|
|
|
createList($listOptions); |
|
818
|
|
|
|
|
819
|
|
|
$context['sub_template'] = 'show_list'; |
|
820
|
|
|
$context['default_list'] = 'profile_attachments'; |
|
821
|
|
|
} |
|
822
|
|
|
|
|
823
|
|
|
/** |
|
824
|
|
|
* Get a list of attachments for this user |
|
825
|
|
|
* Callback for createList() |
|
826
|
|
|
* |
|
827
|
|
|
* @param int $start The item to start with (for pagination purposes) |
|
828
|
|
|
* @param int $items_per_page The number of items to show per page |
|
829
|
|
|
* @param string $sort A string indicating how to sort the results |
|
830
|
|
|
* @param int[] $boardsAllowed |
|
831
|
|
|
* |
|
832
|
|
|
* @return array |
|
833
|
|
|
*/ |
|
834
|
|
|
public function list_getAttachments($start, $items_per_page, $sort, $boardsAllowed) |
|
835
|
|
|
{ |
|
836
|
|
|
// @todo tweak this method to use $context, etc, |
|
837
|
|
|
// then call subs function with params set. |
|
838
|
|
|
return profileLoadAttachments($start, $items_per_page, $sort, $boardsAllowed, $this->_memID); |
|
839
|
|
|
} |
|
840
|
|
|
|
|
841
|
|
|
/** |
|
842
|
|
|
* Callback for createList() |
|
843
|
|
|
* |
|
844
|
|
|
* @param int[] $boardsAllowed |
|
845
|
|
|
* |
|
846
|
|
|
* @return int |
|
847
|
|
|
*/ |
|
848
|
|
|
public function list_getNumAttachments($boardsAllowed) |
|
849
|
|
|
{ |
|
850
|
|
|
// @todo tweak this method to use $context, etc, |
|
851
|
|
|
// then call subs function with params set. |
|
852
|
|
|
return getNumAttachments($boardsAllowed, $this->_memID); |
|
853
|
|
|
} |
|
854
|
|
|
|
|
855
|
|
|
/** |
|
856
|
|
|
* Show all the unwatched topics. |
|
857
|
|
|
*/ |
|
858
|
|
|
public function action_showUnwatched() |
|
859
|
|
|
{ |
|
860
|
|
|
global $txt, $modSettings, $context; |
|
861
|
|
|
|
|
862
|
|
|
// Only the owner can see the list (if the function is enabled of course) |
|
863
|
|
|
if ($this->user->id != $this->_memID || !$modSettings['enable_unwatch']) |
|
864
|
|
|
{ |
|
865
|
|
|
return; |
|
866
|
|
|
} |
|
867
|
|
|
|
|
868
|
|
|
// And here they are: the topics you don't like |
|
869
|
|
|
$listOptions = array( |
|
870
|
|
|
'id' => 'unwatched_topics', |
|
871
|
|
|
'title' => $txt['showUnwatched'], |
|
872
|
|
|
'items_per_page' => $modSettings['defaultMaxMessages'], |
|
873
|
|
|
'no_items_label' => $txt['unwatched_topics_none'], |
|
874
|
|
|
'base_href' => getUrl('action', ['action' => 'profile', 'area' => 'showposts', 'sa' => 'unwatchedtopics', 'u' => $this->_memID]), |
|
875
|
|
|
'default_sort_col' => 'started_on', |
|
876
|
|
|
'get_items' => array( |
|
877
|
|
|
'function' => function ($start, $items_per_page, $sort) { |
|
878
|
|
|
return $this->list_getUnwatched($start, $items_per_page, $sort); |
|
879
|
|
|
}, |
|
880
|
|
|
), |
|
881
|
|
|
'get_count' => array( |
|
882
|
|
|
'function' => function () { |
|
883
|
|
|
return $this->list_getNumUnwatched(); |
|
884
|
|
|
}, |
|
885
|
|
|
), |
|
886
|
|
|
'columns' => array( |
|
887
|
|
|
'subject' => array( |
|
888
|
|
|
'header' => array( |
|
889
|
|
|
'value' => $txt['subject'], |
|
890
|
|
|
'class' => 'lefttext', |
|
891
|
|
|
'style' => 'width: 30%;', |
|
892
|
|
|
), |
|
893
|
|
|
'data' => array( |
|
894
|
|
|
'sprintf' => array( |
|
895
|
|
|
'format' => '<a href="' . getUrl('action', ['topic' => '%1$d.0']) . '">%2$s</a>', |
|
896
|
|
|
'params' => array( |
|
897
|
|
|
'id_topic' => false, |
|
898
|
|
|
'subject' => false, |
|
899
|
|
|
), |
|
900
|
|
|
), |
|
901
|
|
|
), |
|
902
|
|
|
'sort' => array( |
|
903
|
|
|
'default' => 'm.subject', |
|
904
|
|
|
'reverse' => 'm.subject DESC', |
|
905
|
|
|
), |
|
906
|
|
|
), |
|
907
|
|
|
'started_by' => array( |
|
908
|
|
|
'header' => array( |
|
909
|
|
|
'value' => $txt['started_by'], |
|
910
|
|
|
'style' => 'width: 15%;', |
|
911
|
|
|
), |
|
912
|
|
|
'data' => array( |
|
913
|
|
|
'db' => 'started_by', |
|
914
|
|
|
), |
|
915
|
|
|
'sort' => array( |
|
916
|
|
|
'default' => 'mem.real_name', |
|
917
|
|
|
'reverse' => 'mem.real_name DESC', |
|
918
|
|
|
), |
|
919
|
|
|
), |
|
920
|
|
|
'started_on' => array( |
|
921
|
|
|
'header' => array( |
|
922
|
|
|
'value' => $txt['on'], |
|
923
|
|
|
'class' => 'lefttext', |
|
924
|
|
|
'style' => 'width: 20%;', |
|
925
|
|
|
), |
|
926
|
|
|
'data' => array( |
|
927
|
|
|
'db' => 'started_on', |
|
928
|
|
|
'timeformat' => true, |
|
929
|
|
|
), |
|
930
|
|
|
'sort' => array( |
|
931
|
|
|
'default' => 'm.poster_time', |
|
932
|
|
|
'reverse' => 'm.poster_time DESC', |
|
933
|
|
|
), |
|
934
|
|
|
), |
|
935
|
|
|
'last_post_by' => array( |
|
936
|
|
|
'header' => array( |
|
937
|
|
|
'value' => $txt['last_post'], |
|
938
|
|
|
'style' => 'width: 15%;', |
|
939
|
|
|
), |
|
940
|
|
|
'data' => array( |
|
941
|
|
|
'db' => 'last_post_by', |
|
942
|
|
|
), |
|
943
|
|
|
'sort' => array( |
|
944
|
|
|
'default' => 'mem.real_name', |
|
945
|
|
|
'reverse' => 'mem.real_name DESC', |
|
946
|
|
|
), |
|
947
|
|
|
), |
|
948
|
|
|
'last_post_on' => array( |
|
949
|
|
|
'header' => array( |
|
950
|
|
|
'value' => $txt['on'], |
|
951
|
|
|
'class' => 'lefttext', |
|
952
|
|
|
'style' => 'width: 20%;', |
|
953
|
|
|
), |
|
954
|
|
|
'data' => array( |
|
955
|
|
|
'db' => 'last_post_on', |
|
956
|
|
|
'timeformat' => true, |
|
957
|
|
|
), |
|
958
|
|
|
'sort' => array( |
|
959
|
|
|
'default' => 'm.poster_time', |
|
960
|
|
|
'reverse' => 'm.poster_time DESC', |
|
961
|
|
|
), |
|
962
|
|
|
), |
|
963
|
|
|
), |
|
964
|
|
|
); |
|
965
|
|
|
|
|
966
|
|
|
// Create the request list. |
|
967
|
|
|
createList($listOptions); |
|
968
|
|
|
|
|
969
|
|
|
$context['sub_template'] = 'show_list'; |
|
970
|
|
|
$context['default_list'] = 'unwatched_topics'; |
|
971
|
|
|
} |
|
972
|
|
|
|
|
973
|
|
|
/** |
|
974
|
|
|
* Get the relevant topics in the unwatched list |
|
975
|
|
|
* Callback for createList() |
|
976
|
|
|
* |
|
977
|
|
|
* @param int $start The item to start with (for pagination purposes) |
|
978
|
|
|
* @param int $items_per_page The number of items to show per page |
|
979
|
|
|
* @param string $sort A string indicating how to sort the results |
|
980
|
|
|
* |
|
981
|
|
|
* @return array |
|
982
|
|
|
*/ |
|
983
|
|
|
public function list_getUnwatched($start, $items_per_page, $sort) |
|
984
|
|
|
{ |
|
985
|
|
|
return getUnwatchedBy($start, $items_per_page, $sort, $this->_memID); |
|
986
|
|
|
} |
|
987
|
|
|
|
|
988
|
|
|
/** |
|
989
|
|
|
* Count the number of topics in the unwatched list |
|
990
|
|
|
* Callback for createList() |
|
991
|
|
|
*/ |
|
992
|
|
|
public function list_getNumUnwatched() |
|
993
|
|
|
{ |
|
994
|
|
|
return getNumUnwatchedBy($this->_memID); |
|
995
|
|
|
} |
|
996
|
|
|
|
|
997
|
|
|
/** |
|
998
|
|
|
* Gets the user stats for display. |
|
999
|
|
|
*/ |
|
1000
|
|
|
public function action_statPanel() |
|
1001
|
|
|
{ |
|
1002
|
|
|
global $txt, $context, $modSettings; |
|
1003
|
|
|
|
|
1004
|
|
|
require_once(SUBSDIR . '/Stats.subs.php'); |
|
1005
|
|
|
|
|
1006
|
|
|
$context['page_title'] = $txt['statPanel_showStats'] . ' ' . $this->_profile['real_name']; |
|
|
|
|
|
|
1007
|
|
|
|
|
1008
|
|
|
// Is the load average too high to allow searching just now? |
|
1009
|
|
|
if (!empty($modSettings['loadavg_userstats']) && $modSettings['current_load'] >= $modSettings['loadavg_userstats']) |
|
1010
|
|
|
{ |
|
1011
|
|
|
throw new Exception('loadavg_userstats_disabled', false); |
|
1012
|
|
|
} |
|
1013
|
|
|
|
|
1014
|
|
|
theme()->getTemplates()->load('ProfileInfo'); |
|
1015
|
|
|
|
|
1016
|
|
|
// General user statistics. |
|
1017
|
|
|
$timeDays = floor($this->_profile['total_time_logged_in'] / 86400); |
|
1018
|
|
|
$timeHours = floor(($this->_profile['total_time_logged_in'] % 86400) / 3600); |
|
1019
|
|
|
$context['time_logged_in'] = ($timeDays > 0 ? $timeDays . $txt['totalTimeLogged2'] : '') . ($timeHours > 0 ? $timeHours . $txt['totalTimeLogged3'] : '') . floor(($this->_profile['total_time_logged_in'] % 3600) / 60) . $txt['totalTimeLogged4']; |
|
1020
|
|
|
$context['num_posts'] = comma_format($this->_profile['posts']); |
|
|
|
|
|
|
1021
|
|
|
|
|
1022
|
|
|
// Menu tab |
|
1023
|
|
|
$context[$context['profile_menu_name']]['tab_data'] = array( |
|
1024
|
|
|
'title' => $txt['statPanel_generalStats'] . ' - ' . $context['member']['name'], |
|
1025
|
|
|
'class' => 'stats_info' |
|
1026
|
|
|
); |
|
1027
|
|
|
|
|
1028
|
|
|
// Number of topics started. |
|
1029
|
|
|
$context['num_topics'] = UserStatsTopicsStarted($this->_memID); |
|
1030
|
|
|
|
|
1031
|
|
|
// Number of polls started. |
|
1032
|
|
|
$context['num_polls'] = UserStatsPollsStarted($this->_memID); |
|
1033
|
|
|
|
|
1034
|
|
|
// Number of polls voted in. |
|
1035
|
|
|
$context['num_votes'] = UserStatsPollsVoted($this->_memID); |
|
1036
|
|
|
|
|
1037
|
|
|
// Format the numbers... |
|
1038
|
|
|
$context['num_topics'] = comma_format($context['num_topics']); |
|
1039
|
|
|
$context['num_polls'] = comma_format($context['num_polls']); |
|
1040
|
|
|
$context['num_votes'] = comma_format($context['num_votes']); |
|
1041
|
|
|
|
|
1042
|
|
|
// Grab the boards this member posted in most often. |
|
1043
|
|
|
$context['popular_boards'] = UserStatsMostPostedBoard($this->_memID); |
|
1044
|
|
|
|
|
1045
|
|
|
// Now get the 10 boards this user has most often participated in. |
|
1046
|
|
|
$context['board_activity'] = UserStatsMostActiveBoard($this->_memID); |
|
1047
|
|
|
|
|
1048
|
|
|
// Posting activity by time. |
|
1049
|
|
|
$context['posts_by_time'] = UserStatsPostingTime($this->_memID); |
|
1050
|
|
|
|
|
1051
|
|
|
// Custom stats (just add a template_layer to add it to the template!) |
|
1052
|
|
|
call_integration_hook('integrate_profile_stats', array($this->_memID)); |
|
1053
|
|
|
} |
|
1054
|
|
|
|
|
1055
|
|
|
/** |
|
1056
|
|
|
* Show permissions for a user. |
|
1057
|
|
|
*/ |
|
1058
|
|
|
public function action_showPermissions() |
|
1059
|
|
|
{ |
|
1060
|
|
|
global $txt, $board, $context; |
|
1061
|
|
|
|
|
1062
|
|
|
// Verify if the user has sufficient permissions. |
|
1063
|
|
|
isAllowedTo('manage_permissions'); |
|
1064
|
|
|
|
|
1065
|
|
|
ThemeLoader::loadLanguageFile('ManagePermissions'); |
|
1066
|
|
|
ThemeLoader::loadLanguageFile('Admin'); |
|
1067
|
|
|
theme()->getTemplates()->load('ManageMembers'); |
|
1068
|
|
|
theme()->getTemplates()->load('ProfileInfo'); |
|
1069
|
|
|
|
|
1070
|
|
|
// Load all the permission profiles. |
|
1071
|
|
|
require_once(SUBSDIR . '/ManagePermissions.subs.php'); |
|
1072
|
|
|
loadPermissionProfiles(); |
|
1073
|
|
|
|
|
1074
|
|
|
$context['member']['id'] = $this->_memID; |
|
1075
|
|
|
$context['member']['name'] = $this->_profile['real_name']; |
|
1076
|
|
|
|
|
1077
|
|
|
$context['page_title'] = $txt['showPermissions']; |
|
1078
|
|
|
$board = empty($board) ? 0 : (int) $board; |
|
1079
|
|
|
$context['board'] = $board; |
|
1080
|
|
|
|
|
1081
|
|
|
$curGroups = empty($this->_profile['additional_groups']) ? array() : explode(',', $this->_profile['additional_groups']); |
|
|
|
|
|
|
1082
|
|
|
|
|
1083
|
|
|
$curGroups[] = $this->_profile['id_group']; |
|
1084
|
|
|
$curGroups[] = $this->_profile['id_post_group']; |
|
1085
|
|
|
|
|
1086
|
|
|
// Load a list of boards for the jump box - except the defaults. |
|
1087
|
|
|
require_once(SUBSDIR . '/Boards.subs.php'); |
|
1088
|
|
|
$board_list = getBoardList(array('moderator' => $this->_memID), true); |
|
1089
|
|
|
|
|
1090
|
|
|
$context['boards'] = array(); |
|
1091
|
|
|
$context['no_access_boards'] = array(); |
|
1092
|
|
|
foreach ($board_list as $row) |
|
1093
|
|
|
{ |
|
1094
|
|
|
if (count(array_intersect($curGroups, explode(',', $row['member_groups']))) === 0 && !$row['is_mod']) |
|
1095
|
|
|
{ |
|
1096
|
|
|
$context['no_access_boards'][] = array( |
|
1097
|
|
|
'id' => $row['id_board'], |
|
1098
|
|
|
'name' => $row['board_name'], |
|
1099
|
|
|
'is_last' => false, |
|
1100
|
|
|
); |
|
1101
|
|
|
} |
|
1102
|
|
|
elseif ($row['id_profile'] != 1 || $row['is_mod']) |
|
1103
|
|
|
{ |
|
1104
|
|
|
$context['boards'][$row['id_board']] = array( |
|
1105
|
|
|
'id' => $row['id_board'], |
|
1106
|
|
|
'name' => $row['board_name'], |
|
1107
|
|
|
'url' => getUrl('board', ['board' => $row['id_board'], 'start' => 0, 'name' => $row['board_name']]), |
|
1108
|
|
|
'selected' => $board == $row['id_board'], |
|
1109
|
|
|
'profile' => $row['id_profile'], |
|
1110
|
|
|
'profile_name' => $context['profiles'][$row['id_profile']]['name'], |
|
1111
|
|
|
); |
|
1112
|
|
|
} |
|
1113
|
|
|
} |
|
1114
|
|
|
|
|
1115
|
|
|
if (!empty($context['no_access_boards'])) |
|
1116
|
|
|
{ |
|
1117
|
|
|
$context['no_access_boards'][count($context['no_access_boards']) - 1]['is_last'] = true; |
|
1118
|
|
|
} |
|
1119
|
|
|
|
|
1120
|
|
|
$context['member']['permissions'] = array( |
|
1121
|
|
|
'general' => array(), |
|
1122
|
|
|
'board' => array() |
|
1123
|
|
|
); |
|
1124
|
|
|
|
|
1125
|
|
|
// If you're an admin we know you can do everything, we might as well leave. |
|
1126
|
|
|
$context['member']['has_all_permissions'] = in_array(1, $curGroups); |
|
1127
|
|
|
if ($context['member']['has_all_permissions']) |
|
1128
|
|
|
{ |
|
1129
|
|
|
return; |
|
1130
|
|
|
} |
|
1131
|
|
|
|
|
1132
|
|
|
// Get all general permissions for the groups this member is in |
|
1133
|
|
|
$context['member']['permissions']['general'] = getMemberGeneralPermissions($curGroups); |
|
|
|
|
|
|
1134
|
|
|
|
|
1135
|
|
|
// Get all board permissions for this member |
|
1136
|
|
|
$context['member']['permissions']['board'] = getMemberBoardPermissions($this->_memID, $curGroups, $board); |
|
|
|
|
|
|
1137
|
|
|
} |
|
1138
|
|
|
|
|
1139
|
|
|
/** |
|
1140
|
|
|
* View a members warnings. |
|
1141
|
|
|
*/ |
|
1142
|
|
|
public function action_viewWarning() |
|
1143
|
|
|
{ |
|
1144
|
|
|
global $modSettings, $context, $txt; |
|
1145
|
|
|
|
|
1146
|
|
|
// Firstly, can we actually even be here? |
|
1147
|
|
|
if (!allowedTo('issue_warning') && (empty($modSettings['warning_show']) || ($modSettings['warning_show'] == 1 && !$context['user']['is_owner']))) |
|
1148
|
|
|
{ |
|
1149
|
|
|
throw new Exception('no_access', false); |
|
1150
|
|
|
} |
|
1151
|
|
|
|
|
1152
|
|
|
theme()->getTemplates()->load('ProfileInfo'); |
|
1153
|
|
|
|
|
1154
|
|
|
// We need this because of template_load_warning_variables |
|
1155
|
|
|
theme()->getTemplates()->load('Profile'); |
|
1156
|
|
|
|
|
1157
|
|
|
// Make sure things which are disabled stay disabled. |
|
1158
|
|
|
$modSettings['warning_watch'] = !empty($modSettings['warning_watch']) ? $modSettings['warning_watch'] : 110; |
|
1159
|
|
|
$modSettings['warning_moderate'] = !empty($modSettings['warning_moderate']) && !empty($modSettings['postmod_active']) ? $modSettings['warning_moderate'] : 110; |
|
1160
|
|
|
$modSettings['warning_mute'] = !empty($modSettings['warning_mute']) ? $modSettings['warning_mute'] : 110; |
|
1161
|
|
|
|
|
1162
|
|
|
// Let's use a generic list to get all the current warnings |
|
1163
|
|
|
// and use the issue warnings grab-a-granny thing. |
|
1164
|
|
|
$listOptions = array( |
|
1165
|
|
|
'id' => 'view_warnings', |
|
1166
|
|
|
'title' => $txt['profile_viewwarning_previous_warnings'], |
|
1167
|
|
|
'items_per_page' => $modSettings['defaultMaxMessages'], |
|
1168
|
|
|
'no_items_label' => $txt['profile_viewwarning_no_warnings'], |
|
1169
|
|
|
'base_href' => getUrl('action', ['action' => 'profile', 'area' => 'viewwarning', 'sa' => 'user', 'u' => $this->_memID]), |
|
1170
|
|
|
'default_sort_col' => 'log_time', |
|
1171
|
|
|
'get_items' => array( |
|
1172
|
|
|
'function' => 'list_getUserWarnings', |
|
1173
|
|
|
'params' => array( |
|
1174
|
|
|
$this->_memID, |
|
1175
|
|
|
), |
|
1176
|
|
|
), |
|
1177
|
|
|
'get_count' => array( |
|
1178
|
|
|
'function' => 'list_getUserWarningCount', |
|
1179
|
|
|
'params' => array( |
|
1180
|
|
|
$this->_memID, |
|
1181
|
|
|
), |
|
1182
|
|
|
), |
|
1183
|
|
|
'columns' => array( |
|
1184
|
|
|
'log_time' => array( |
|
1185
|
|
|
'header' => array( |
|
1186
|
|
|
'value' => $txt['profile_warning_previous_time'], |
|
1187
|
|
|
), |
|
1188
|
|
|
'data' => array( |
|
1189
|
|
|
'db' => 'time', |
|
1190
|
|
|
), |
|
1191
|
|
|
'sort' => array( |
|
1192
|
|
|
'default' => 'lc.log_time DESC', |
|
1193
|
|
|
'reverse' => 'lc.log_time', |
|
1194
|
|
|
), |
|
1195
|
|
|
), |
|
1196
|
|
|
'reason' => array( |
|
1197
|
|
|
'header' => array( |
|
1198
|
|
|
'value' => $txt['profile_warning_previous_reason'], |
|
1199
|
|
|
'style' => 'width: 50%;', |
|
1200
|
|
|
), |
|
1201
|
|
|
'data' => array( |
|
1202
|
|
|
'db' => 'reason', |
|
1203
|
|
|
), |
|
1204
|
|
|
), |
|
1205
|
|
|
'level' => array( |
|
1206
|
|
|
'header' => array( |
|
1207
|
|
|
'value' => $txt['profile_warning_previous_level'], |
|
1208
|
|
|
), |
|
1209
|
|
|
'data' => array( |
|
1210
|
|
|
'db' => 'counter', |
|
1211
|
|
|
), |
|
1212
|
|
|
'sort' => array( |
|
1213
|
|
|
'default' => 'lc.counter DESC', |
|
1214
|
|
|
'reverse' => 'lc.counter', |
|
1215
|
|
|
), |
|
1216
|
|
|
), |
|
1217
|
|
|
), |
|
1218
|
|
|
'additional_rows' => array( |
|
1219
|
|
|
array( |
|
1220
|
|
|
'position' => 'after_title', |
|
1221
|
|
|
'value' => $txt['profile_viewwarning_desc'], |
|
1222
|
|
|
'class' => 'smalltext', |
|
1223
|
|
|
'style' => 'padding: 2ex;', |
|
1224
|
|
|
), |
|
1225
|
|
|
), |
|
1226
|
|
|
); |
|
1227
|
|
|
|
|
1228
|
|
|
// Create the list for viewing. |
|
1229
|
|
|
createList($listOptions); |
|
1230
|
|
|
|
|
1231
|
|
|
// Create some common text bits for the template. |
|
1232
|
|
|
$context['level_effects'] = array( |
|
1233
|
|
|
0 => '', |
|
1234
|
|
|
$modSettings['warning_watch'] => $txt['profile_warning_effect_own_watched'], |
|
1235
|
|
|
$modSettings['warning_moderate'] => $txt['profile_warning_effect_own_moderated'], |
|
1236
|
|
|
$modSettings['warning_mute'] => $txt['profile_warning_effect_own_muted'], |
|
1237
|
|
|
); |
|
1238
|
|
|
$context['current_level'] = 0; |
|
1239
|
|
|
$context['sub_template'] = 'viewWarning'; |
|
1240
|
|
|
|
|
1241
|
|
|
foreach ($context['level_effects'] as $limit => $dummy) |
|
1242
|
|
|
{ |
|
1243
|
|
|
if ($context['member']['warning'] >= $limit) |
|
1244
|
|
|
{ |
|
1245
|
|
|
$context['current_level'] = $limit; |
|
1246
|
|
|
} |
|
1247
|
|
|
} |
|
1248
|
|
|
} |
|
1249
|
|
|
|
|
1250
|
|
|
/** |
|
1251
|
|
|
* Collect and output data related to the profile buddy tab |
|
1252
|
|
|
* |
|
1253
|
|
|
* - Ajax call from profile info buddy tab |
|
1254
|
|
|
*/ |
|
1255
|
|
|
public function action_profile_buddies() |
|
1256
|
|
|
{ |
|
1257
|
|
|
global $context; |
|
1258
|
|
|
|
|
1259
|
|
|
checkSession('get'); |
|
1260
|
|
|
|
|
1261
|
|
|
// Need the ProfileInfo and Index (for helper functions) templates |
|
1262
|
|
|
theme()->getTemplates()->load('ProfileInfo'); |
|
1263
|
|
|
|
|
1264
|
|
|
// Prep for a buddy check |
|
1265
|
|
|
$this->_register_summarytabs(); |
|
1266
|
|
|
$this->_define_user_values(); |
|
1267
|
|
|
|
|
1268
|
|
|
// This is returned only for ajax request to a jqueryUI tab |
|
1269
|
|
|
theme()->getLayers()->removeAll(); |
|
1270
|
|
|
|
|
1271
|
|
|
// Some buddies for you |
|
1272
|
|
|
if (in_array('buddies', $this->_summary_areas)) |
|
1273
|
|
|
{ |
|
1274
|
|
|
$this->_load_buddies(); |
|
1275
|
|
|
$context['sub_template'] = 'profile_block_buddies'; |
|
1276
|
|
|
} |
|
1277
|
|
|
} |
|
1278
|
|
|
|
|
1279
|
|
|
/** |
|
1280
|
|
|
* Load the buddies tab with their buddies, real or imaginary |
|
1281
|
|
|
*/ |
|
1282
|
|
|
private function _load_buddies() |
|
1283
|
|
|
{ |
|
1284
|
|
|
global $context, $modSettings; |
|
1285
|
|
|
|
|
1286
|
|
|
// Would you be mine? Could you be mine? Be my buddy :D |
|
1287
|
|
|
$context['buddies'] = []; |
|
1288
|
|
|
if (!empty($modSettings['enable_buddylist']) |
|
1289
|
|
|
&& $context['user']['is_owner'] |
|
1290
|
|
|
&& !empty($this->user->buddies) |
|
1291
|
|
|
&& in_array('buddies', $this->_summary_areas)) |
|
1292
|
|
|
{ |
|
1293
|
|
|
if (MembersList::load($this->user->buddies, false, 'profile')) |
|
1294
|
|
|
{ |
|
1295
|
|
|
// Get the info for this buddy |
|
1296
|
|
|
foreach ($this->user->buddies as $buddy) |
|
1297
|
|
|
{ |
|
1298
|
|
|
$member = MembersList::get($buddy); |
|
1299
|
|
|
$member->loadContext(true); |
|
1300
|
|
|
|
|
1301
|
|
|
$context['buddies'][$buddy] = $member; |
|
1302
|
|
|
} |
|
1303
|
|
|
} |
|
1304
|
|
|
} |
|
1305
|
|
|
} |
|
1306
|
|
|
|
|
1307
|
|
|
/** |
|
1308
|
|
|
* Collect and output data related to the profile recent tab |
|
1309
|
|
|
* |
|
1310
|
|
|
* - Ajax call from profile info recent tab |
|
1311
|
|
|
*/ |
|
1312
|
|
|
public function action_profile_recent() |
|
1313
|
|
|
{ |
|
1314
|
|
|
global $context; |
|
1315
|
|
|
|
|
1316
|
|
|
checkSession('get'); |
|
1317
|
|
|
|
|
1318
|
|
|
// Prep for recent activity |
|
1319
|
|
|
$this->_register_summarytabs(); |
|
1320
|
|
|
$this->_define_user_values(); |
|
1321
|
|
|
|
|
1322
|
|
|
// The block templates are here |
|
1323
|
|
|
theme()->getTemplates()->load('ProfileInfo'); |
|
1324
|
|
|
$context['sub_template'] = 'profile_blocks'; |
|
1325
|
|
|
$context['profile_blocks'] = array(); |
|
1326
|
|
|
|
|
1327
|
|
|
// Flush everything since we intend to return the information to an ajax handler |
|
1328
|
|
|
theme()->getLayers()->removeAll(); |
|
1329
|
|
|
|
|
1330
|
|
|
// So, just what have you been up to? |
|
1331
|
|
|
if (in_array('posts', $this->_summary_areas)) |
|
1332
|
|
|
{ |
|
1333
|
|
|
$this->_load_recent_posts(); |
|
1334
|
|
|
$context['profile_blocks'][] = 'template_profile_block_posts'; |
|
1335
|
|
|
} |
|
1336
|
|
|
|
|
1337
|
|
|
if (in_array('topics', $this->_summary_areas)) |
|
1338
|
|
|
{ |
|
1339
|
|
|
$this->_load_recent_topics(); |
|
1340
|
|
|
$context['profile_blocks'][] = 'template_profile_block_topics'; |
|
1341
|
|
|
} |
|
1342
|
|
|
|
|
1343
|
|
|
if (in_array('attachments', $this->_summary_areas)) |
|
1344
|
|
|
{ |
|
1345
|
|
|
$this->_load_recent_attachments(); |
|
1346
|
|
|
$context['profile_blocks'][] = 'template_profile_block_attachments'; |
|
1347
|
|
|
} |
|
1348
|
|
|
} |
|
1349
|
|
|
|
|
1350
|
|
|
/** |
|
1351
|
|
|
* Load a members most recent posts |
|
1352
|
|
|
*/ |
|
1353
|
|
|
private function _load_recent_posts() |
|
1354
|
|
|
{ |
|
1355
|
|
|
global $context, $modSettings; |
|
1356
|
|
|
|
|
1357
|
|
|
// How about their most recent posts? |
|
1358
|
|
|
if (in_array('posts', $this->_summary_areas)) |
|
1359
|
|
|
{ |
|
1360
|
|
|
// Is the load average too high just now, then let them know |
|
1361
|
|
|
if (!empty($modSettings['loadavg_show_posts']) && $modSettings['current_load'] >= $modSettings['loadavg_show_posts']) |
|
1362
|
|
|
{ |
|
1363
|
|
|
$context['loadaverage'] = true; |
|
1364
|
|
|
} |
|
1365
|
|
|
else |
|
1366
|
|
|
{ |
|
1367
|
|
|
// Set up to get the last 10 posts of this member |
|
1368
|
|
|
$msgCount = count_user_posts($this->_memID); |
|
1369
|
|
|
$range_limit = ''; |
|
1370
|
|
|
$maxIndex = 10; |
|
1371
|
|
|
$start = $this->_req->getQuery('start', 'intval', 0); |
|
1372
|
|
|
|
|
1373
|
|
|
// If they are a frequent poster, we guess the range to help minimize what the query work |
|
1374
|
|
|
if ($msgCount > 1000) |
|
1375
|
|
|
{ |
|
1376
|
|
|
list ($min_msg_member, $max_msg_member) = findMinMaxUserMessage($this->_memID); |
|
1377
|
|
|
$margin = floor(($max_msg_member - $min_msg_member) * (($start + $modSettings['defaultMaxMessages']) / $msgCount) + .1 * ($max_msg_member - $min_msg_member)); |
|
1378
|
|
|
$range_limit = 'm.id_msg > ' . ($max_msg_member - $margin); |
|
1379
|
|
|
} |
|
1380
|
|
|
|
|
1381
|
|
|
// Find this user's most recent posts |
|
1382
|
|
|
$rows = load_user_posts($this->_memID, 0, $maxIndex, $range_limit); |
|
1383
|
|
|
$bbc_parser = ParserWrapper::instance(); |
|
1384
|
|
|
$context['posts'] = array(); |
|
1385
|
|
|
foreach ($rows as $row) |
|
1386
|
|
|
{ |
|
1387
|
|
|
// Censor.... |
|
1388
|
|
|
$row['body'] = censor($row['body']); |
|
1389
|
|
|
$row['subject'] = censor($row['subject']); |
|
1390
|
|
|
|
|
1391
|
|
|
// Do the code. |
|
1392
|
|
|
$row['body'] = $bbc_parser->parseMessage($row['body'], $row['smileys_enabled']); |
|
1393
|
|
|
$preview = strip_tags(strtr($row['body'], array('<br />' => ' '))); |
|
1394
|
|
|
$preview = Util::shorten_text($preview, !empty($modSettings['ssi_preview_length']) ? $modSettings['ssi_preview_length'] : 128); |
|
1395
|
|
|
$short_subject = Util::shorten_text($row['subject'], !empty($modSettings['ssi_subject_length']) ? $modSettings['ssi_subject_length'] : 24); |
|
1396
|
|
|
|
|
1397
|
|
|
// And the array... |
|
1398
|
|
|
$context['posts'][] = array( |
|
1399
|
|
|
'body' => $preview, |
|
1400
|
|
|
'board' => array( |
|
1401
|
|
|
'name' => $row['bname'], |
|
1402
|
|
|
'link' => '<a href="' . getUrl('board', ['board' => $row['id_board'], 'start' => 0, 'name' => $row['bname']]). '">' . $row['bname'] . '</a>' |
|
1403
|
|
|
), |
|
1404
|
|
|
'subject' => $row['subject'], |
|
1405
|
|
|
'short_subject' => $short_subject, |
|
1406
|
|
|
'time' => standardTime($row['poster_time']), |
|
1407
|
|
|
'html_time' => htmlTime($row['poster_time']), |
|
1408
|
|
|
'timestamp' => forum_time(true, $row['poster_time']), |
|
1409
|
|
|
'link' => '<a href="' . getUrl('topic', ['topic' => $row['id_topic'], 'msg' => $row['id_msg'], 'subject' => $row['subject'], 'hash' => '#msg' . $row['id_msg']]) . '" rel="nofollow">' . $short_subject . '</a>', |
|
1410
|
|
|
); |
|
1411
|
|
|
} |
|
1412
|
|
|
} |
|
1413
|
|
|
} |
|
1414
|
|
|
} |
|
1415
|
|
|
|
|
1416
|
|
|
/** |
|
1417
|
|
|
* Load a users recent topics |
|
1418
|
|
|
*/ |
|
1419
|
|
|
private function _load_recent_topics() |
|
1420
|
|
|
{ |
|
1421
|
|
|
global $context, $modSettings; |
|
1422
|
|
|
|
|
1423
|
|
|
// How about the most recent topics that they started? |
|
1424
|
|
|
if (in_array('topics', $this->_summary_areas)) |
|
1425
|
|
|
{ |
|
1426
|
|
|
// Is the load average still too high? |
|
1427
|
|
|
if (!empty($modSettings['loadavg_show_posts']) && $modSettings['current_load'] >= $modSettings['loadavg_show_posts']) |
|
1428
|
|
|
{ |
|
1429
|
|
|
$context['loadaverage'] = true; |
|
1430
|
|
|
} |
|
1431
|
|
|
else |
|
1432
|
|
|
{ |
|
1433
|
|
|
// Set up to get the last 10 topics of this member |
|
1434
|
|
|
$topicCount = count_user_topics($this->_memID); |
|
1435
|
|
|
$range_limit = ''; |
|
1436
|
|
|
$maxIndex = 10; |
|
1437
|
|
|
$start = $this->_req->getQuery('start', 'intval', 0); |
|
1438
|
|
|
|
|
1439
|
|
|
// If they are a frequent topic starter we guess the range to help the query |
|
1440
|
|
|
if ($topicCount > 1000) |
|
1441
|
|
|
{ |
|
1442
|
|
|
list ($min_topic_member, $max_topic_member) = findMinMaxUserTopic($this->_memID); |
|
1443
|
|
|
$margin = floor(($max_topic_member - $min_topic_member) * (($start + $modSettings['defaultMaxMessages']) / $topicCount) + .1 * ($max_topic_member - $min_topic_member)); |
|
1444
|
|
|
$margin *= 5; |
|
1445
|
|
|
$range_limit = 't.id_first_msg > ' . ($max_topic_member - $margin); |
|
1446
|
|
|
} |
|
1447
|
|
|
|
|
1448
|
|
|
// Find this user's most recent topics |
|
1449
|
|
|
$rows = load_user_topics($this->_memID, 0, $maxIndex, $range_limit); |
|
1450
|
|
|
$context['topics'] = array(); |
|
1451
|
|
|
$bbc_parser = ParserWrapper::instance(); |
|
1452
|
|
|
|
|
1453
|
|
|
foreach ($rows as $row) |
|
1454
|
|
|
{ |
|
1455
|
|
|
// Censor.... |
|
1456
|
|
|
$row['body'] = censor($row['body']); |
|
1457
|
|
|
$row['subject'] = censor($row['subject']); |
|
1458
|
|
|
|
|
1459
|
|
|
// Do the code. |
|
1460
|
|
|
$row['body'] = $bbc_parser->parseMessage($row['body'], $row['smileys_enabled']); |
|
1461
|
|
|
$preview = strip_tags(strtr($row['body'], array('<br />' => ' '))); |
|
1462
|
|
|
$preview = Util::shorten_text($preview, !empty($modSettings['ssi_preview_length']) ? $modSettings['ssi_preview_length'] : 128); |
|
1463
|
|
|
$short_subject = Util::shorten_text($row['subject'], !empty($modSettings['ssi_subject_length']) ? $modSettings['ssi_subject_length'] : 24); |
|
1464
|
|
|
|
|
1465
|
|
|
// And the array... |
|
1466
|
|
|
$context['topics'][] = array( |
|
1467
|
|
|
'board' => array( |
|
1468
|
|
|
'name' => $row['bname'], |
|
1469
|
|
|
'link' => '<a href="' . getUrl('board', ['board' => $row['id_board'], 'start' => 0, 'name' => $row['bname']]) . '</a>' |
|
1470
|
|
|
), |
|
1471
|
|
|
'subject' => $row['subject'], |
|
1472
|
|
|
'short_subject' => $short_subject, |
|
1473
|
|
|
'body' => $preview, |
|
1474
|
|
|
'time' => standardTime($row['poster_time']), |
|
1475
|
|
|
'html_time' => htmlTime($row['poster_time']), |
|
1476
|
|
|
'timestamp' => forum_time(true, $row['poster_time']), |
|
1477
|
|
|
'link' => '<a href="' . getUrl('topic', ['topic' => $row['id_topic'], 'msg' => $row['id_msg'], 'subject' => $row['subject'], 'hash' => '#msg' . $row['id_msg']]) . '" rel="nofollow">' . $short_subject . '</a>', |
|
1478
|
|
|
); |
|
1479
|
|
|
} |
|
1480
|
|
|
} |
|
1481
|
|
|
} |
|
1482
|
|
|
} |
|
1483
|
|
|
|
|
1484
|
|
|
/** |
|
1485
|
|
|
* If they have made recent attachments, lets get a list of them to display |
|
1486
|
|
|
*/ |
|
1487
|
|
|
private function _load_recent_attachments() |
|
1488
|
|
|
{ |
|
1489
|
|
|
global $context, $modSettings, $settings; |
|
1490
|
|
|
|
|
1491
|
|
|
$context['thumbs'] = array(); |
|
1492
|
|
|
|
|
1493
|
|
|
// Load up the most recent attachments for this user for use in profile views etc. |
|
1494
|
|
|
if (!empty($modSettings['attachmentEnable']) |
|
1495
|
|
|
&& !empty($settings['attachments_on_summary']) |
|
1496
|
|
|
&& in_array('attachments', $this->_summary_areas)) |
|
1497
|
|
|
{ |
|
1498
|
|
|
$boardsAllowed = boardsAllowedTo('view_attachments'); |
|
1499
|
|
|
|
|
1500
|
|
|
if (empty($boardsAllowed)) |
|
1501
|
|
|
{ |
|
1502
|
|
|
$boardsAllowed = array(-1); |
|
1503
|
|
|
} |
|
1504
|
|
|
|
|
1505
|
|
|
$attachments = $this->list_getAttachments(0, $settings['attachments_on_summary'], 'm.poster_time DESC', $boardsAllowed); |
|
1506
|
|
|
|
|
1507
|
|
|
// Some generic images for mime types |
|
1508
|
|
|
$mime_images_url = $settings['default_images_url'] . '/mime_images/'; |
|
1509
|
|
|
$mime_path = $settings['default_theme_dir'] . '/images/mime_images/'; |
|
1510
|
|
|
|
|
1511
|
|
|
// Load them in to $context for use in the template |
|
1512
|
|
|
foreach ($attachments as $i => $attachment) |
|
1513
|
|
|
{ |
|
1514
|
|
|
$context['thumbs'][$i] = array( |
|
1515
|
|
|
'url' => getUrl('action', ['action' => 'dlattach', 'topic' => $attachment['topic'] . '.0', 'attach' => $attachment['id']]), |
|
1516
|
|
|
'img' => '', |
|
1517
|
|
|
'filename' => $attachment['filename'], |
|
1518
|
|
|
'downloads' => $attachment['downloads'], |
|
1519
|
|
|
'subject' => $attachment['subject'], |
|
1520
|
|
|
'id' => $attachment['id'], |
|
1521
|
|
|
); |
|
1522
|
|
|
|
|
1523
|
|
|
// Show a thumbnail image as well? |
|
1524
|
|
|
if ($attachment['is_image'] && !empty($modSettings['attachmentShowImages']) && !empty($modSettings['attachmentThumbnails'])) |
|
1525
|
|
|
{ |
|
1526
|
|
|
if (!empty($attachment['id_thumb'])) |
|
1527
|
|
|
{ |
|
1528
|
|
|
$context['thumbs'][$i]['img'] = '<img id="thumb_' . $attachment['id'] . '" src="' . getUrl('action', ['action' => 'dlattach', 'topic' => $attachment['topic'] . '.0', 'attach' => $attachment['id_thumb'] . ';image']) . '" title="" alt="" />'; |
|
1529
|
|
|
} |
|
1530
|
|
|
elseif (!empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight'])) |
|
1531
|
|
|
{ |
|
1532
|
|
|
// No thumbnail available ... use html instead |
|
1533
|
|
|
if ($attachment['width'] > $modSettings['attachmentThumbWidth'] || $attachment['height'] > $modSettings['attachmentThumbHeight']) |
|
1534
|
|
|
{ |
|
1535
|
|
|
$context['thumbs'][$i]['img'] = '<img id="thumb_' . $attachment['id'] . '" src="' . getUrl('action', ['action' => 'dlattach', 'topic' => $attachment['topic'] . '.0', 'attach' => $attachment['id']]) . '" title="" alt="" width="' . $modSettings['attachmentThumbWidth'] . '" height="' . $modSettings['attachmentThumbHeight'] . '" />'; |
|
1536
|
|
|
} |
|
1537
|
|
|
else |
|
1538
|
|
|
{ |
|
1539
|
|
|
$context['thumbs'][$i]['img'] = '<img id="thumb_' . $attachment['id'] . '" src="' . getUrl('action', ['action' => 'dlattach', 'topic' => $attachment['topic'] . '.0', 'attach' => $attachment['id']]) . '" title="" alt="" width="' . $attachment['width'] . '" height="' . $attachment['height'] . '" />'; |
|
1540
|
|
|
} |
|
1541
|
|
|
} |
|
1542
|
|
|
} |
|
1543
|
|
|
// Not an image so lets set a mime thumbnail based off the filetype |
|
1544
|
|
|
elseif ((!empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight'])) && (128 > $modSettings['attachmentThumbWidth'] || 128 > $modSettings['attachmentThumbHeight'])) |
|
1545
|
|
|
{ |
|
1546
|
|
|
$context['thumbs'][$i]['img'] = '<img src="' . $mime_images_url . (!file_exists($mime_path . $attachment['fileext'] . '.png') ? 'default' : $attachment['fileext']) . '.png" title="" alt="" width="' . $modSettings['attachmentThumbWidth'] . '" height="' . $modSettings['attachmentThumbHeight'] . '" />'; |
|
1547
|
|
|
} |
|
1548
|
|
|
else |
|
1549
|
|
|
{ |
|
1550
|
|
|
$context['thumbs'][$i]['img'] = '<img src="' . $mime_images_url . (!file_exists($mime_path . $attachment['fileext'] . '.png') ? 'default' : $attachment['fileext']) . '.png" title="" alt="" />'; |
|
1551
|
|
|
} |
|
1552
|
|
|
} |
|
1553
|
|
|
} |
|
1554
|
|
|
} |
|
1555
|
|
|
} |
|
1556
|
|
|
|