These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Provides ways to add information to your website by linking to and capturing output |
||
5 | * from ElkArte |
||
6 | * |
||
7 | * @name ElkArte Forum |
||
8 | * @copyright ElkArte Forum contributors |
||
9 | * @license BSD http://opensource.org/licenses/BSD-3-Clause |
||
10 | * |
||
11 | * This software is a derived product, based on: |
||
12 | * |
||
13 | * Simple Machines Forum (SMF) |
||
14 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||
15 | * license: BSD, See included LICENSE.TXT for terms and conditions. |
||
16 | * |
||
17 | * @version 1.0.10 |
||
18 | * |
||
19 | */ |
||
20 | |||
21 | // Don't do anything if ElkArte is already loaded. |
||
22 | if (defined('ELK')) |
||
23 | return true; |
||
24 | |||
25 | define('ELK', 'SSI'); |
||
26 | |||
27 | // Shortcut for the browser cache stale |
||
28 | define('CACHE_STALE', '?109'); |
||
29 | |||
30 | // We're going to want a few globals... these are all set later. |
||
31 | global $time_start, $maintenance, $msubject, $mmessage, $mbname, $language; |
||
32 | global $boardurl, $webmaster_email, $cookiename; |
||
33 | global $db_server, $db_name, $db_user, $db_prefix, $db_persist, $db_error_send, $db_last_error; |
||
34 | global $modSettings, $context, $sc, $user_info, $topic, $board, $txt; |
||
35 | global $ssi_db_user, $scripturl, $ssi_db_passwd, $db_passwd; |
||
36 | global $sourcedir, $boarddir; |
||
37 | |||
38 | // Remember the current configuration so it can be set back. |
||
39 | $ssi_magic_quotes_runtime = function_exists('get_magic_quotes_gpc') && get_magic_quotes_runtime(); |
||
40 | if (function_exists('set_magic_quotes_runtime')) |
||
41 | @set_magic_quotes_runtime(0); |
||
42 | $time_start = microtime(true); |
||
43 | |||
44 | // Just being safe... |
||
45 | foreach (array('db_character_set', 'cachedir') as $variable) |
||
46 | if (isset($GLOBALS[$variable])) |
||
47 | unset($GLOBALS[$variable]); |
||
48 | |||
49 | // Get the forum's settings for database and file paths. |
||
50 | require_once(dirname(__FILE__) . '/Settings.php'); |
||
51 | |||
52 | // Fix for using the current directory as a path. |
||
53 | if (substr($sourcedir, 0, 1) == '.' && substr($sourcedir, 1, 1) != '.') |
||
54 | $sourcedir = dirname(__FILE__) . substr($sourcedir, 1); |
||
55 | |||
56 | // Make sure the paths are correct... at least try to fix them. |
||
57 | if (!file_exists($boarddir) && file_exists(dirname(__FILE__) . '/agreement.txt')) |
||
58 | $boarddir = dirname(__FILE__); |
||
59 | if (!file_exists($sourcedir) && file_exists($boarddir . '/sources')) |
||
60 | $sourcedir = $boarddir . '/sources'; |
||
61 | |||
62 | // Check that directories which didn't exist in past releases are initialized. |
||
63 | if ((empty($cachedir) || !file_exists($cachedir)) && file_exists($boarddir . '/cache')) |
||
64 | $cachedir = $boarddir . '/cache'; |
||
65 | if ((empty($extdir) || !file_exists($extdir)) && file_exists($sourcedir . '/ext')) |
||
66 | $extdir = $sourcedir . '/ext'; |
||
67 | if ((empty($languagedir) || !file_exists($languagedir)) && file_exists($boarddir . '/themes/default/languages')) |
||
68 | $languagedir = $boarddir . '/themes/default/languages'; |
||
69 | |||
70 | // Time to forget about variables and go with constants! |
||
71 | DEFINE('BOARDDIR', $boarddir); |
||
72 | DEFINE('CACHEDIR', $cachedir); |
||
73 | DEFINE('EXTDIR', $extdir); |
||
74 | DEFINE('LANGUAGEDIR', $languagedir); |
||
75 | DEFINE('SOURCEDIR', $sourcedir); |
||
76 | DEFINE('ADMINDIR', $sourcedir . '/admin'); |
||
77 | DEFINE('CONTROLLERDIR', $sourcedir . '/controllers'); |
||
78 | DEFINE('SUBSDIR', $sourcedir . '/subs'); |
||
79 | unset($boarddir, $cachedir, $sourcedir, $languagedir, $extdir); |
||
80 | |||
81 | $ssi_error_reporting = error_reporting(E_ALL | E_STRICT); |
||
82 | /** |
||
83 | * Set this to one of three values depending on what you want to happen in the case of a fatal error. |
||
84 | * - false: Default, will just load the error sub template and die - not putting any theme layers around it. |
||
85 | * - true: Will load the error sub template AND put the template layers around it (Not useful if on total custom pages). |
||
86 | * - string: Name of a callback function to call in the event of an error to allow you to define your own methods. Will die after function returns. |
||
87 | */ |
||
88 | $ssi_on_error_method = false; |
||
89 | |||
90 | // Don't do john didley if the forum's been shut down competely. |
||
91 | if ($maintenance == 2 && (!isset($ssi_maintenance_off) || $ssi_maintenance_off !== true)) |
||
92 | die($mmessage); |
||
93 | |||
94 | // Load the important includes. |
||
95 | require_once(SOURCEDIR . '/QueryString.php'); |
||
96 | require_once(SOURCEDIR . '/Session.php'); |
||
97 | require_once(SOURCEDIR . '/Subs.php'); |
||
98 | require_once(SOURCEDIR . '/Errors.php'); |
||
99 | require_once(SOURCEDIR . '/Logging.php'); |
||
100 | require_once(SOURCEDIR . '/Load.php'); |
||
101 | require_once(SUBSDIR . '/Cache.subs.php'); |
||
102 | require_once(SOURCEDIR . '/Security.php'); |
||
103 | require_once(SOURCEDIR . '/BrowserDetector.class.php'); |
||
104 | require_once(SOURCEDIR . '/ErrorContext.class.php'); |
||
105 | require_once(SUBSDIR . '/Util.class.php'); |
||
106 | require_once(SUBSDIR . '/TemplateLayers.class.php'); |
||
107 | require_once(SOURCEDIR . '/Action.controller.php'); |
||
108 | |||
109 | // Clean the request variables. |
||
110 | cleanRequest(); |
||
111 | |||
112 | // Initiate the database connection and define some database functions to use. |
||
113 | loadDatabase(); |
||
114 | |||
115 | // Load settings from the database. |
||
116 | reloadSettings(); |
||
117 | |||
118 | // Seed the random generator? |
||
119 | elk_seed_generator(); |
||
120 | |||
121 | // Check on any hacking attempts. |
||
122 | if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS'])) |
||
123 | die('Hacking attempt...'); |
||
124 | elseif (isset($_REQUEST['ssi_theme']) && (int) $_REQUEST['ssi_theme'] == (int) $ssi_theme) |
||
125 | die('Hacking attempt...'); |
||
126 | elseif (isset($_COOKIE['ssi_theme']) && (int) $_COOKIE['ssi_theme'] == (int) $ssi_theme) |
||
127 | die('Hacking attempt...'); |
||
128 | elseif (isset($_REQUEST['ssi_layers'], $ssi_layers) && (@get_magic_quotes_gpc() ? stripslashes($_REQUEST['ssi_layers']) : $_REQUEST['ssi_layers']) == $ssi_layers) |
||
129 | die('Hacking attempt...'); |
||
130 | if (isset($_REQUEST['context'])) |
||
131 | die('Hacking attempt...'); |
||
132 | |||
133 | // Gzip output? (because it must be boolean and true, this can't be hacked.) |
||
134 | if (isset($ssi_gzip) && $ssi_gzip === true && ini_get('zlib.output_compression') != '1' && ini_get('output_handler') != 'ob_gzhandler' && version_compare(PHP_VERSION, '4.2.0', '>=')) |
||
135 | ob_start('ob_gzhandler'); |
||
136 | else |
||
137 | $modSettings['enableCompressedOutput'] = '0'; |
||
138 | |||
139 | // Primarily, this is to fix the URLs... |
||
140 | ob_start('ob_sessrewrite'); |
||
141 | |||
142 | // Start the session... known to scramble SSI includes in cases... |
||
143 | if (!headers_sent()) |
||
144 | loadSession(); |
||
145 | else |
||
146 | { |
||
147 | if (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()])) |
||
148 | { |
||
149 | // Make a stab at it, but ignore the E_WARNINGs generated because we can't send headers. |
||
150 | $temp = error_reporting(error_reporting() & !E_WARNING); |
||
151 | loadSession(); |
||
152 | error_reporting($temp); |
||
153 | } |
||
154 | |||
155 | if (!isset($_SESSION['session_value'])) |
||
156 | { |
||
157 | $_SESSION['session_var'] = substr(md5(mt_rand() . session_id() . mt_rand()), 0, rand(7, 12)); |
||
158 | $_SESSION['session_value'] = md5(session_id() . mt_rand()); |
||
159 | } |
||
160 | $sc = $_SESSION['session_value']; |
||
161 | // This is here only to avoid session errors in PHP7 |
||
162 | // microtime effectively forces the replacing of the session in the db each |
||
163 | // time the page is loaded |
||
164 | $_SESSION['mictrotime'] = microtime(); |
||
165 | } |
||
166 | |||
167 | // Get rid of $board and $topic... do stuff loadBoard would do. |
||
168 | unset($board, $topic); |
||
169 | $user_info['is_mod'] = false; |
||
170 | $context['user']['is_mod'] = &$user_info['is_mod']; |
||
171 | $context['linktree'] = array(); |
||
172 | |||
173 | // Load the user and their cookie, as well as their settings. |
||
174 | loadUserSettings(); |
||
175 | |||
176 | // Load the current user's permissions.... |
||
177 | loadPermissions(); |
||
178 | |||
179 | // Load BadBehavior functions |
||
180 | loadBadBehavior(); |
||
181 | |||
182 | // Load the current or SSI theme. (just use $ssi_theme = id_theme;) |
||
183 | loadTheme(isset($ssi_theme) ? (int) $ssi_theme : 0); |
||
184 | |||
185 | // @todo: probably not the best place, but somewhere it should be set... |
||
186 | if (!headers_sent()) |
||
187 | header('Content-Type: text/html; charset=UTF-8'); |
||
188 | |||
189 | // Take care of any banning that needs to be done. |
||
190 | if (isset($_REQUEST['ssi_ban']) || (isset($ssi_ban) && $ssi_ban === true)) |
||
191 | is_not_banned(); |
||
192 | |||
193 | // Do we allow guests in here? |
||
194 | if (empty($ssi_guest_access) && empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && basename($_SERVER['PHP_SELF']) != 'SSI.php') |
||
195 | { |
||
196 | require_once(CONTROLLERDIR . '/Auth.controller.php'); |
||
197 | $controller = new Auth_Controller(); |
||
198 | $controller->action_kickguest(); |
||
199 | obExit(null, true); |
||
200 | } |
||
201 | |||
202 | // Load the stuff like the menu bar, etc. |
||
203 | if (isset($ssi_layers)) |
||
204 | { |
||
205 | $template_layers = Template_Layers::getInstance(); |
||
206 | $template_layers->removeAll(); |
||
207 | foreach ($ssi_layers as $layer) |
||
208 | $template_layers->addBegin($layer); |
||
209 | template_header(); |
||
210 | } |
||
211 | else |
||
212 | setupThemeContext(); |
||
213 | |||
214 | // We need to set up user agent, and make more checks on the request |
||
215 | $req = request(); |
||
216 | |||
217 | // Make sure they didn't muss around with the settings... but only if it's not cli. |
||
218 | if (isset($_SERVER['REMOTE_ADDR']) && session_id() == '') |
||
219 | trigger_error($txt['ssi_session_broken'], E_USER_NOTICE); |
||
220 | |||
221 | // Without visiting the forum this session variable might not be set on submit. |
||
222 | if (!isset($_SESSION['USER_AGENT']) && (!isset($_GET['ssi_function']) || $_GET['ssi_function'] !== 'pollVote')) |
||
223 | $_SESSION['USER_AGENT'] = $req->user_agent(); |
||
224 | |||
225 | // Have the ability to easily add functions to SSI. |
||
226 | call_integration_hook('integrate_SSI'); |
||
227 | |||
228 | // Call a function passed by GET. |
||
229 | if (isset($_GET['ssi_function']) && function_exists('ssi_' . $_GET['ssi_function']) && (!empty($modSettings['allow_guestAccess']) || !$user_info['is_guest'])) |
||
230 | { |
||
231 | call_user_func('ssi_' . $_GET['ssi_function']); |
||
232 | exit; |
||
233 | } |
||
234 | |||
235 | if (isset($_GET['ssi_function'])) |
||
236 | exit; |
||
237 | // You shouldn't just access SSI.php directly by URL!! |
||
238 | elseif (basename($_SERVER['PHP_SELF']) == 'SSI.php') |
||
239 | die(sprintf($txt['ssi_not_direct'], $user_info['is_admin'] ? '\'' . addslashes(__FILE__) . '\'' : '\'SSI.php\'')); |
||
240 | |||
241 | error_reporting($ssi_error_reporting); |
||
242 | if (function_exists('set_magic_quotes_runtime')) |
||
243 | @set_magic_quotes_runtime($ssi_magic_quotes_runtime); |
||
244 | |||
245 | return true; |
||
246 | |||
247 | /** |
||
248 | * This shuts down the SSI and shows the footer. |
||
249 | */ |
||
250 | function ssi_shutdown() |
||
251 | { |
||
252 | if (!isset($_GET['ssi_function']) || $_GET['ssi_function'] != 'shutdown') |
||
253 | template_footer(); |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * Display a welcome message, like: |
||
258 | * "Hey, User, you have 0 messages, 0 are new." |
||
259 | * |
||
260 | * @param string $output_method |
||
261 | */ |
||
262 | function ssi_welcome($output_method = 'echo') |
||
263 | { |
||
264 | global $context, $txt, $scripturl; |
||
265 | |||
266 | if ($output_method == 'echo') |
||
267 | { |
||
268 | if ($context['user']['is_guest']) |
||
269 | echo replaceBasicActionUrl($txt[$context['can_register'] ? 'welcome_guest_register' : 'welcome_guest']); |
||
270 | else |
||
271 | echo $txt['hello_member'], ' <strong>', $context['user']['name'], '</strong>', allowedTo('pm_read') ? ', ' . (empty($context['user']['messages']) ? $txt['msg_alert_no_messages'] : (($context['user']['messages'] == 1 ? sprintf($txt['msg_alert_one_message'], $scripturl . '?action=pm') : sprintf($txt['msg_alert_many_message'], $scripturl . '?action=pm', $context['user']['messages'])) . ', ' . ($context['user']['unread_messages'] == 1 ? $txt['msg_alert_one_new'] : sprintf($txt['msg_alert_many_new'], $context['user']['unread_messages'])))) : ''; |
||
272 | } |
||
273 | // Don't echo... then do what?! |
||
274 | else |
||
275 | return $context['user']; |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * Display a menu bar, like is displayed at the top of the forum. |
||
280 | * |
||
281 | * @param string $output_method |
||
282 | */ |
||
283 | function ssi_menubar($output_method = 'echo') |
||
284 | { |
||
285 | global $context; |
||
286 | |||
287 | if ($output_method == 'echo') |
||
288 | template_menu(); |
||
289 | // What else could this do? |
||
290 | else |
||
291 | return $context['menu_buttons']; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Show a logout link. |
||
296 | * |
||
297 | * @param string $redirect_to |
||
298 | * @param string $output_method = 'echo' |
||
299 | */ |
||
300 | function ssi_logout($redirect_to = '', $output_method = 'echo') |
||
301 | { |
||
302 | global $context, $txt, $scripturl; |
||
303 | |||
304 | if ($redirect_to != '') |
||
305 | $_SESSION['logout_url'] = $redirect_to; |
||
306 | |||
307 | // Guests can't log out. |
||
308 | if ($context['user']['is_guest']) |
||
309 | return false; |
||
310 | |||
311 | $link = '<a href="' . $scripturl . '?action=logout;' . $context['session_var'] . '=' . $context['session_id'] . '">' . $txt['logout'] . '</a>'; |
||
312 | |||
313 | if ($output_method == 'echo') |
||
314 | echo $link; |
||
315 | else |
||
316 | return $link; |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Recent post list: |
||
321 | * [board] Subject by Poster Date |
||
322 | * |
||
323 | * @todo this may use getLastPosts with some modification |
||
324 | * |
||
325 | * @param int $num_recent |
||
326 | * @param int[]|null $exclude_boards |
||
327 | * @param int[]|null $include_boards |
||
328 | * @param string $output_method |
||
329 | * @param bool $limit_body |
||
330 | */ |
||
331 | function ssi_recentPosts($num_recent = 8, $exclude_boards = null, $include_boards = null, $output_method = 'echo', $limit_body = true) |
||
332 | { |
||
333 | global $modSettings; |
||
334 | |||
335 | // Excluding certain boards... |
||
336 | if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0) |
||
337 | $exclude_boards = array($modSettings['recycle_board']); |
||
338 | else |
||
339 | $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards)); |
||
340 | |||
341 | // What about including certain boards - note we do some protection here as pre-2.0 didn't have this parameter. |
||
342 | if (is_array($include_boards) || (int) $include_boards === $include_boards) |
||
343 | { |
||
344 | $include_boards = is_array($include_boards) ? $include_boards : array($include_boards); |
||
345 | } |
||
346 | elseif ($include_boards != null) |
||
347 | { |
||
348 | $include_boards = array(); |
||
349 | } |
||
350 | |||
351 | // Let's restrict the query boys (and girls) |
||
352 | $query_where = ' |
||
353 | m.id_msg >= {int:min_message_id} |
||
354 | ' . (empty($exclude_boards) ? '' : ' |
||
355 | AND b.id_board NOT IN ({array_int:exclude_boards})') . ' |
||
356 | ' . ($include_boards === null ? '' : ' |
||
357 | AND b.id_board IN ({array_int:include_boards})') . ' |
||
358 | AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' |
||
359 | AND m.approved = {int:is_approved}' : ''); |
||
360 | |||
361 | $query_where_params = array( |
||
362 | 'is_approved' => 1, |
||
363 | 'include_boards' => $include_boards === null ? '' : $include_boards, |
||
364 | 'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards, |
||
365 | 'min_message_id' => $modSettings['maxMsgID'] - 25 * min($num_recent, 5), |
||
366 | ); |
||
367 | |||
368 | // Past to this simpleton of a function... |
||
369 | return ssi_queryPosts($query_where, $query_where_params, $num_recent, 'm.id_msg DESC', $output_method, $limit_body); |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * Fetch a post with a particular ID. |
||
374 | * By default will only show if you have permission |
||
375 | * to the see the board in question - this can be overriden. |
||
376 | * |
||
377 | * @todo this may use getRecentPosts with some modification |
||
378 | * |
||
379 | * @param int[] $post_ids |
||
380 | * @param bool $override_permissions |
||
381 | * @param string $output_method = 'echo' |
||
382 | */ |
||
383 | function ssi_fetchPosts($post_ids = array(), $override_permissions = false, $output_method = 'echo') |
||
384 | { |
||
385 | global $modSettings; |
||
386 | |||
387 | if (empty($post_ids)) |
||
388 | return; |
||
389 | |||
390 | // Allow the user to request more than one - why not? |
||
391 | $post_ids = is_array($post_ids) ? $post_ids : array($post_ids); |
||
392 | |||
393 | // Restrict the posts required... |
||
394 | $query_where = ' |
||
395 | m.id_msg IN ({array_int:message_list})' . ($override_permissions ? '' : ' |
||
396 | AND {query_wanna_see_board}') . ($modSettings['postmod_active'] ? ' |
||
397 | AND m.approved = {int:is_approved}' : ''); |
||
398 | $query_where_params = array( |
||
399 | 'message_list' => $post_ids, |
||
400 | 'is_approved' => 1, |
||
401 | ); |
||
402 | |||
403 | // Then make the query and dump the data. |
||
404 | return ssi_queryPosts($query_where, $query_where_params, '', 'm.id_msg DESC', $output_method, false, $override_permissions); |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * This removes code duplication in other queries |
||
409 | * - don't call it direct unless you really know what you're up to. |
||
410 | * |
||
411 | * @todo if ssi_recentPosts and ssi_fetchPosts will use Recent.subs.php this can be removed |
||
412 | * |
||
413 | * @param string $query_where |
||
414 | * @param mixed[] $query_where_params |
||
415 | * @param int $query_limit |
||
416 | * @param string $query_order |
||
417 | * @param string $output_method = 'echo' |
||
418 | * @param bool $limit_body |
||
419 | * @param bool $override_permissions |
||
420 | */ |
||
421 | function ssi_queryPosts($query_where = '', $query_where_params = array(), $query_limit = 10, $query_order = 'm.id_msg DESC', $output_method = 'echo', $limit_body = false, $override_permissions = false) |
||
422 | { |
||
423 | global $scripturl, $txt, $user_info, $modSettings; |
||
424 | |||
425 | $db = database(); |
||
426 | |||
427 | // Find all the posts. Newer ones will have higher IDs. |
||
428 | $request = $db->query('substring', ' |
||
429 | SELECT |
||
430 | m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg, m.id_board, b.name AS board_name, |
||
431 | IFNULL(mem.real_name, m.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : ' |
||
432 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= m.id_msg_modified AS is_read, |
||
433 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from') . ', ' . ($limit_body ? 'SUBSTRING(m.body, 1, 384) AS body' : 'm.body') . ', m.smileys_enabled |
||
434 | FROM {db_prefix}messages AS m |
||
435 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) |
||
436 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (!$user_info['is_guest'] ? ' |
||
437 | LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = m.id_topic AND lt.id_member = {int:current_member}) |
||
438 | LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = m.id_board AND lmr.id_member = {int:current_member})' : '') . ' |
||
439 | WHERE 1=1 ' . ($override_permissions ? '' : ' |
||
440 | AND {query_wanna_see_board}') . ($modSettings['postmod_active'] ? ' |
||
441 | AND m.approved = {int:is_approved}' : '') . ' |
||
442 | ' . (empty($query_where) ? '' : 'AND ' . $query_where) . ' |
||
443 | ORDER BY ' . $query_order . ' |
||
444 | ' . ($query_limit == '' ? '' : 'LIMIT {int:query_limit}'), |
||
445 | array_merge($query_where_params, array( |
||
446 | 'current_member' => $user_info['id'], |
||
447 | 'is_approved' => 1, |
||
448 | 'query_limit' => $query_limit, |
||
449 | )) |
||
450 | ); |
||
451 | $posts = array(); |
||
452 | while ($row = $db->fetch_assoc($request)) |
||
453 | { |
||
454 | $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']); |
||
455 | |||
456 | // Censor it! |
||
457 | censorText($row['subject']); |
||
458 | censorText($row['body']); |
||
459 | |||
460 | $preview = strip_tags(strtr($row['body'], array('<br />' => ' '))); |
||
461 | |||
462 | // Build the array. |
||
463 | $posts[] = array( |
||
464 | 'id' => $row['id_msg'], |
||
465 | 'board' => array( |
||
466 | 'id' => $row['id_board'], |
||
467 | 'name' => $row['board_name'], |
||
468 | 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', |
||
469 | 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>' |
||
470 | ), |
||
471 | 'topic' => $row['id_topic'], |
||
472 | 'poster' => array( |
||
473 | 'id' => $row['id_member'], |
||
474 | 'name' => $row['poster_name'], |
||
475 | 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], |
||
476 | 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' |
||
477 | ), |
||
478 | 'subject' => $row['subject'], |
||
479 | 'short_subject' => Util::shorten_text($row['subject'], !empty($modSettings['ssi_subject_length']) ? $modSettings['ssi_subject_length'] : 24), |
||
480 | 'preview' => Util::shorten_text($preview, !empty($modSettings['ssi_preview_length']) ? $modSettings['ssi_preview_length'] : 128), |
||
481 | 'body' => $row['body'], |
||
482 | 'time' => standardTime($row['poster_time']), |
||
483 | 'html_time' => htmlTime($row['poster_time']), |
||
484 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
485 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new', |
||
486 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '" rel="nofollow">' . $row['subject'] . '</a>', |
||
487 | 'new' => !empty($row['is_read']), |
||
488 | 'is_new' => empty($row['is_read']), |
||
489 | 'new_from' => $row['new_from'], |
||
490 | ); |
||
491 | } |
||
492 | $db->free_result($request); |
||
493 | |||
494 | // Just return it. |
||
495 | if ($output_method != 'echo' || empty($posts)) |
||
496 | return $posts; |
||
497 | |||
498 | echo ' |
||
499 | <table class="ssi_table">'; |
||
500 | foreach ($posts as $post) |
||
501 | echo ' |
||
502 | <tr> |
||
503 | <td class="righttext"> |
||
504 | [', $post['board']['link'], '] |
||
505 | </td> |
||
506 | <td class="top"> |
||
507 | <a href="', $post['href'], '">', $post['subject'], '</a> |
||
508 | ', $txt['by'], ' ', $post['poster']['link'], ' |
||
509 | ', $post['is_new'] ? '<a href="' . $scripturl . '?topic=' . $post['topic'] . '.msg' . $post['new_from'] . ';topicseen#new" rel="nofollow"><span class="new_posts">' . $txt['new'] . '</span></a>' : '', ' |
||
510 | </td> |
||
511 | <td class="righttext"> |
||
512 | ', $post['time'], ' |
||
513 | </td> |
||
514 | </tr>'; |
||
515 | echo ' |
||
516 | </table>'; |
||
517 | } |
||
518 | |||
519 | /** |
||
520 | * Recent topic list: |
||
521 | * [board] Subject by Poster Date |
||
522 | * |
||
523 | * @param int $num_recent |
||
524 | * @param int[]|null $exclude_boards |
||
525 | * @param bool|null $include_boards |
||
526 | * @param string $output_method = 'echo' |
||
527 | */ |
||
528 | function ssi_recentTopics($num_recent = 8, $exclude_boards = null, $include_boards = null, $output_method = 'echo') |
||
529 | { |
||
530 | global $settings, $scripturl, $txt, $user_info, $modSettings; |
||
531 | |||
532 | $db = database(); |
||
533 | |||
534 | if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0) |
||
535 | $exclude_boards = array($modSettings['recycle_board']); |
||
536 | else |
||
537 | $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards)); |
||
538 | |||
539 | // Only some boards?. |
||
540 | if (is_array($include_boards) || (int) $include_boards === $include_boards) |
||
541 | $include_boards = is_array($include_boards) ? $include_boards : array($include_boards); |
||
542 | elseif ($include_boards != null) |
||
543 | { |
||
544 | $output_method = $include_boards; |
||
545 | $include_boards = array(); |
||
546 | } |
||
547 | |||
548 | require_once(SUBSDIR . '/MessageIndex.subs.php'); |
||
549 | $icon_sources = MessageTopicIcons(); |
||
550 | |||
551 | // Find all the posts in distinct topics. Newer ones will have higher IDs. |
||
552 | $request = $db->query('', ' |
||
553 | SELECT |
||
554 | t.id_topic, b.id_board, b.name AS board_name |
||
555 | FROM {db_prefix}topics AS t |
||
556 | INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) |
||
557 | LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) |
||
558 | WHERE t.id_last_msg >= {int:min_message_id}' . (empty($exclude_boards) ? '' : ' |
||
559 | AND b.id_board NOT IN ({array_int:exclude_boards})') . '' . (empty($include_boards) ? '' : ' |
||
560 | AND b.id_board IN ({array_int:include_boards})') . ' |
||
561 | AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' |
||
562 | AND t.approved = {int:is_approved} |
||
563 | AND ml.approved = {int:is_approved}' : '') . ' |
||
564 | ORDER BY t.id_last_msg DESC |
||
565 | LIMIT {int:num_recent}', |
||
566 | array( |
||
567 | 'include_boards' => empty($include_boards) ? '' : $include_boards, |
||
568 | 'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards, |
||
569 | 'min_message_id' => $modSettings['maxMsgID'] - 35 * min($num_recent, 5), |
||
570 | 'is_approved' => 1, |
||
571 | 'num_recent' => $num_recent, |
||
572 | ) |
||
573 | ); |
||
574 | $topics = array(); |
||
575 | while ($row = $db->fetch_assoc($request)) |
||
576 | $topics[$row['id_topic']] = $row; |
||
577 | $db->free_result($request); |
||
578 | |||
579 | // Did we find anything? If not, bail. |
||
580 | if (empty($topics)) |
||
581 | return array(); |
||
582 | |||
583 | // Find all the posts in distinct topics. Newer ones will have higher IDs. |
||
584 | $request = $db->query('substring', ' |
||
585 | SELECT |
||
586 | ml.poster_time, mf.subject, ml.id_member, ml.id_msg, t.id_topic, t.num_replies, t.num_views, mg.online_color, |
||
587 | IFNULL(mem.real_name, ml.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : ' |
||
588 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= ml.id_msg_modified AS is_read, |
||
589 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from') . ', SUBSTRING(ml.body, 1, 384) AS body, ml.smileys_enabled, ml.icon |
||
590 | FROM {db_prefix}topics AS t |
||
591 | INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) |
||
592 | INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg) |
||
593 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = ml.id_member)' . (!$user_info['is_guest'] ? ' |
||
594 | LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) |
||
595 | LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})' : '') . ' |
||
596 | LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = mem.id_group) |
||
597 | WHERE t.id_topic IN ({array_int:topic_list}) |
||
598 | ORDER BY t.id_last_msg DESC', |
||
599 | array( |
||
600 | 'current_member' => $user_info['id'], |
||
601 | 'topic_list' => array_keys($topics), |
||
602 | ) |
||
603 | ); |
||
604 | $posts = array(); |
||
605 | while ($row = $db->fetch_assoc($request)) |
||
606 | { |
||
607 | $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), array('<br />' => ' '))); |
||
608 | if (Util::strlen($row['body']) > 128) |
||
609 | $row['body'] = Util::substr($row['body'], 0, 128) . '...'; |
||
610 | |||
611 | // Censor the subject. |
||
612 | censorText($row['subject']); |
||
613 | censorText($row['body']); |
||
614 | |||
615 | if (!empty($modSettings['messageIconChecks_enable']) && !isset($icon_sources[$row['icon']])) |
||
616 | $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url'; |
||
617 | |||
618 | // Build the array. |
||
619 | $posts[] = array( |
||
620 | 'board' => array( |
||
621 | 'id' => $topics[$row['id_topic']]['id_board'], |
||
622 | 'name' => $topics[$row['id_topic']]['board_name'], |
||
623 | 'href' => $scripturl . '?board=' . $topics[$row['id_topic']]['id_board'] . '.0', |
||
624 | 'link' => '<a href="' . $scripturl . '?board=' . $topics[$row['id_topic']]['id_board'] . '.0">' . $topics[$row['id_topic']]['board_name'] . '</a>', |
||
625 | ), |
||
626 | 'topic' => $row['id_topic'], |
||
627 | 'poster' => array( |
||
628 | 'id' => $row['id_member'], |
||
629 | 'name' => $row['poster_name'], |
||
630 | 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], |
||
631 | 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' |
||
632 | ), |
||
633 | 'subject' => $row['subject'], |
||
634 | 'replies' => $row['num_replies'], |
||
635 | 'views' => $row['num_views'], |
||
636 | 'short_subject' => Util::shorten_text($row['subject'], 25), |
||
637 | 'preview' => $row['body'], |
||
638 | 'time' => standardTime($row['poster_time']), |
||
639 | 'html_time' => htmlTime($row['poster_time']), |
||
640 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
641 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new', |
||
642 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#new" rel="nofollow">' . $row['subject'] . '</a>', |
||
643 | // Retained for compatibility - is technically incorrect! |
||
644 | 'new' => !empty($row['is_read']), |
||
645 | 'is_new' => empty($row['is_read']), |
||
646 | 'new_from' => $row['new_from'], |
||
647 | 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.png" style="vertical-align: middle;" alt="' . $row['icon'] . '" />', |
||
648 | ); |
||
649 | } |
||
650 | $db->free_result($request); |
||
651 | |||
652 | // Just return it. |
||
653 | if ($output_method != 'echo' || empty($posts)) |
||
654 | return $posts; |
||
655 | |||
656 | echo ' |
||
657 | <table class="ssi_table">'; |
||
658 | foreach ($posts as $post) |
||
659 | echo ' |
||
660 | <tr> |
||
661 | <td class="righttext top"> |
||
662 | [', $post['board']['link'], '] |
||
663 | </td> |
||
664 | <td class="top"> |
||
665 | <a href="', $post['href'], '">', $post['subject'], '</a> |
||
666 | ', $txt['by'], ' ', $post['poster']['link'], ' |
||
667 | ', !$post['is_new'] ? '' : '<a href="' . $scripturl . '?topic=' . $post['topic'] . '.msg' . $post['new_from'] . ';topicseen#new" rel="nofollow"><span class="new_posts">' . $txt['new'] . '</span></a>', ' |
||
668 | </td> |
||
669 | <td class="righttext"> |
||
670 | ', $post['time'], ' |
||
671 | </td> |
||
672 | </tr>'; |
||
673 | echo ' |
||
674 | </table>'; |
||
675 | } |
||
676 | |||
677 | /** |
||
678 | * Show the top poster's name and profile link. |
||
679 | * |
||
680 | * @param int $topNumber |
||
681 | * @param string $output_method = 'echo' |
||
682 | */ |
||
683 | function ssi_topPoster($topNumber = 1, $output_method = 'echo') |
||
684 | { |
||
685 | require_once(SUBSDIR . '/Stats.subs.php'); |
||
686 | $top_posters = topPosters($topNumber); |
||
687 | |||
688 | // Just return all the top posters. |
||
689 | if ($output_method != 'echo') |
||
690 | return $top_posters; |
||
691 | |||
692 | // Make a quick array to list the links in. |
||
693 | $temp_array = array(); |
||
694 | foreach ($top_posters as $member) |
||
695 | $temp_array[] = $member['link']; |
||
696 | |||
697 | echo implode(', ', $temp_array); |
||
698 | } |
||
699 | |||
700 | /** |
||
701 | * Show boards by activity. |
||
702 | * |
||
703 | * @param int $num_top |
||
704 | * @param string $output_method = 'echo' |
||
705 | */ |
||
706 | function ssi_topBoards($num_top = 10, $output_method = 'echo') |
||
707 | { |
||
708 | global $txt; |
||
709 | |||
710 | require_once(SUBSDIR . '/Stats.subs.php'); |
||
711 | |||
712 | // Find boards with lots of posts. |
||
713 | $boards = topBoards($num_top, true); |
||
714 | |||
715 | foreach ($boards as $id => $board) |
||
716 | $boards[$id]['new'] = empty($board['is_read']); |
||
717 | |||
718 | // If we shouldn't output or have nothing to output, just jump out. |
||
719 | if ($output_method != 'echo' || empty($boards)) |
||
720 | return $boards; |
||
721 | |||
722 | echo ' |
||
723 | <table class="ssi_table"> |
||
724 | <tr> |
||
725 | <th class="lefttext">', $txt['board'], '</th> |
||
726 | <th class="righttext">', $txt['board_topics'], '</th> |
||
727 | <th class="righttext">', $txt['posts'], '</th> |
||
728 | </tr>'; |
||
729 | foreach ($boards as $board) |
||
730 | echo ' |
||
731 | <tr> |
||
732 | <td>', $board['new'] ? ' <a href="' . $board['href'] . '"><span class="new_posts">' . $txt['new'] . '</span></a> ' : '', $board['link'], '</td> |
||
733 | <td class="righttext">', $board['num_topics'], '</td> |
||
734 | <td class="righttext">', $board['num_posts'], '</td> |
||
735 | </tr>'; |
||
736 | echo ' |
||
737 | </table>'; |
||
738 | } |
||
739 | |||
740 | /** |
||
741 | * Shows the top topics. |
||
742 | * |
||
743 | * @param string $type |
||
744 | * @param 10 $num_topics |
||
745 | * @param string $output_method = 'echo' |
||
746 | */ |
||
747 | function ssi_topTopics($type = 'replies', $num_topics = 10, $output_method = 'echo') |
||
748 | { |
||
749 | global $txt, $scripturl; |
||
750 | |||
751 | require_once(SUBSDIR . '/Stats.subs.php'); |
||
752 | |||
753 | if (function_exists('topTopic' . ucfirst($type))) |
||
754 | $function = 'topTopic' . ucfirst($type); |
||
755 | else |
||
756 | $function = 'topTopicReplies'; |
||
757 | |||
758 | $topics = $function($num_topics); |
||
759 | |||
760 | foreach ($topics as $topic_id => $row) |
||
761 | { |
||
762 | censorText($row['subject']); |
||
763 | |||
764 | $topics[$topic_id]['href'] = $scripturl . '?topic=' . $row['id'] . '.0'; |
||
765 | $topics[$topic_id]['link'] = '<a href="' . $scripturl . '?topic=' . $row['id'] . '.0">' . $row['subject'] . '</a>'; |
||
766 | } |
||
767 | |||
768 | if ($output_method != 'echo' || empty($topics)) |
||
769 | return $topics; |
||
770 | |||
771 | echo ' |
||
772 | <table class="top_topic ssi_table"> |
||
773 | <tr> |
||
774 | <th class="link"></th> |
||
775 | <th class="views">', $txt['views'], '</th> |
||
776 | <th class="num_replies">', $txt['replies'], '</th> |
||
777 | </tr>'; |
||
778 | foreach ($topics as $topic) |
||
779 | echo ' |
||
780 | <tr> |
||
781 | <td class="link"> |
||
782 | ', $topic['link'], ' |
||
783 | </td> |
||
784 | <td class="views">', $topic['num_views'], '</td> |
||
785 | <td class="num_replies">', $topic['num_replies'], '</td> |
||
786 | </tr>'; |
||
787 | echo ' |
||
788 | </table>'; |
||
789 | } |
||
790 | |||
791 | /** |
||
792 | * Shows the top topics, by replies. |
||
793 | * |
||
794 | * @param int $num_topics = 10 |
||
795 | * @param string $output_method = 'echo' |
||
796 | */ |
||
797 | function ssi_topTopicsReplies($num_topics = 10, $output_method = 'echo') |
||
798 | { |
||
799 | return ssi_topTopics('replies', $num_topics, $output_method); |
||
800 | } |
||
801 | |||
802 | /** |
||
803 | * Shows the top topics, by views. |
||
804 | * |
||
805 | * @param int $num_topics = 10 |
||
806 | * @param string $output_method = 'echo' |
||
807 | */ |
||
808 | function ssi_topTopicsViews($num_topics = 10, $output_method = 'echo') |
||
809 | { |
||
810 | return ssi_topTopics('views', $num_topics, $output_method); |
||
811 | } |
||
812 | |||
813 | /** |
||
814 | * Show a link to the latest member: |
||
815 | * Please welcome, Someone, out latest member. |
||
816 | * |
||
817 | * @param string $output_method = 'echo' |
||
818 | */ |
||
819 | function ssi_latestMember($output_method = 'echo') |
||
820 | { |
||
821 | global $txt, $context; |
||
822 | |||
823 | if ($output_method == 'echo') |
||
824 | echo ' |
||
825 | ', sprintf($txt['welcome_newest_member'], $context['common_stats']['latest_member']['link']), '<br />'; |
||
826 | else |
||
827 | return $context['common_stats']['latest_member']; |
||
828 | } |
||
829 | |||
830 | /** |
||
831 | * Fetch a random member - if type set to 'day' will only change once a day! |
||
832 | * |
||
833 | * @param string $random_type = '' |
||
834 | * @param string $output_method = 'echo' |
||
835 | */ |
||
836 | function ssi_randomMember($random_type = '', $output_method = 'echo') |
||
837 | { |
||
838 | global $modSettings; |
||
839 | |||
840 | // If we're looking for something to stay the same each day then seed the generator. |
||
841 | if ($random_type == 'day') |
||
842 | { |
||
843 | // Set the seed to change only once per day. |
||
844 | mt_srand(floor(time() / 86400)); |
||
845 | } |
||
846 | |||
847 | // Get the lowest ID we're interested in. |
||
848 | $member_id = mt_rand(1, $modSettings['latestMember']); |
||
849 | |||
850 | $result = ssi_queryMembers('member_greater_equal', $member_id, 1, 'id_member ASC', $output_method); |
||
851 | |||
852 | // If we got nothing do the reverse - in case of unactivated members. |
||
853 | if (empty($result)) |
||
854 | $result = ssi_queryMembers('member_lesser_equal', $member_id, 1, 'id_member DESC', $output_method); |
||
855 | |||
856 | // Just to be sure put the random generator back to something... random. |
||
857 | if ($random_type != '') |
||
858 | mt_srand(time()); |
||
859 | |||
860 | return $result; |
||
861 | } |
||
862 | |||
863 | /** |
||
864 | * Fetch a specific member. |
||
865 | * |
||
866 | * @param int[] $member_ids = array() |
||
867 | * @param string $output_method = 'echo' |
||
868 | */ |
||
869 | function ssi_fetchMember($member_ids = array(), $output_method = 'echo') |
||
870 | { |
||
871 | if (empty($member_ids)) |
||
872 | return; |
||
873 | |||
874 | // Can have more than one member if you really want... |
||
875 | $member_ids = is_array($member_ids) ? $member_ids : array($member_ids); |
||
876 | |||
877 | // Then make the query and dump the data. |
||
878 | return ssi_queryMembers('members', $member_ids, '', 'id_member', $output_method); |
||
879 | } |
||
880 | |||
881 | /** |
||
882 | * Fetch a specific member. |
||
883 | * |
||
884 | * @param null $group_id |
||
885 | * @param string $output_method = 'echo' |
||
886 | */ |
||
887 | function ssi_fetchGroupMembers($group_id = null, $output_method = 'echo') |
||
888 | { |
||
889 | if ($group_id === null) |
||
890 | return; |
||
891 | |||
892 | return ssi_queryMembers('group_list', is_array($group_id) ? $group_id : array($group_id), '', 'real_name', $output_method); |
||
893 | } |
||
894 | |||
895 | /** |
||
896 | * Fetch some member data! |
||
897 | * |
||
898 | * @param string|null $query_where |
||
899 | * @param string|string[] $query_where_params |
||
900 | * @param string $query_limit |
||
901 | * @param string $query_order |
||
902 | * @param string $output_method |
||
903 | */ |
||
904 | function ssi_queryMembers($query_where = null, $query_where_params = array(), $query_limit = '', $query_order = 'id_member DESC', $output_method = 'echo') |
||
905 | { |
||
906 | global $memberContext; |
||
907 | |||
908 | if ($query_where === null) |
||
909 | return; |
||
910 | |||
911 | require_once(SUBSDIR . '/Members.subs.php'); |
||
912 | $members_data = retrieveMemberData(array( |
||
913 | $query_where => $query_where_params, |
||
914 | 'limit' => !empty($query_limit) ? (int) $query_limit : 10, |
||
915 | 'order_by' => $query_order, |
||
916 | 'activated_status' => 1, |
||
917 | )); |
||
918 | |||
919 | $members = array(); |
||
920 | foreach ($members_data['member_info'] as $row) |
||
921 | $members[] = $row['id']; |
||
922 | |||
923 | if (empty($members)) |
||
924 | return array(); |
||
925 | |||
926 | // Load the members. |
||
927 | loadMemberData($members); |
||
928 | |||
929 | // Draw the table! |
||
930 | if ($output_method == 'echo') |
||
931 | echo ' |
||
932 | <table class="ssi_table">'; |
||
933 | |||
934 | $query_members = array(); |
||
935 | foreach ($members as $member) |
||
936 | { |
||
937 | // Load their context data. |
||
938 | if (!loadMemberContext($member)) |
||
939 | continue; |
||
940 | |||
941 | // Store this member's information. |
||
942 | $query_members[$member] = $memberContext[$member]; |
||
943 | |||
944 | // Only do something if we're echo'ing. |
||
945 | if ($output_method == 'echo') |
||
946 | echo ' |
||
947 | <tr> |
||
948 | <td class="centertext"> |
||
949 | ', $query_members[$member]['link'], ' |
||
950 | <br />', $query_members[$member]['blurb'], ' |
||
951 | <br />', $query_members[$member]['avatar']['image'], ' |
||
952 | </td> |
||
953 | </tr>'; |
||
954 | } |
||
955 | |||
956 | // End the table if appropriate. |
||
957 | if ($output_method == 'echo') |
||
958 | echo ' |
||
959 | </table>'; |
||
960 | |||
961 | // Send back the data. |
||
962 | return $query_members; |
||
963 | } |
||
964 | |||
965 | /** |
||
966 | * Show some basic stats: Total This: XXXX, etc. |
||
967 | * |
||
968 | * @param string $output_method |
||
969 | */ |
||
970 | function ssi_boardStats($output_method = 'echo') |
||
971 | { |
||
972 | global $txt, $scripturl, $modSettings; |
||
973 | |||
974 | if (!allowedTo('view_stats')) |
||
975 | return; |
||
976 | |||
977 | require_once(SUBSDIR . '/Boards.subs.php'); |
||
978 | require_once(SUBSDIR . '/Stats.subs.php'); |
||
979 | |||
980 | $totals = array( |
||
981 | 'members' => $modSettings['totalMembers'], |
||
982 | 'posts' => $modSettings['totalMessages'], |
||
983 | 'topics' => $modSettings['totalTopics'], |
||
984 | 'boards' => countBoards(), |
||
985 | 'categories' => numCategories(), |
||
986 | ); |
||
987 | |||
988 | if ($output_method != 'echo') |
||
989 | return $totals; |
||
990 | |||
991 | echo ' |
||
992 | ', $txt['total_members'], ': <a href="', $scripturl . '?action=memberlist">', comma_format($totals['members']), '</a><br /> |
||
993 | ', $txt['total_posts'], ': ', comma_format($totals['posts']), '<br /> |
||
994 | ', $txt['total_topics'], ': ', comma_format($totals['topics']), ' <br /> |
||
995 | ', $txt['total_cats'], ': ', comma_format($totals['categories']), '<br /> |
||
996 | ', $txt['total_boards'], ': ', comma_format($totals['boards']); |
||
997 | } |
||
998 | |||
999 | /** |
||
1000 | * Shows a list of online users: |
||
1001 | * YY Guests, ZZ Users and then a list... |
||
1002 | * |
||
1003 | * @param string $output_method |
||
1004 | */ |
||
1005 | function ssi_whosOnline($output_method = 'echo') |
||
1006 | { |
||
1007 | global $user_info, $txt, $settings; |
||
1008 | |||
1009 | require_once(SUBSDIR . '/MembersOnline.subs.php'); |
||
1010 | $membersOnlineOptions = array( |
||
1011 | 'show_hidden' => allowedTo('moderate_forum'), |
||
1012 | ); |
||
1013 | $return = getMembersOnlineStats($membersOnlineOptions); |
||
1014 | |||
1015 | // Add some redundancy for backwards compatibility reasons. |
||
1016 | if ($output_method != 'echo') |
||
1017 | return $return + array( |
||
1018 | 'users' => $return['users_online'], |
||
1019 | 'guests' => $return['num_guests'], |
||
1020 | 'hidden' => $return['num_users_hidden'], |
||
1021 | 'buddies' => $return['num_buddies'], |
||
1022 | 'num_users' => $return['num_users_online'], |
||
1023 | 'total_users' => $return['num_users_online'] + $return['num_guests'] + $return['num_spiders'], |
||
1024 | ); |
||
1025 | |||
1026 | echo ' |
||
1027 | ', comma_format($return['num_guests']), ' ', $return['num_guests'] == 1 ? $txt['guest'] : $txt['guests'], ', ', comma_format($return['num_users_online']), ' ', $return['num_users_online'] == 1 ? $txt['user'] : $txt['users']; |
||
1028 | |||
1029 | $bracketList = array(); |
||
1030 | if (!empty($user_info['buddies'])) |
||
1031 | $bracketList[] = comma_format($return['num_buddies']) . ' ' . ($return['num_buddies'] == 1 ? $txt['buddy'] : $txt['buddies']); |
||
1032 | if (!empty($return['num_spiders'])) |
||
1033 | $bracketList[] = comma_format($return['num_spiders']) . ' ' . ($return['num_spiders'] == 1 ? $txt['spider'] : $txt['spiders']); |
||
1034 | if (!empty($return['num_users_hidden'])) |
||
1035 | $bracketList[] = comma_format($return['num_users_hidden']) . ' ' . $txt['hidden']; |
||
1036 | |||
1037 | if (!empty($bracketList)) |
||
1038 | echo ' (' . implode(', ', $bracketList) . ')'; |
||
1039 | |||
1040 | echo '<br /> |
||
1041 | ', implode(', ', $return['list_users_online']); |
||
1042 | |||
1043 | // Showing membergroups? |
||
1044 | if (!empty($settings['show_group_key']) && !empty($return['membergroups'])) |
||
1045 | echo '<br /> |
||
1046 | [' . implode('] [', $return['membergroups']) . ']'; |
||
1047 | } |
||
1048 | |||
1049 | /** |
||
1050 | * Just like whosOnline except it also logs the online presence. |
||
1051 | * |
||
1052 | * @param string $output_method |
||
1053 | */ |
||
1054 | function ssi_logOnline($output_method = 'echo') |
||
1055 | { |
||
1056 | writeLog(); |
||
1057 | |||
1058 | if ($output_method != 'echo') |
||
1059 | return ssi_whosOnline($output_method); |
||
1060 | else |
||
1061 | ssi_whosOnline($output_method); |
||
1062 | } |
||
1063 | |||
1064 | /** |
||
1065 | * Shows a login box. |
||
1066 | * |
||
1067 | * @param string $redirect_to = '' |
||
1068 | * @param string $output_method = 'echo' |
||
1069 | */ |
||
1070 | function ssi_login($redirect_to = '', $output_method = 'echo') |
||
1071 | { |
||
1072 | global $scripturl, $txt, $user_info, $modSettings, $context, $settings; |
||
1073 | |||
1074 | if ($redirect_to != '') |
||
1075 | $_SESSION['login_url'] = $redirect_to; |
||
1076 | |||
1077 | if ($output_method != 'echo' || !$user_info['is_guest']) |
||
1078 | return $user_info['is_guest']; |
||
1079 | |||
1080 | $context['default_username'] = isset($_POST['user']) ? preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($_POST['user'], ENT_COMPAT, 'UTF-8')) : ''; |
||
1081 | |||
1082 | echo ' |
||
1083 | <script src="', $settings['default_theme_url'], '/scripts/sha256.js"></script> |
||
1084 | |||
1085 | <form action="', $scripturl, '?action=login2" name="frmLogin" id="frmLogin" method="post" accept-charset="UTF-8" ', empty($context['disable_login_hashing']) ? ' onsubmit="hashLoginPassword(this, \'' . $context['session_id'] . '\');"' : '', '> |
||
1086 | <div class="login"> |
||
1087 | <div class="roundframe">'; |
||
1088 | |||
1089 | // Did they make a mistake last time? |
||
1090 | if (!empty($context['login_errors'])) |
||
1091 | echo ' |
||
1092 | <p class="errorbox">', implode('<br />', $context['login_errors']), '</p><br />'; |
||
1093 | |||
1094 | // Or perhaps there's some special description for this time? |
||
1095 | if (isset($context['description'])) |
||
1096 | echo ' |
||
1097 | <p class="description">', $context['description'], '</p>'; |
||
1098 | |||
1099 | // Now just get the basic information - username, password, etc. |
||
1100 | echo ' |
||
1101 | <dl> |
||
1102 | <dt>', $txt['username'], ':</dt> |
||
1103 | <dd><input type="text" name="user" size="20" value="', $context['default_username'], '" class="input_text" autofocus="autofocus" placeholder="', $txt['username'], '" /></dd> |
||
1104 | <dt>', $txt['password'], ':</dt> |
||
1105 | <dd><input type="password" name="passwrd" value="" size="20" class="input_password" placeholder="', $txt['password'], '" /></dd> |
||
1106 | </dl>'; |
||
1107 | |||
1108 | if (!empty($modSettings['enableOpenID'])) |
||
1109 | echo '<p><strong>—', $txt['or'], '—</strong></p> |
||
1110 | <dl> |
||
1111 | <dt>', $txt['openid'], ':</dt> |
||
1112 | <dd><input type="text" name="openid_identifier" class="input_text openid_login" size="17" /> <a href="', $scripturl, '?action=quickhelp;help=register_openid" onclick="return reqOverlayDiv(this.href);" class="help"><img src="', $settings['images_url'], '/helptopics.png" alt="', $txt['help'], '" class="centericon" /></a></dd> |
||
1113 | </dl>'; |
||
1114 | |||
1115 | echo ' |
||
1116 | <p><input type="submit" value="', $txt['login'], '" class="button_submit" /></p> |
||
1117 | <p class="smalltext"><a href="', $scripturl, '?action=reminder">', $txt['forgot_your_password'], '</a></p> |
||
1118 | <input type="hidden" name="hash_passwrd" value="" /> |
||
1119 | <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
||
1120 | <input type="hidden" name="', $context['login_token_var'], '" value="', $context['login_token'], '" /> |
||
1121 | </div> |
||
1122 | </div> |
||
1123 | </form>'; |
||
1124 | |||
1125 | // Focus on the correct input - username or password. |
||
1126 | echo ' |
||
1127 | <script><!-- // --><![CDATA[ |
||
1128 | document.forms.frmLogin.', isset($context['default_username']) && $context['default_username'] != '' ? 'passwrd' : 'user', '.focus(); |
||
1129 | // ]]></script>'; |
||
1130 | |||
1131 | } |
||
1132 | |||
1133 | /** |
||
1134 | * Show the most-voted-in poll. |
||
1135 | * |
||
1136 | * @param string $output_method = 'echo' |
||
1137 | */ |
||
1138 | function ssi_topPoll($output_method = 'echo') |
||
1139 | { |
||
1140 | // Just use recentPoll, no need to duplicate code... |
||
1141 | return ssi_recentPoll(true, $output_method); |
||
1142 | } |
||
1143 | |||
1144 | /** |
||
1145 | * Show the most recently posted poll. |
||
1146 | * |
||
1147 | * @param bool $topPollInstead = false |
||
1148 | * @param string $output_method = string |
||
1149 | */ |
||
1150 | function ssi_recentPoll($topPollInstead = false, $output_method = 'echo') |
||
1151 | { |
||
1152 | global $txt, $settings, $boardurl, $user_info, $context, $modSettings; |
||
1153 | |||
1154 | $boardsAllowed = array_intersect(boardsAllowedTo('poll_view'), boardsAllowedTo('poll_vote')); |
||
1155 | |||
1156 | if (empty($boardsAllowed)) |
||
1157 | return array(); |
||
1158 | |||
1159 | $db = database(); |
||
1160 | |||
1161 | $request = $db->query('', ' |
||
1162 | SELECT p.id_poll, p.question, t.id_topic, p.max_votes, p.guest_vote, p.hide_results, p.expire_time |
||
1163 | FROM {db_prefix}polls AS p |
||
1164 | INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ') |
||
1165 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)' . ($topPollInstead ? ' |
||
1166 | INNER JOIN {db_prefix}poll_choices AS pc ON (pc.id_poll = p.id_poll)' : '') . ' |
||
1167 | LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_poll = p.id_poll AND lp.id_member > {int:no_member} AND lp.id_member = {int:current_member}) |
||
1168 | WHERE p.voting_locked = {int:voting_opened} |
||
1169 | AND (p.expire_time = {int:no_expiration} OR {int:current_time} < p.expire_time) |
||
1170 | AND ' . ($user_info['is_guest'] ? 'p.guest_vote = {int:guest_vote_allowed}' : 'lp.id_choice IS NULL') . ' |
||
1171 | AND {query_wanna_see_board}' . (!in_array(0, $boardsAllowed) ? ' |
||
1172 | AND b.id_board IN ({array_int:boards_allowed_list})' : '') . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' |
||
1173 | AND b.id_board != {int:recycle_enable}' : '') . ' |
||
1174 | ORDER BY ' . ($topPollInstead ? 'pc.votes' : 'p.id_poll') . ' DESC |
||
1175 | LIMIT 1', |
||
1176 | array( |
||
1177 | 'current_member' => $user_info['id'], |
||
1178 | 'boards_allowed_list' => $boardsAllowed, |
||
1179 | 'is_approved' => 1, |
||
1180 | 'guest_vote_allowed' => 1, |
||
1181 | 'no_member' => 0, |
||
1182 | 'voting_opened' => 0, |
||
1183 | 'no_expiration' => 0, |
||
1184 | 'current_time' => time(), |
||
1185 | 'recycle_enable' => $modSettings['recycle_board'], |
||
1186 | ) |
||
1187 | ); |
||
1188 | $row = $db->fetch_assoc($request); |
||
1189 | $db->free_result($request); |
||
1190 | |||
1191 | // This user has voted on all the polls. |
||
1192 | if ($row == false) |
||
1193 | return array(); |
||
1194 | |||
1195 | // If this is a guest who's voted we'll through ourselves to show poll to show the results. |
||
1196 | if ($user_info['is_guest'] && (!$row['guest_vote'] || (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote']))))) |
||
1197 | return ssi_showPoll($row['id_topic'], $output_method); |
||
1198 | |||
1199 | $request = $db->query('', ' |
||
1200 | SELECT COUNT(DISTINCT id_member) |
||
1201 | FROM {db_prefix}log_polls |
||
1202 | WHERE id_poll = {int:current_poll}', |
||
1203 | array( |
||
1204 | 'current_poll' => $row['id_poll'], |
||
1205 | ) |
||
1206 | ); |
||
1207 | list ($total) = $db->fetch_row($request); |
||
1208 | $db->free_result($request); |
||
1209 | |||
1210 | $request = $db->query('', ' |
||
1211 | SELECT id_choice, label, votes |
||
1212 | FROM {db_prefix}poll_choices |
||
1213 | WHERE id_poll = {int:current_poll}', |
||
1214 | array( |
||
1215 | 'current_poll' => $row['id_poll'], |
||
1216 | ) |
||
1217 | ); |
||
1218 | $options = array(); |
||
1219 | while ($rowChoice = $db->fetch_assoc($request)) |
||
1220 | { |
||
1221 | censorText($rowChoice['label']); |
||
1222 | |||
1223 | $options[$rowChoice['id_choice']] = array($rowChoice['label'], $rowChoice['votes']); |
||
1224 | } |
||
1225 | $db->free_result($request); |
||
1226 | |||
1227 | // Can they view it? |
||
1228 | $is_expired = !empty($row['expire_time']) && $row['expire_time'] < time(); |
||
1229 | $allow_view_results = allowedTo('moderate_board') || $row['hide_results'] == 0 || $is_expired; |
||
1230 | |||
1231 | $return = array( |
||
1232 | 'id' => $row['id_poll'], |
||
1233 | 'image' => 'poll', |
||
1234 | 'question' => $row['question'], |
||
1235 | 'total_votes' => $total, |
||
1236 | 'is_locked' => false, |
||
1237 | 'topic' => $row['id_topic'], |
||
1238 | 'allow_view_results' => $allow_view_results, |
||
1239 | 'options' => array() |
||
1240 | ); |
||
1241 | |||
1242 | // Calculate the percentages and bar lengths... |
||
1243 | $divisor = $return['total_votes'] == 0 ? 1 : $return['total_votes']; |
||
1244 | foreach ($options as $i => $option) |
||
1245 | { |
||
1246 | $bar = floor(($option[1] * 100) / $divisor); |
||
1247 | $barWide = $bar == 0 ? 1 : floor(($bar * 5) / 3); |
||
1248 | $return['options'][$i] = array( |
||
1249 | 'id' => 'options-' . ($topPollInstead ? 'top-' : 'recent-') . $i, |
||
1250 | 'percent' => $bar, |
||
1251 | 'votes' => $option[1], |
||
1252 | 'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.png" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.png" style="width:' . $barWide . 'px; height:12px;" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.png" alt="" /></span>', |
||
1253 | 'option' => parse_bbc($option[0]), |
||
1254 | 'vote_button' => '<input type="' . ($row['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . ($topPollInstead ? 'top-' : 'recent-') . $i . '" value="' . $i . '" class="input_' . ($row['max_votes'] > 1 ? 'check' : 'radio') . '" />' |
||
1255 | ); |
||
1256 | } |
||
1257 | |||
1258 | $return['allowed_warning'] = $row['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($options), $row['max_votes'])) : ''; |
||
1259 | |||
1260 | if ($output_method != 'echo') |
||
1261 | return $return; |
||
1262 | |||
1263 | if ($allow_view_results) |
||
1264 | { |
||
1265 | echo ' |
||
1266 | <form class="ssi_poll" action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="UTF-8"> |
||
1267 | <strong>', $return['question'], '</strong><br /> |
||
1268 | ', !empty($return['allowed_warning']) ? $return['allowed_warning'] . '<br />' : ''; |
||
1269 | |||
1270 | foreach ($return['options'] as $option) |
||
1271 | echo ' |
||
1272 | <label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label><br />'; |
||
1273 | |||
1274 | echo ' |
||
1275 | <input type="submit" value="', $txt['poll_vote'], '" class="button_submit" /> |
||
1276 | <input type="hidden" name="poll" value="', $return['id'], '" /> |
||
1277 | <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
||
1278 | </form>'; |
||
1279 | } |
||
1280 | else |
||
1281 | echo $txt['poll_cannot_see']; |
||
1282 | } |
||
1283 | |||
1284 | /** |
||
1285 | * Show a poll. |
||
1286 | * It is possible to use this function in combination with the template |
||
1287 | * template_display_poll_above from Display.template.php, the only part missing |
||
1288 | * is the definition of the poll moderation button array (see Display.controller.php |
||
1289 | * for details). |
||
1290 | * |
||
1291 | * @param int|null $topicID = null |
||
1292 | * @param string $output_method = 'echo' |
||
1293 | */ |
||
1294 | function ssi_showPoll($topicID = null, $output_method = 'echo') |
||
1295 | { |
||
1296 | global $txt, $user_info, $context, $scripturl; |
||
1297 | global $board; |
||
1298 | static $last_board = null; |
||
1299 | |||
1300 | require_once(SUBSDIR . '/Poll.subs.php'); |
||
1301 | require_once(SUBSDIR . '/Topic.subs.php'); |
||
1302 | |||
1303 | if ($topicID === null && isset($_REQUEST['ssi_topic'])) |
||
1304 | $topicID = (int) $_REQUEST['ssi_topic']; |
||
1305 | else |
||
1306 | $topicID = (int) $topicID; |
||
1307 | |||
1308 | if (empty($topicID)) |
||
1309 | return array(); |
||
1310 | |||
1311 | // Get the topic starter information. |
||
1312 | $topicinfo = getTopicInfo($topicID, 'starter'); |
||
1313 | |||
1314 | $boards_can_poll = boardsAllowedTo('poll_view'); |
||
1315 | |||
1316 | // If: |
||
1317 | // - is not allowed to see poll in any board, |
||
1318 | // - or: |
||
1319 | // - is not allowed in the specific board, and |
||
1320 | // - is not an admin |
||
1321 | // fail |
||
1322 | if (empty($boards_can_poll) || (!in_array($topicinfo['id_board'], $boards_can_poll) && !in_array(0, $boards_can_poll))) |
||
1323 | return array(); |
||
1324 | |||
1325 | $context['user']['started'] = $user_info['id'] == $topicinfo['id_member'] && !$user_info['is_guest']; |
||
1326 | |||
1327 | $poll_id = associatedPoll($topicID); |
||
1328 | loadPollContext($poll_id); |
||
1329 | |||
1330 | if (empty($context['poll'])) |
||
1331 | return array(); |
||
1332 | |||
1333 | // For "compatibility" sake |
||
1334 | // @deprecated since 1.0 |
||
1335 | $context['poll']['allow_vote'] = $context['allow_vote']; |
||
1336 | $context['poll']['allow_view_results'] = $context['allow_poll_view']; |
||
1337 | $context['poll']['topic'] = $topicID; |
||
1338 | |||
1339 | if ($output_method != 'echo') |
||
1340 | return $context['poll']; |
||
1341 | |||
1342 | echo ' |
||
1343 | <div class="content" id="poll_options"> |
||
1344 | <h4 id="pollquestion"> |
||
1345 | ', $context['poll']['question'], ' |
||
1346 | </h4>'; |
||
1347 | |||
1348 | if ($context['poll']['allow_vote']) |
||
1349 | { |
||
1350 | echo ' |
||
1351 | <form action="', $scripturl, '?action=poll;sa=vote;topic=', $context['current_topic'], '.', $context['start'], ';poll=', $context['poll']['id'], '" method="post" accept-charset="UTF-8">'; |
||
1352 | |||
1353 | // Show a warning if they are allowed more than one option. |
||
1354 | if ($context['poll']['allowed_warning']) |
||
1355 | echo ' |
||
1356 | <p>', $context['poll']['allowed_warning'], '</p>'; |
||
1357 | |||
1358 | echo ' |
||
1359 | <ul class="options">'; |
||
1360 | |||
1361 | // Show each option with its button - a radio likely. |
||
1362 | foreach ($context['poll']['options'] as $option) |
||
1363 | echo ' |
||
1364 | <li>', $option['vote_button'], ' <label for="', $option['id'], '">', $option['option'], '</label></li>'; |
||
1365 | |||
1366 | echo ' |
||
1367 | </ul> |
||
1368 | <div class="submitbutton"> |
||
1369 | <input type="submit" value="', $txt['poll_vote'], '" class="button_submit" /> |
||
1370 | <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
||
1371 | </div> |
||
1372 | </form>'; |
||
1373 | // Is the clock ticking? |
||
1374 | if (!empty($context['poll']['expire_time'])) |
||
1375 | echo ' |
||
1376 | <p><strong>', ($context['poll']['is_expired'] ? $txt['poll_expired_on'] : $txt['poll_expires_on']), ':</strong> ', $context['poll']['expire_time'], '</p>'; |
||
1377 | |||
1378 | } |
||
1379 | elseif ($context['poll']['allow_view_results']) |
||
1380 | { |
||
1381 | echo ' |
||
1382 | <ul class="options">'; |
||
1383 | |||
1384 | // Show each option with its corresponding percentage bar. |
||
1385 | foreach ($context['poll']['options'] as $option) |
||
1386 | { |
||
1387 | echo ' |
||
1388 | <li', $option['voted_this'] ? ' class="voted"' : '', '>', $option['option'], ' |
||
1389 | <div class="results">'; |
||
1390 | |||
1391 | if ($context['allow_poll_view']) |
||
1392 | echo ' |
||
1393 | <div class="statsbar"> ', $option['bar_ndt'], '</div> |
||
1394 | <span class="percentage">', $option['votes'], ' (', $option['percent'], '%)</span>'; |
||
1395 | |||
1396 | echo ' |
||
1397 | </div> |
||
1398 | </li>'; |
||
1399 | } |
||
1400 | |||
1401 | echo ' |
||
1402 | </ul>'; |
||
1403 | |||
1404 | if ($context['allow_poll_view']) |
||
1405 | echo ' |
||
1406 | <p><strong>', $txt['poll_total_voters'], ':</strong> ', $context['poll']['total_votes'], '</p>'; |
||
1407 | // Is the clock ticking? |
||
1408 | if (!empty($context['poll']['expire_time'])) |
||
1409 | echo ' |
||
1410 | <p><strong>', ($context['poll']['is_expired'] ? $txt['poll_expired_on'] : $txt['poll_expires_on']), ':</strong> ', $context['poll']['expire_time'], '</p>'; |
||
1411 | } |
||
1412 | // Cannot see it I'm afraid! |
||
1413 | else |
||
1414 | echo $txt['poll_cannot_see']; |
||
1415 | |||
1416 | echo ' |
||
1417 | </div>'; |
||
1418 | } |
||
1419 | |||
1420 | /** |
||
1421 | * Takes care of voting - don't worry, this is done automatically. |
||
1422 | */ |
||
1423 | function ssi_pollVote() |
||
1424 | { |
||
1425 | global $context, $sc, $topic, $board; |
||
1426 | |||
1427 | $pollID = isset($_POST['poll']) ? (int) $_POST['poll'] : 0; |
||
1428 | |||
1429 | if (empty($pollID) || !isset($_POST[$context['session_var']]) || $_POST[$context['session_var']] != $sc || empty($_POST['options'])) |
||
1430 | { |
||
1431 | echo '<!DOCTYPE html> |
||
1432 | <html> |
||
1433 | <head> |
||
1434 | <script><!-- // --><![CDATA[ |
||
1435 | history.go(-1); |
||
1436 | // ]]></script> |
||
1437 | </head> |
||
1438 | <body>«</body> |
||
1439 | </html>'; |
||
1440 | return; |
||
1441 | } |
||
1442 | |||
1443 | require_once(CONTROLLERDIR . '/Poll.controller.php'); |
||
1444 | require_once(SUBSDIR . '/Poll.subs.php'); |
||
1445 | // We have to fake we are in a topic so that we can use the proper controller |
||
1446 | list ($topic, $board) = topicFromPoll($pollID); |
||
1447 | loadBoard(); |
||
1448 | |||
1449 | $poll_action = new Poll_Controller(); |
||
1450 | |||
1451 | // The controller takes already care of redirecting properly or fail |
||
1452 | $poll_action->action_vote(); |
||
1453 | } |
||
1454 | |||
1455 | /** |
||
1456 | * Show a search box. |
||
1457 | * |
||
1458 | * @param string $output_method = 'echo' |
||
1459 | */ |
||
1460 | function ssi_quickSearch($output_method = 'echo') |
||
1461 | { |
||
1462 | global $scripturl, $txt; |
||
1463 | |||
1464 | if (!allowedTo('search_posts')) |
||
1465 | return; |
||
1466 | |||
1467 | if ($output_method != 'echo') |
||
1468 | return $scripturl . '?action=search'; |
||
1469 | |||
1470 | echo ' |
||
1471 | <form action="', $scripturl, '?action=search;sa=results" method="post" accept-charset="UTF-8"> |
||
1472 | <input type="hidden" name="advanced" value="0" /><input type="text" name="search" size="30" class="input_text" /> <input type="submit" value="', $txt['search'], '" class="button_submit" /> |
||
1473 | </form>'; |
||
1474 | } |
||
1475 | |||
1476 | /** |
||
1477 | * Show what would be the forum news. |
||
1478 | * |
||
1479 | * @param string $output_method = 'echo' |
||
1480 | */ |
||
1481 | function ssi_news($output_method = 'echo') |
||
1482 | { |
||
1483 | global $context; |
||
1484 | |||
1485 | if ($output_method != 'echo') |
||
1486 | return $context['random_news_line']; |
||
1487 | |||
1488 | echo $context['random_news_line']; |
||
1489 | } |
||
1490 | |||
1491 | /** |
||
1492 | * Show today's birthdays. |
||
1493 | * |
||
1494 | * @param string $output_method = 'echo' |
||
1495 | */ |
||
1496 | function ssi_todaysBirthdays($output_method = 'echo') |
||
1497 | { |
||
1498 | global $scripturl, $modSettings, $user_info; |
||
1499 | |||
1500 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view') || !allowedTo('profile_view_any')) |
||
1501 | return; |
||
1502 | |||
1503 | $eventOptions = array( |
||
1504 | 'include_birthdays' => true, |
||
1505 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1506 | ); |
||
1507 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'subs/Calendar.subs.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1508 | |||
1509 | if ($output_method != 'echo') |
||
1510 | return $return['calendar_birthdays']; |
||
1511 | |||
1512 | foreach ($return['calendar_birthdays'] as $member) |
||
1513 | echo ' |
||
1514 | <a href="', $scripturl, '?action=profile;u=', $member['id'], '"><span class="fix_rtl_names">' . $member['name'] . '</span>' . (isset($member['age']) ? ' (' . $member['age'] . ')' : '') . '</a>' . (!$member['is_last'] ? ', ' : ''); |
||
1515 | } |
||
1516 | |||
1517 | /** |
||
1518 | * Show today's holidays. |
||
1519 | * |
||
1520 | * @param string $output_method = 'echo' |
||
1521 | */ |
||
1522 | function ssi_todaysHolidays($output_method = 'echo') |
||
1523 | { |
||
1524 | global $modSettings, $user_info; |
||
1525 | |||
1526 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1527 | return; |
||
1528 | |||
1529 | $eventOptions = array( |
||
1530 | 'include_holidays' => true, |
||
1531 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1532 | ); |
||
1533 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'subs/Calendar.subs.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1534 | |||
1535 | if ($output_method != 'echo') |
||
1536 | return $return['calendar_holidays']; |
||
1537 | |||
1538 | echo ' |
||
1539 | ', implode(', ', $return['calendar_holidays']); |
||
1540 | } |
||
1541 | |||
1542 | /** |
||
1543 | * Show today's events. |
||
1544 | * |
||
1545 | * @param string $output_method = 'echo' |
||
1546 | */ |
||
1547 | function ssi_todaysEvents($output_method = 'echo') |
||
1548 | { |
||
1549 | global $modSettings, $user_info; |
||
1550 | |||
1551 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1552 | return; |
||
1553 | |||
1554 | $eventOptions = array( |
||
1555 | 'include_events' => true, |
||
1556 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1557 | ); |
||
1558 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'subs/Calendar.subs.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1559 | |||
1560 | if ($output_method != 'echo') |
||
1561 | return $return['calendar_events']; |
||
1562 | |||
1563 | foreach ($return['calendar_events'] as $event) |
||
1564 | { |
||
1565 | if ($event['can_edit']) |
||
1566 | echo ' |
||
1567 | <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> '; |
||
1568 | echo ' |
||
1569 | ' . $event['link'] . (!$event['is_last'] ? ', ' : ''); |
||
1570 | } |
||
1571 | } |
||
1572 | |||
1573 | /** |
||
1574 | * Show all calendar entires for today. (birthdays, holidays, and events.) |
||
1575 | * |
||
1576 | * @param string $output_method = 'echo' |
||
1577 | */ |
||
1578 | function ssi_todaysCalendar($output_method = 'echo') |
||
1579 | { |
||
1580 | global $modSettings, $txt, $scripturl, $user_info; |
||
1581 | |||
1582 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1583 | return; |
||
1584 | |||
1585 | $eventOptions = array( |
||
1586 | 'include_birthdays' => allowedTo('profile_view_any'), |
||
1587 | 'include_holidays' => true, |
||
1588 | 'include_events' => true, |
||
1589 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1590 | ); |
||
1591 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'subs/Calendar.subs.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1592 | |||
1593 | if ($output_method != 'echo') |
||
1594 | return $return; |
||
1595 | |||
1596 | if (!empty($return['calendar_holidays'])) |
||
1597 | echo ' |
||
1598 | <span class="holiday">' . $txt['calendar_prompt'] . ' ' . implode(', ', $return['calendar_holidays']) . '<br /></span>'; |
||
1599 | |||
1600 | if (!empty($return['calendar_birthdays'])) |
||
1601 | { |
||
1602 | echo ' |
||
1603 | <span class="birthday">' . $txt['birthdays_upcoming'] . '</span> '; |
||
1604 | foreach ($return['calendar_birthdays'] as $member) |
||
1605 | echo ' |
||
1606 | <a href="', $scripturl, '?action=profile;u=', $member['id'], '"><span class="fix_rtl_names">', $member['name'], '</span>', isset($member['age']) ? ' (' . $member['age'] . ')' : '', '</a>', !$member['is_last'] ? ', ' : ''; |
||
1607 | echo ' |
||
1608 | <br />'; |
||
1609 | } |
||
1610 | |||
1611 | if (!empty($return['calendar_events'])) |
||
1612 | { |
||
1613 | echo ' |
||
1614 | <span class="event">' . $txt['events_upcoming'] . '</span> '; |
||
1615 | foreach ($return['calendar_events'] as $event) |
||
1616 | { |
||
1617 | if ($event['can_edit']) |
||
1618 | echo ' |
||
1619 | <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> '; |
||
1620 | echo ' |
||
1621 | ' . $event['link'] . (!$event['is_last'] ? ', ' : ''); |
||
1622 | } |
||
1623 | } |
||
1624 | } |
||
1625 | |||
1626 | /** |
||
1627 | * Show the latest news, with a template... by board. |
||
1628 | * |
||
1629 | * @param int|null $board |
||
1630 | * @param int|null $limit |
||
1631 | * @param int|null $start |
||
1632 | * @param int|null $length |
||
1633 | * @param string $preview |
||
1634 | * @param string $output_method = 'echo' |
||
1635 | */ |
||
1636 | function ssi_boardNews($board = null, $limit = null, $start = null, $length = null, $preview = 'first', $output_method = 'echo') |
||
1637 | { |
||
1638 | global $scripturl, $txt, $settings, $modSettings; |
||
1639 | |||
1640 | loadLanguage('Stats'); |
||
1641 | |||
1642 | $db = database(); |
||
1643 | |||
1644 | // Must be integers.... |
||
1645 | if ($limit === null) |
||
1646 | $limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 5; |
||
1647 | else |
||
1648 | $limit = (int) $limit; |
||
1649 | |||
1650 | if ($start === null) |
||
1651 | $start = isset($_GET['start']) ? (int) $_GET['start'] : 0; |
||
1652 | else |
||
1653 | $start = (int) $start; |
||
1654 | |||
1655 | if ($board !== null) |
||
1656 | $board = (int) $board; |
||
1657 | elseif (isset($_GET['board'])) |
||
1658 | $board = (int) $_GET['board']; |
||
1659 | |||
1660 | if ($length === null) |
||
1661 | $length = isset($_GET['length']) ? (int) $_GET['length'] : 500; |
||
1662 | else |
||
1663 | $length = (int) $length; |
||
1664 | |||
1665 | $limit = max(0, $limit); |
||
1666 | $start = max(0, $start); |
||
1667 | |||
1668 | // Make sure guests can see this board. |
||
1669 | $request = $db->query('', ' |
||
1670 | SELECT id_board |
||
1671 | FROM {db_prefix}boards |
||
1672 | WHERE ' . ($board === null ? '' : 'id_board = {int:current_board} |
||
1673 | AND ') . 'FIND_IN_SET(-1, member_groups) != 0 |
||
1674 | LIMIT 1', |
||
1675 | array( |
||
1676 | 'current_board' => $board, |
||
1677 | ) |
||
1678 | ); |
||
1679 | if ($db->num_rows($request) == 0) |
||
1680 | { |
||
1681 | if ($output_method == 'echo') |
||
1682 | die($txt['ssi_no_guests']); |
||
0 ignored issues
–
show
|
|||
1683 | else |
||
1684 | return array(); |
||
1685 | } |
||
1686 | list ($board) = $db->fetch_row($request); |
||
1687 | $db->free_result($request); |
||
1688 | |||
1689 | // Load the message icons - the usual suspects. |
||
1690 | require_once(SUBSDIR . '/MessageIndex.subs.php'); |
||
1691 | $icon_sources = MessageTopicIcons(); |
||
1692 | |||
1693 | // Find the posts. |
||
1694 | $indexOptions = array( |
||
1695 | 'only_approved' => true, |
||
1696 | 'include_sticky' => false, |
||
1697 | 'ascending' => false, |
||
1698 | 'include_avatars' => false, |
||
1699 | 'previews' => $length |
||
1700 | ); |
||
1701 | $request = messageIndexTopics($board, 0, $start, $limit, 'first_post', 't.id_topic', $indexOptions); |
||
1702 | |||
1703 | if (empty($request)) |
||
1704 | return; |
||
1705 | |||
1706 | $return = array(); |
||
1707 | foreach ($request as $row) |
||
1708 | { |
||
1709 | if (!isset($row[$preview . '_body'])) |
||
1710 | $preview = 'first'; |
||
1711 | |||
1712 | $row['body'] = $row[$preview . '_body']; |
||
1713 | $row['subject'] = $row[$preview . '_subject']; |
||
1714 | $row['id_msg'] = $row['id_' . $preview . '_msg']; |
||
1715 | $row['icon'] = $row[$preview . '_icon']; |
||
1716 | $row['id_member'] = $row[$preview . '_id_member']; |
||
1717 | $row['smileys_enabled'] = $row[$preview . '_smileys']; |
||
1718 | $row['poster_time'] = $row[$preview . '_poster_time']; |
||
1719 | $row['poster_name'] = $row[$preview . '_display_name']; |
||
1720 | $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']); |
||
1721 | |||
1722 | // Check that this message icon is there... |
||
1723 | if (!empty($modSettings['messageIconChecks_enable']) && !isset($icon_sources[$row['icon']])) |
||
1724 | $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url'; |
||
1725 | |||
1726 | censorText($row['subject']); |
||
1727 | censorText($row['body']); |
||
1728 | |||
1729 | $return[] = array( |
||
1730 | 'id' => $row['id_topic'], |
||
1731 | 'message_id' => $row['id_msg'], |
||
1732 | 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.png" alt="' . $row['icon'] . '" />', |
||
1733 | 'subject' => $row['subject'], |
||
1734 | 'time' => standardTime($row['poster_time']), |
||
1735 | 'html_time' => htmlTime($row['poster_time']), |
||
1736 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
1737 | 'body' => $row['body'], |
||
1738 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0', |
||
1739 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['num_replies'] . ' ' . ($row['num_replies'] == 1 ? $txt['ssi_comment'] : $txt['ssi_comments']) . '</a>', |
||
1740 | 'replies' => $row['num_replies'], |
||
1741 | 'comment_href' => !empty($row['locked']) ? '' : $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'], |
||
1742 | 'comment_link' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'] . '">' . $txt['ssi_write_comment'] . '</a>', |
||
1743 | 'new_comment' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . '">' . $txt['ssi_write_comment'] . '</a>', |
||
1744 | 'poster' => array( |
||
1745 | 'id' => $row['id_member'], |
||
1746 | 'name' => $row['poster_name'], |
||
1747 | 'href' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : '', |
||
1748 | 'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name'] |
||
1749 | ), |
||
1750 | 'locked' => !empty($row['locked']), |
||
1751 | 'is_last' => false |
||
1752 | ); |
||
1753 | } |
||
1754 | |||
1755 | $return[count($return) - 1]['is_last'] = true; |
||
1756 | |||
1757 | if ($output_method != 'echo') |
||
1758 | return $return; |
||
1759 | |||
1760 | foreach ($return as $news) |
||
1761 | { |
||
1762 | echo ' |
||
1763 | <div class="news_item"> |
||
1764 | <h3 class="news_header"> |
||
1765 | ', $news['icon'], ' |
||
1766 | <a href="', $news['href'], '">', $news['subject'], '</a> |
||
1767 | </h3> |
||
1768 | <div class="news_timestamp">', $news['time'], ' ', $txt['by'], ' ', $news['poster']['link'], '</div> |
||
1769 | <div class="news_body" style="padding: 2ex 0;">', $news['body'], '</div> |
||
1770 | ', $news['link'], $news['locked'] ? '' : ' | ' . $news['comment_link'], ' |
||
1771 | </div>'; |
||
1772 | |||
1773 | if (!$news['is_last']) |
||
1774 | echo ' |
||
1775 | <hr />'; |
||
1776 | } |
||
1777 | } |
||
1778 | |||
1779 | /** |
||
1780 | * Show the most recent events. |
||
1781 | * |
||
1782 | * @param int $max_events |
||
1783 | * @param string $output_method = 'echo' |
||
1784 | */ |
||
1785 | function ssi_recentEvents($max_events = 7, $output_method = 'echo') |
||
1786 | { |
||
1787 | global $modSettings, $txt; |
||
1788 | |||
1789 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1790 | return; |
||
1791 | |||
1792 | require_once(SUBSDIR . '/Calendar.subs.php'); |
||
1793 | |||
1794 | // Find all events which are happening in the near future that the member can see. |
||
1795 | $date = strftime('%Y-%m-%d', forum_time(false)); |
||
1796 | $events = getEventRange($date, $date, true, $max_events); |
||
1797 | |||
1798 | $return = array(); |
||
1799 | $duplicates = array(); |
||
1800 | foreach ($events as $date => $day_events) |
||
1801 | { |
||
1802 | foreach ($day_events as $row) |
||
1803 | { |
||
1804 | // Check if we've already come by an event linked to this same topic with the same title... and don't display it if we have. |
||
1805 | if (!empty($duplicates[$row['title'] . $row['id_topic']])) |
||
1806 | continue; |
||
1807 | |||
1808 | $return[$date][] = $row; |
||
1809 | |||
1810 | // Let's not show this one again, huh? |
||
1811 | $duplicates[$row['title'] . $row['id_topic']] = true; |
||
1812 | } |
||
1813 | } |
||
1814 | |||
1815 | foreach ($return as $mday => $array) |
||
1816 | $return[$mday][count($array) - 1]['is_last'] = true; |
||
1817 | |||
1818 | if ($output_method != 'echo' || empty($return)) |
||
1819 | return $return; |
||
1820 | |||
1821 | // Well the output method is echo. |
||
1822 | echo ' |
||
1823 | <span class="event">' . $txt['events'] . '</span> '; |
||
1824 | foreach ($return as $mday => $array) |
||
1825 | foreach ($array as $event) |
||
1826 | { |
||
1827 | if ($event['can_edit']) |
||
1828 | echo ' |
||
1829 | <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> '; |
||
1830 | |||
1831 | echo ' |
||
1832 | ' . $event['link'] . (!$event['is_last'] ? ', ' : ''); |
||
1833 | } |
||
1834 | } |
||
1835 | |||
1836 | /** |
||
1837 | * Check the passed id_member/password. |
||
1838 | * If $is_username is true, treats $id as a username. |
||
1839 | * |
||
1840 | * @param int|null $id |
||
1841 | * @param string|null $password |
||
1842 | * @param bool $is_username |
||
1843 | */ |
||
1844 | function ssi_checkPassword($id = null, $password = null, $is_username = false) |
||
1845 | { |
||
1846 | // If $id is null, this was most likely called from a query string and should do nothing. |
||
1847 | if ($id === null) |
||
1848 | return; |
||
1849 | |||
1850 | require_once(SUBSDIR . '/Auth.subs.php'); |
||
1851 | |||
1852 | $member = loadExistingMember($id, !$is_username); |
||
1853 | |||
1854 | return validateLoginPassword($password, $member['passwd'], $member['member_name']) && $member['is_activated'] == 1; |
||
1855 | } |
||
1856 | |||
1857 | /** |
||
1858 | * We want to show the recent attachments outside of the forum. |
||
1859 | * |
||
1860 | * @param int $num_attachments = 10 |
||
1861 | * @param string[] $attachment_ext = array() |
||
1862 | * @param string $output_method = 'echo' |
||
1863 | */ |
||
1864 | function ssi_recentAttachments($num_attachments = 10, $attachment_ext = array(), $output_method = 'echo') |
||
1865 | { |
||
1866 | global $modSettings, $scripturl, $txt, $settings; |
||
1867 | |||
1868 | // We want to make sure that we only get attachments for boards that we can see *if* any. |
||
1869 | $attachments_boards = boardsAllowedTo('view_attachments'); |
||
1870 | |||
1871 | // No boards? Adios amigo. |
||
1872 | if (empty($attachments_boards)) |
||
1873 | return array(); |
||
1874 | |||
1875 | $db = database(); |
||
1876 | |||
1877 | // Is it an array? |
||
1878 | if (!is_array($attachment_ext)) |
||
1879 | $attachment_ext = array($attachment_ext); |
||
1880 | |||
1881 | // Lets build the query. |
||
1882 | $request = $db->query('', ' |
||
1883 | SELECT |
||
1884 | att.id_attach, att.id_msg, att.filename, IFNULL(att.size, 0) AS filesize, att.downloads, mem.id_member, |
||
1885 | IFNULL(mem.real_name, m.poster_name) AS poster_name, m.id_topic, m.subject, t.id_board, m.poster_time, |
||
1886 | att.width, att.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ', IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . ' |
||
1887 | FROM {db_prefix}attachments AS att |
||
1888 | INNER JOIN {db_prefix}messages AS m ON (m.id_msg = att.id_msg) |
||
1889 | INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) |
||
1890 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ' |
||
1891 | LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = att.id_thumb)') . ' |
||
1892 | WHERE att.attachment_type = 0' . ($attachments_boards === array(0) ? '' : ' |
||
1893 | AND m.id_board IN ({array_int:boards_can_see})') . (!empty($attachment_ext) ? ' |
||
1894 | AND att.fileext IN ({array_string:attachment_ext})' : '') . |
||
1895 | (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : ' |
||
1896 | AND t.approved = {int:is_approved} |
||
1897 | AND m.approved = {int:is_approved} |
||
1898 | AND att.approved = {int:is_approved}') . ' |
||
1899 | ORDER BY att.id_attach DESC |
||
1900 | LIMIT {int:num_attachments}', |
||
1901 | array( |
||
1902 | 'boards_can_see' => $attachments_boards, |
||
1903 | 'attachment_ext' => $attachment_ext, |
||
1904 | 'num_attachments' => $num_attachments, |
||
1905 | 'is_approved' => 1, |
||
1906 | ) |
||
1907 | ); |
||
1908 | |||
1909 | // We have something. |
||
1910 | $attachments = array(); |
||
1911 | while ($row = $db->fetch_assoc($request)) |
||
1912 | { |
||
1913 | $filename = preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename'], ENT_COMPAT, 'UTF-8')); |
||
1914 | |||
1915 | // Is it an image? |
||
1916 | $attachments[$row['id_attach']] = array( |
||
1917 | 'member' => array( |
||
1918 | 'id' => $row['id_member'], |
||
1919 | 'name' => $row['poster_name'], |
||
1920 | 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>', |
||
1921 | ), |
||
1922 | 'file' => array( |
||
1923 | 'filename' => $filename, |
||
1924 | 'filesize' => round($row['filesize'] / 1024, 2) . $txt['kilobyte'], |
||
1925 | 'downloads' => $row['downloads'], |
||
1926 | 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'], |
||
1927 | 'link' => '<img src="' . $settings['images_url'] . '/icons/clip.png" alt="" /> <a href="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . '">' . $filename . '</a>', |
||
1928 | 'is_image' => !empty($row['width']) && !empty($row['height']) && !empty($modSettings['attachmentShowImages']), |
||
1929 | ), |
||
1930 | 'topic' => array( |
||
1931 | 'id' => $row['id_topic'], |
||
1932 | 'subject' => $row['subject'], |
||
1933 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], |
||
1934 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '">' . $row['subject'] . '</a>', |
||
1935 | 'time' => standardTime($row['poster_time']), |
||
1936 | 'html_time' => htmlTime($row['poster_time']), |
||
1937 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
1938 | ), |
||
1939 | ); |
||
1940 | |||
1941 | // Images. |
||
1942 | if ($attachments[$row['id_attach']]['file']['is_image']) |
||
1943 | { |
||
1944 | $id_thumb = empty($row['id_thumb']) ? $row['id_attach'] : $row['id_thumb']; |
||
1945 | $attachments[$row['id_attach']]['file']['image'] = array( |
||
1946 | 'id' => $id_thumb, |
||
1947 | 'width' => $row['width'], |
||
1948 | 'height' => $row['height'], |
||
1949 | 'img' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image" alt="' . $filename . '" />', |
||
1950 | 'thumb' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '" />', |
||
1951 | 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image', |
||
1952 | 'link' => '<a href="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image"><img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '" /></a>', |
||
1953 | ); |
||
1954 | } |
||
1955 | } |
||
1956 | $db->free_result($request); |
||
1957 | |||
1958 | // So you just want an array? Here you can have it. |
||
1959 | if ($output_method == 'array' || empty($attachments)) |
||
1960 | return $attachments; |
||
1961 | |||
1962 | // Give them the default. |
||
1963 | echo ' |
||
1964 | <table class="ssi_downloads" cellpadding="2"> |
||
1965 | <tr> |
||
1966 | <th align="left">', $txt['file'], '</th> |
||
1967 | <th align="left">', $txt['posted_by'], '</th> |
||
1968 | <th align="left">', $txt['downloads'], '</th> |
||
1969 | <th align="left">', $txt['filesize'], '</th> |
||
1970 | </tr>'; |
||
1971 | |||
1972 | foreach ($attachments as $attach) |
||
1973 | echo ' |
||
1974 | <tr> |
||
1975 | <td>', $attach['file']['link'], '</td> |
||
1976 | <td>', $attach['member']['link'], '</td> |
||
1977 | <td align="center">', $attach['file']['downloads'], '</td> |
||
1978 | <td>', $attach['file']['filesize'], '</td> |
||
1979 | </tr>'; |
||
1980 | echo ' |
||
1981 | </table>'; |
||
1982 | } |
||
1983 |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.