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 | * Simple Machines Forum (SMF) |
||
5 | * |
||
6 | * @package SMF |
||
7 | * @author Simple Machines http://www.simplemachines.org |
||
8 | * @copyright 2017 Simple Machines and individual contributors |
||
9 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
10 | * |
||
11 | * @version 2.1 Beta 3 |
||
12 | */ |
||
13 | |||
14 | // Don't do anything if SMF is already loaded. |
||
15 | if (defined('SMF')) |
||
16 | return true; |
||
17 | |||
18 | define('SMF', 'SSI'); |
||
19 | |||
20 | // We're going to want a few globals... these are all set later. |
||
21 | global $time_start, $maintenance, $msubject, $mmessage, $mbname, $language; |
||
22 | global $boardurl, $boarddir, $sourcedir, $webmaster_email, $cookiename; |
||
23 | global $db_type, $db_server, $db_name, $db_user, $db_prefix, $db_persist, $db_error_send, $db_last_error; |
||
24 | global $db_connection, $modSettings, $context, $sc, $user_info, $topic, $board, $txt; |
||
25 | global $smcFunc, $ssi_db_user, $scripturl, $ssi_db_passwd, $db_passwd, $cachedir; |
||
26 | |||
27 | // Remember the current configuration so it can be set back. |
||
28 | $ssi_magic_quotes_runtime = function_exists('get_magic_quotes_gpc') && get_magic_quotes_runtime(); |
||
29 | if (function_exists('set_magic_quotes_runtime')) |
||
30 | @set_magic_quotes_runtime(0); |
||
0 ignored issues
–
show
|
|||
31 | $time_start = microtime(); |
||
32 | |||
33 | // Just being safe... |
||
34 | foreach (array('db_character_set', 'cachedir') as $variable) |
||
35 | if (isset($GLOBALS[$variable])) |
||
36 | unset($GLOBALS[$variable]); |
||
37 | |||
38 | // Get the forum's settings for database and file paths. |
||
39 | require_once(dirname(__FILE__) . '/Settings.php'); |
||
40 | |||
41 | // Make absolutely sure the cache directory is defined. |
||
42 | View Code Duplication | if ((empty($cachedir) || !file_exists($cachedir)) && file_exists($boarddir . '/cache')) |
|
43 | $cachedir = $boarddir . '/cache'; |
||
44 | |||
45 | $ssi_error_reporting = error_reporting(defined('E_STRICT') ? E_ALL | E_STRICT : E_ALL); |
||
46 | /* Set this to one of three values depending on what you want to happen in the case of a fatal error. |
||
47 | false: Default, will just load the error sub template and die - not putting any theme layers around it. |
||
48 | true: Will load the error sub template AND put the SMF layers around it (Not useful if on total custom pages). |
||
49 | 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. |
||
50 | */ |
||
51 | $ssi_on_error_method = false; |
||
52 | |||
53 | // Don't do john didley if the forum's been shut down completely. |
||
54 | if ($maintenance == 2 && (!isset($ssi_maintenance_off) || $ssi_maintenance_off !== true)) |
||
55 | die($mmessage); |
||
56 | |||
57 | // Fix for using the current directory as a path. |
||
58 | View Code Duplication | if (substr($sourcedir, 0, 1) == '.' && substr($sourcedir, 1, 1) != '.') |
|
59 | $sourcedir = dirname(__FILE__) . substr($sourcedir, 1); |
||
60 | |||
61 | // Load the important includes. |
||
62 | require_once($sourcedir . '/QueryString.php'); |
||
63 | require_once($sourcedir . '/Session.php'); |
||
64 | require_once($sourcedir . '/Subs.php'); |
||
65 | require_once($sourcedir . '/Errors.php'); |
||
66 | require_once($sourcedir . '/Logging.php'); |
||
67 | require_once($sourcedir . '/Load.php'); |
||
68 | require_once($sourcedir . '/Security.php'); |
||
69 | require_once($sourcedir . '/Class-BrowserDetect.php'); |
||
70 | require_once($sourcedir . '/Subs-Auth.php'); |
||
71 | |||
72 | // Create a variable to store some SMF specific functions in. |
||
73 | $smcFunc = array(); |
||
74 | |||
75 | // Initiate the database connection and define some database functions to use. |
||
76 | loadDatabase(); |
||
77 | |||
78 | // Load installed 'Mods' settings. |
||
79 | reloadSettings(); |
||
80 | // Clean the request variables. |
||
81 | cleanRequest(); |
||
82 | |||
83 | // Seed the random generator? |
||
84 | if (empty($modSettings['rand_seed']) || mt_rand(1, 250) == 69) |
||
85 | smf_seed_generator(); |
||
86 | |||
87 | // Check on any hacking attempts. |
||
88 | if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS'])) |
||
89 | die('No direct access...'); |
||
90 | elseif (isset($_REQUEST['ssi_theme']) && (int) $_REQUEST['ssi_theme'] == (int) $ssi_theme) |
||
91 | die('No direct access...'); |
||
92 | elseif (isset($_COOKIE['ssi_theme']) && (int) $_COOKIE['ssi_theme'] == (int) $ssi_theme) |
||
93 | die('No direct access...'); |
||
94 | elseif (isset($_REQUEST['ssi_layers'], $ssi_layers) && (@get_magic_quotes_gpc() ? stripslashes($_REQUEST['ssi_layers']) : $_REQUEST['ssi_layers']) == $ssi_layers) |
||
95 | die('No direct access...'); |
||
96 | if (isset($_REQUEST['context'])) |
||
97 | die('No direct access...'); |
||
98 | |||
99 | // Gzip output? (because it must be boolean and true, this can't be hacked.) |
||
100 | 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', '>=')) |
||
101 | ob_start('ob_gzhandler'); |
||
102 | else |
||
103 | $modSettings['enableCompressedOutput'] = '0'; |
||
104 | |||
105 | // Primarily, this is to fix the URLs... |
||
106 | ob_start('ob_sessrewrite'); |
||
107 | |||
108 | // Start the session... known to scramble SSI includes in cases... |
||
109 | if (!headers_sent()) |
||
110 | loadSession(); |
||
111 | else |
||
112 | { |
||
113 | if (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()])) |
||
114 | { |
||
115 | // Make a stab at it, but ignore the E_WARNINGs generated because we can't send headers. |
||
116 | $temp = error_reporting(error_reporting() & !E_WARNING); |
||
117 | loadSession(); |
||
118 | error_reporting($temp); |
||
119 | } |
||
120 | |||
121 | View Code Duplication | if (!isset($_SESSION['session_value'])) |
|
122 | { |
||
123 | $_SESSION['session_var'] = substr(md5(mt_rand() . session_id() . mt_rand()), 0, rand(7, 12)); |
||
124 | $_SESSION['session_value'] = md5(session_id() . mt_rand()); |
||
125 | } |
||
126 | $sc = $_SESSION['session_value']; |
||
127 | } |
||
128 | |||
129 | // Get rid of $board and $topic... do stuff loadBoard would do. |
||
130 | unset($board, $topic); |
||
131 | $user_info['is_mod'] = false; |
||
132 | $context['user']['is_mod'] = &$user_info['is_mod']; |
||
133 | $context['linktree'] = array(); |
||
134 | |||
135 | // Load the user and their cookie, as well as their settings. |
||
136 | loadUserSettings(); |
||
137 | |||
138 | // Load the current user's permissions.... |
||
139 | loadPermissions(); |
||
140 | |||
141 | // Load the current or SSI theme. (just use $ssi_theme = id_theme;) |
||
142 | loadTheme(isset($ssi_theme) ? (int) $ssi_theme : 0); |
||
143 | |||
144 | // @todo: probably not the best place, but somewhere it should be set... |
||
145 | if (!headers_sent()) |
||
146 | header('Content-Type: text/html; charset=' . (empty($modSettings['global_character_set']) ? (empty($txt['lang_character_set']) ? 'ISO-8859-1' : $txt['lang_character_set']) : $modSettings['global_character_set'])); |
||
147 | |||
148 | // Take care of any banning that needs to be done. |
||
149 | if (isset($_REQUEST['ssi_ban']) || (isset($ssi_ban) && $ssi_ban === true)) |
||
150 | is_not_banned(); |
||
151 | |||
152 | // Do we allow guests in here? |
||
153 | if (empty($ssi_guest_access) && empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && basename($_SERVER['PHP_SELF']) != 'SSI.php') |
||
154 | { |
||
155 | require_once($sourcedir . '/Subs-Auth.php'); |
||
156 | KickGuest(); |
||
157 | obExit(null, true); |
||
158 | } |
||
159 | |||
160 | // Load the stuff like the menu bar, etc. |
||
161 | if (isset($ssi_layers)) |
||
162 | { |
||
163 | $context['template_layers'] = $ssi_layers; |
||
164 | template_header(); |
||
165 | } |
||
166 | else |
||
167 | setupThemeContext(); |
||
168 | |||
169 | // Make sure they didn't muss around with the settings... but only if it's not cli. |
||
170 | if (isset($_SERVER['REMOTE_ADDR']) && !isset($_SERVER['is_cli']) && session_id() == '') |
||
171 | trigger_error($txt['ssi_session_broken'], E_USER_NOTICE); |
||
172 | |||
173 | // Without visiting the forum this session variable might not be set on submit. |
||
174 | if (!isset($_SESSION['USER_AGENT']) && (!isset($_GET['ssi_function']) || $_GET['ssi_function'] !== 'pollVote')) |
||
175 | $_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT']; |
||
176 | |||
177 | // Have the ability to easily add functions to SSI. |
||
178 | call_integration_hook('integrate_SSI'); |
||
179 | |||
180 | // Ignore a call to ssi_* functions if we are not accessing SSI.php directly. |
||
181 | if (basename($_SERVER['PHP_SELF']) == 'SSI.php') |
||
182 | { |
||
183 | // You shouldn't just access SSI.php directly by URL!! |
||
184 | if (!isset($_GET['ssi_function'])) |
||
185 | die(sprintf($txt['ssi_not_direct'], $user_info['is_admin'] ? '\'' . addslashes(__FILE__) . '\'' : '\'SSI.php\'')); |
||
186 | // Call a function passed by GET. |
||
187 | if (function_exists('ssi_' . $_GET['ssi_function']) && (!empty($modSettings['allow_guestAccess']) || !$user_info['is_guest'])) |
||
188 | call_user_func('ssi_' . $_GET['ssi_function']); |
||
189 | exit; |
||
190 | } |
||
191 | |||
192 | // To avoid side effects later on. |
||
193 | unset($_GET['ssi_function']); |
||
194 | |||
195 | error_reporting($ssi_error_reporting); |
||
196 | if (function_exists('set_magic_quotes_runtime')) |
||
197 | @set_magic_quotes_runtime($ssi_magic_quotes_runtime); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
198 | |||
199 | return true; |
||
200 | |||
201 | /** |
||
202 | * This shuts down the SSI and shows the footer. |
||
203 | * @return void |
||
204 | */ |
||
205 | function ssi_shutdown() |
||
206 | { |
||
207 | if (!isset($_GET['ssi_function']) || $_GET['ssi_function'] != 'shutdown') |
||
208 | template_footer(); |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * Display a welcome message, like: Hey, User, you have 0 messages, 0 are new. |
||
213 | * @param string $output_method The output method. If 'echo', will display everything. Otherwise returns an array of user info. |
||
214 | * @return void|array Displays a welcome message or returns an array of user data depending on output_method. |
||
215 | */ |
||
216 | function ssi_welcome($output_method = 'echo') |
||
217 | { |
||
218 | global $context, $txt, $scripturl; |
||
219 | |||
220 | if ($output_method == 'echo') |
||
221 | { |
||
222 | if ($context['user']['is_guest']) |
||
223 | echo sprintf($txt[$context['can_register'] ? 'welcome_guest_register' : 'welcome_guest'], $txt['guest_title'], $context['forum_name_html_safe'], $scripturl . '?action=login', 'return reqOverlayDiv(this.href, ' . JavaScriptEscape($txt['login']) . ');', $scripturl . '?action=signup'); |
||
224 | else |
||
225 | 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'])))) : ''; |
||
226 | } |
||
227 | // Don't echo... then do what?! |
||
228 | else |
||
229 | return $context['user']; |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Display a menu bar, like is displayed at the top of the forum. |
||
234 | * @param string $output_method The output method. If 'echo', will display the menu, otherwise returns an array of menu data. |
||
235 | * @return void|array Displays the menu or returns an array of menu data depending on output_method. |
||
236 | */ |
||
237 | function ssi_menubar($output_method = 'echo') |
||
238 | { |
||
239 | global $context; |
||
240 | |||
241 | if ($output_method == 'echo') |
||
242 | template_menu(); |
||
243 | // What else could this do? |
||
244 | else |
||
245 | return $context['menu_buttons']; |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * Show a logout link. |
||
250 | * @param string $redirect_to A URL to redirect the user to after they log out. |
||
251 | * @param string $output_method The output method. If 'echo', shows a logout link, otherwise returns the HTML for it. |
||
252 | * @return void|string Displays a logout link or returns its HTML depending on output_method. |
||
253 | */ |
||
254 | function ssi_logout($redirect_to = '', $output_method = 'echo') |
||
255 | { |
||
256 | global $context, $txt, $scripturl; |
||
257 | |||
258 | if ($redirect_to != '') |
||
259 | $_SESSION['logout_url'] = $redirect_to; |
||
260 | |||
261 | // Guests can't log out. |
||
262 | if ($context['user']['is_guest']) |
||
263 | return false; |
||
264 | |||
265 | $link = '<a href="' . $scripturl . '?action=logout;' . $context['session_var'] . '=' . $context['session_id'] . '">' . $txt['logout'] . '</a>'; |
||
266 | |||
267 | if ($output_method == 'echo') |
||
268 | echo $link; |
||
269 | else |
||
270 | return $link; |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Recent post list: [board] Subject by Poster Date |
||
275 | * @param int $num_recent How many recent posts to display |
||
276 | * @param null|array $exclude_boards If set, doesn't show posts from the specified boards |
||
277 | * @param null|array $include_boards If set, only includes posts from the specified boards |
||
278 | * @param string $output_method The output method. If 'echo', displays the posts, otherwise returns an array of information about them. |
||
279 | * @param bool $limit_body Whether or not to only show the first 384 characters of each post |
||
280 | * @return void|array Displays a list of recent posts or returns an array of information about them depending on output_method. |
||
281 | */ |
||
282 | function ssi_recentPosts($num_recent = 8, $exclude_boards = null, $include_boards = null, $output_method = 'echo', $limit_body = true) |
||
283 | { |
||
284 | global $modSettings, $context; |
||
285 | |||
286 | // Excluding certain boards... |
||
287 | View Code Duplication | if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0) |
|
288 | $exclude_boards = array($modSettings['recycle_board']); |
||
289 | else |
||
290 | $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards)); |
||
291 | |||
292 | // What about including certain boards - note we do some protection here as pre-2.0 didn't have this parameter. |
||
293 | View Code Duplication | if (is_array($include_boards) || (int) $include_boards === $include_boards) |
|
294 | { |
||
295 | $include_boards = is_array($include_boards) ? $include_boards : array($include_boards); |
||
296 | } |
||
297 | elseif ($include_boards != null) |
||
298 | { |
||
299 | $include_boards = array(); |
||
300 | } |
||
301 | |||
302 | // Let's restrict the query boys (and girls) |
||
303 | $query_where = ' |
||
304 | m.id_msg >= {int:min_message_id} |
||
305 | ' . (empty($exclude_boards) ? '' : ' |
||
306 | AND b.id_board NOT IN ({array_int:exclude_boards})') . ' |
||
307 | ' . ($include_boards === null ? '' : ' |
||
308 | AND b.id_board IN ({array_int:include_boards})') . ' |
||
309 | AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' |
||
310 | AND m.approved = {int:is_approved}' : ''); |
||
311 | |||
312 | $query_where_params = array( |
||
313 | 'is_approved' => 1, |
||
314 | 'include_boards' => $include_boards === null ? '' : $include_boards, |
||
315 | 'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards, |
||
316 | 'min_message_id' => $modSettings['maxMsgID'] - (!empty($context['min_message_posts']) ? $context['min_message_posts'] : 25) * min($num_recent, 5), |
||
317 | ); |
||
318 | |||
319 | // Past to this simpleton of a function... |
||
320 | return ssi_queryPosts($query_where, $query_where_params, $num_recent, 'm.id_msg DESC', $output_method, $limit_body); |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * Fetches one or more posts by ID. |
||
325 | * @param array $post_ids An array containing the IDs of the posts to show |
||
326 | * @param bool $override_permissions Whether to ignore permissions. If true, will show posts even if the user doesn't have permission to see them. |
||
327 | * @param string $output_method The output method. If 'echo', displays the posts, otherwise returns an array of info about them |
||
328 | * @return void|array Displays the specified posts or returns an array of info about them, depending on output_method. |
||
329 | */ |
||
330 | function ssi_fetchPosts($post_ids = array(), $override_permissions = false, $output_method = 'echo') |
||
331 | { |
||
332 | global $modSettings; |
||
333 | |||
334 | if (empty($post_ids)) |
||
335 | return; |
||
336 | |||
337 | // Allow the user to request more than one - why not? |
||
338 | $post_ids = is_array($post_ids) ? $post_ids : array($post_ids); |
||
339 | |||
340 | // Restrict the posts required... |
||
341 | $query_where = ' |
||
342 | m.id_msg IN ({array_int:message_list})' . ($override_permissions ? '' : ' |
||
343 | AND {query_wanna_see_board}') . ($modSettings['postmod_active'] ? ' |
||
344 | AND m.approved = {int:is_approved}' : ''); |
||
345 | $query_where_params = array( |
||
346 | 'message_list' => $post_ids, |
||
347 | 'is_approved' => 1, |
||
348 | ); |
||
349 | |||
350 | // Then make the query and dump the data. |
||
351 | return ssi_queryPosts($query_where, $query_where_params, '', 'm.id_msg DESC', $output_method, false, $override_permissions); |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * This handles actually pulling post info. Called from other functions to eliminate duplication. |
||
356 | * @param string $query_where The WHERE clause for the query |
||
357 | * @param array $query_where_params An array of parameters for the WHERE clause |
||
358 | * @param int $query_limit The maximum number of rows to return |
||
359 | * @param string $query_order The ORDER BY clause for the query |
||
360 | * @param string $output_method The output method. If 'echo', displays the posts, otherwise returns an array of info about them. |
||
361 | * @param bool $limit_body If true, will only show the first 384 characters of the post rather than all of it |
||
362 | * @param bool|false $override_permissions Whether or not to ignore permissions. If true, will show all posts regardless of whether the user can actually see them |
||
363 | * @return void|array Displays the posts or returns an array of info about them, depending on output_method |
||
364 | */ |
||
365 | 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) |
||
366 | { |
||
367 | global $scripturl, $txt, $user_info; |
||
368 | global $modSettings, $smcFunc, $context; |
||
369 | |||
370 | if (!empty($modSettings['enable_likes'])) |
||
371 | $context['can_like'] = allowedTo('likes_like'); |
||
372 | |||
373 | // Find all the posts. Newer ones will have higher IDs. |
||
374 | $request = $smcFunc['db_query']('substring', ' |
||
375 | SELECT |
||
376 | m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg, m.id_board, m.likes, b.name AS board_name, |
||
377 | IFNULL(mem.real_name, m.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : ' |
||
378 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= m.id_msg_modified AS is_read, |
||
379 | 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 |
||
380 | FROM {db_prefix}messages AS m |
||
381 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) |
||
382 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (!$user_info['is_guest'] ? ' |
||
383 | LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = m.id_topic AND lt.id_member = {int:current_member}) |
||
384 | LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = m.id_board AND lmr.id_member = {int:current_member})' : '') . ' |
||
385 | WHERE 1=1 ' . ($override_permissions ? '' : ' |
||
386 | AND {query_wanna_see_board}') . ($modSettings['postmod_active'] ? ' |
||
387 | AND m.approved = {int:is_approved}' : '') . ' |
||
388 | ' . (empty($query_where) ? '' : 'AND ' . $query_where) . ' |
||
389 | ORDER BY ' . $query_order . ' |
||
390 | ' . ($query_limit == '' ? '' : 'LIMIT ' . $query_limit), |
||
391 | array_merge($query_where_params, array( |
||
392 | 'current_member' => $user_info['id'], |
||
393 | 'is_approved' => 1, |
||
394 | )) |
||
395 | ); |
||
396 | $posts = array(); |
||
397 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
398 | { |
||
399 | $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']); |
||
400 | |||
401 | // Censor it! |
||
402 | censorText($row['subject']); |
||
403 | censorText($row['body']); |
||
404 | |||
405 | $preview = strip_tags(strtr($row['body'], array('<br>' => ' '))); |
||
406 | |||
407 | // Build the array. |
||
408 | $posts[$row['id_msg']] = array( |
||
409 | 'id' => $row['id_msg'], |
||
410 | 'board' => array( |
||
411 | 'id' => $row['id_board'], |
||
412 | 'name' => $row['board_name'], |
||
413 | 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', |
||
414 | 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>' |
||
415 | ), |
||
416 | 'topic' => $row['id_topic'], |
||
417 | 'poster' => array( |
||
418 | 'id' => $row['id_member'], |
||
419 | 'name' => $row['poster_name'], |
||
420 | 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], |
||
421 | 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' |
||
422 | ), |
||
423 | 'subject' => $row['subject'], |
||
424 | 'short_subject' => shorten_subject($row['subject'], 25), |
||
425 | 'preview' => $smcFunc['strlen']($preview) > 128 ? $smcFunc['substr']($preview, 0, 128) . '...' : $preview, |
||
426 | 'body' => $row['body'], |
||
427 | 'time' => timeformat($row['poster_time']), |
||
428 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
429 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new', |
||
430 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '" rel="nofollow">' . $row['subject'] . '</a>', |
||
431 | 'new' => !empty($row['is_read']), |
||
432 | 'is_new' => empty($row['is_read']), |
||
433 | 'new_from' => $row['new_from'], |
||
434 | ); |
||
435 | |||
436 | // Get the likes for each message. |
||
437 | View Code Duplication | if (!empty($modSettings['enable_likes'])) |
|
438 | $posts[$row['id_msg']]['likes'] = array( |
||
439 | 'count' => $row['likes'], |
||
440 | 'you' => in_array($row['id_msg'], prepareLikesContext($row['id_topic'])), |
||
441 | 'can_like' => !$context['user']['is_guest'] && $row['id_member'] != $context['user']['id'] && !empty($context['can_like']), |
||
442 | ); |
||
443 | } |
||
444 | $smcFunc['db_free_result']($request); |
||
445 | |||
446 | // If mods want to do somthing with this list of posts, let them do that now. |
||
447 | call_integration_hook('integrate_ssi_queryPosts', array(&$posts)); |
||
448 | |||
449 | // Just return it. |
||
450 | if ($output_method != 'echo' || empty($posts)) |
||
451 | return $posts; |
||
452 | |||
453 | echo ' |
||
454 | <table style="border: none" class="ssi_table">'; |
||
455 | View Code Duplication | foreach ($posts as $post) |
|
456 | echo ' |
||
457 | <tr> |
||
458 | <td style="text-align: right; vertical-align: top; white-space: nowrap"> |
||
459 | [', $post['board']['link'], '] |
||
460 | </td> |
||
461 | <td style="vertical-align: top"> |
||
462 | <a href="', $post['href'], '">', $post['subject'], '</a> |
||
463 | ', $txt['by'], ' ', $post['poster']['link'], ' |
||
464 | ', $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>' : '', ' |
||
465 | </td> |
||
466 | <td style="text-align: right; white-space: nowrap"> |
||
467 | ', $post['time'], ' |
||
468 | </td> |
||
469 | </tr>'; |
||
470 | echo ' |
||
471 | </table>'; |
||
472 | } |
||
473 | |||
474 | /** |
||
475 | * Recent topic list: [board] Subject by Poster Date |
||
476 | * @param int $num_recent How many recent topics to show |
||
477 | * @param null|array $exclude_boards If set, exclude topics from the specified board(s) |
||
478 | * @param null|array $include_boards If set, only include topics from the specified board(s) |
||
479 | * @param string $output_method The output method. If 'echo', displays a list of topics, otherwise returns an array of info about them |
||
480 | * @return void|array Either displays a list of topics or returns an array of info about them, depending on output_method. |
||
481 | */ |
||
482 | function ssi_recentTopics($num_recent = 8, $exclude_boards = null, $include_boards = null, $output_method = 'echo') |
||
483 | { |
||
484 | global $settings, $scripturl, $txt, $user_info; |
||
485 | global $modSettings, $smcFunc, $context; |
||
486 | |||
487 | View Code Duplication | if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0) |
|
488 | $exclude_boards = array($modSettings['recycle_board']); |
||
489 | else |
||
490 | $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards)); |
||
491 | |||
492 | // Only some boards?. |
||
493 | View Code Duplication | if (is_array($include_boards) || (int) $include_boards === $include_boards) |
|
494 | { |
||
495 | $include_boards = is_array($include_boards) ? $include_boards : array($include_boards); |
||
496 | } |
||
497 | elseif ($include_boards != null) |
||
498 | { |
||
499 | $output_method = $include_boards; |
||
500 | $include_boards = array(); |
||
501 | } |
||
502 | |||
503 | $icon_sources = array(); |
||
504 | foreach ($context['stable_icons'] as $icon) |
||
505 | $icon_sources[$icon] = 'images_url'; |
||
506 | |||
507 | // Find all the posts in distinct topics. Newer ones will have higher IDs. |
||
508 | $request = $smcFunc['db_query']('substring', ' |
||
509 | SELECT |
||
510 | t.id_topic, b.id_board, b.name AS board_name |
||
511 | FROM {db_prefix}topics AS t |
||
512 | INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) |
||
513 | LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) |
||
514 | WHERE t.id_last_msg >= {int:min_message_id}' . (empty($exclude_boards) ? '' : ' |
||
515 | AND b.id_board NOT IN ({array_int:exclude_boards})') . '' . (empty($include_boards) ? '' : ' |
||
516 | AND b.id_board IN ({array_int:include_boards})') . ' |
||
517 | AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' |
||
518 | AND t.approved = {int:is_approved} |
||
519 | AND ml.approved = {int:is_approved}' : '') . ' |
||
520 | ORDER BY t.id_last_msg DESC |
||
521 | LIMIT ' . $num_recent, |
||
522 | array( |
||
523 | 'include_boards' => empty($include_boards) ? '' : $include_boards, |
||
524 | 'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards, |
||
525 | 'min_message_id' => $modSettings['maxMsgID'] - (!empty($context['min_message_topics']) ? $context['min_message_topics'] : 35) * min($num_recent, 5), |
||
526 | 'is_approved' => 1, |
||
527 | ) |
||
528 | ); |
||
529 | $topics = array(); |
||
530 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
531 | $topics[$row['id_topic']] = $row; |
||
532 | $smcFunc['db_free_result']($request); |
||
533 | |||
534 | // Did we find anything? If not, bail. |
||
535 | if (empty($topics)) |
||
536 | return array(); |
||
537 | |||
538 | $recycle_board = !empty($modSettings['recycle_enable']) && !empty($modSettings['recycle_board']) ? (int) $modSettings['recycle_board'] : 0; |
||
539 | |||
540 | // Find all the posts in distinct topics. Newer ones will have higher IDs. |
||
541 | $request = $smcFunc['db_query']('substring', ' |
||
542 | SELECT |
||
543 | mf.poster_time, mf.subject, ml.id_topic, mf.id_member, ml.id_msg, t.num_replies, t.num_views, mg.online_color, |
||
544 | IFNULL(mem.real_name, mf.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : ' |
||
545 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= ml.id_msg_modified AS is_read, |
||
546 | IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from') . ', SUBSTRING(mf.body, 1, 384) AS body, mf.smileys_enabled, mf.icon |
||
547 | FROM {db_prefix}topics AS t |
||
548 | INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) |
||
549 | INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_last_msg) |
||
550 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mf.id_member)' . (!$user_info['is_guest'] ? ' |
||
551 | LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) |
||
552 | LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})' : '') . ' |
||
553 | LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = mem.id_group) |
||
554 | WHERE t.id_topic IN ({array_int:topic_list})', |
||
555 | array( |
||
556 | 'current_member' => $user_info['id'], |
||
557 | 'topic_list' => array_keys($topics), |
||
558 | ) |
||
559 | ); |
||
560 | $posts = array(); |
||
561 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
562 | { |
||
563 | $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), array('<br>' => ' '))); |
||
564 | View Code Duplication | if ($smcFunc['strlen']($row['body']) > 128) |
|
565 | $row['body'] = $smcFunc['substr']($row['body'], 0, 128) . '...'; |
||
566 | |||
567 | // Censor the subject. |
||
568 | censorText($row['subject']); |
||
569 | censorText($row['body']); |
||
570 | |||
571 | // Recycled icon |
||
572 | if (!empty($recycle_board) && $topics[$row['id_topic']]['id_board']) |
||
573 | $row['icon'] = 'recycled'; |
||
574 | |||
575 | View Code Duplication | if (!empty($modSettings['messageIconChecks_enable']) && !isset($icon_sources[$row['icon']])) |
|
576 | $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url'; |
||
577 | |||
578 | // Build the array. |
||
579 | $posts[] = array( |
||
580 | 'board' => array( |
||
581 | 'id' => $topics[$row['id_topic']]['id_board'], |
||
582 | 'name' => $topics[$row['id_topic']]['board_name'], |
||
583 | 'href' => $scripturl . '?board=' . $topics[$row['id_topic']]['id_board'] . '.0', |
||
584 | 'link' => '<a href="' . $scripturl . '?board=' . $topics[$row['id_topic']]['id_board'] . '.0">' . $topics[$row['id_topic']]['board_name'] . '</a>', |
||
585 | ), |
||
586 | 'topic' => $row['id_topic'], |
||
587 | 'poster' => array( |
||
588 | 'id' => $row['id_member'], |
||
589 | 'name' => $row['poster_name'], |
||
590 | 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], |
||
591 | 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' |
||
592 | ), |
||
593 | 'subject' => $row['subject'], |
||
594 | 'replies' => $row['num_replies'], |
||
595 | 'views' => $row['num_views'], |
||
596 | 'short_subject' => shorten_subject($row['subject'], 25), |
||
597 | 'preview' => $row['body'], |
||
598 | 'time' => timeformat($row['poster_time']), |
||
599 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
600 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new', |
||
601 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#new" rel="nofollow">' . $row['subject'] . '</a>', |
||
602 | // Retained for compatibility - is technically incorrect! |
||
603 | 'new' => !empty($row['is_read']), |
||
604 | 'is_new' => empty($row['is_read']), |
||
605 | 'new_from' => $row['new_from'], |
||
606 | 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.png" style="vertical-align:middle;" alt="' . $row['icon'] . '">', |
||
607 | ); |
||
608 | } |
||
609 | $smcFunc['db_free_result']($request); |
||
610 | |||
611 | // If mods want to do somthing with this list of topics, let them do that now. |
||
612 | call_integration_hook('integrate_ssi_recentTopics', array(&$posts)); |
||
613 | |||
614 | // Just return it. |
||
615 | if ($output_method != 'echo' || empty($posts)) |
||
616 | return $posts; |
||
617 | |||
618 | echo ' |
||
619 | <table style="border: none" class="ssi_table">'; |
||
620 | View Code Duplication | foreach ($posts as $post) |
|
621 | echo ' |
||
622 | <tr> |
||
623 | <td style="text-align: right; vertical-align: top; white-space: nowrap"> |
||
624 | [', $post['board']['link'], '] |
||
625 | </td> |
||
626 | <td style="vertical-align: top"> |
||
627 | <a href="', $post['href'], '">', $post['subject'], '</a> |
||
628 | ', $txt['by'], ' ', $post['poster']['link'], ' |
||
629 | ', !$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>', ' |
||
630 | </td> |
||
631 | <td style="text-align: right; white-space: nowrap"> |
||
632 | ', $post['time'], ' |
||
633 | </td> |
||
634 | </tr>'; |
||
635 | echo ' |
||
636 | </table>'; |
||
637 | } |
||
638 | |||
639 | /** |
||
640 | * Shows a list of top posters |
||
641 | * @param int $topNumber How many top posters to list |
||
642 | * @param string $output_method The output method. If 'echo', will display a list of users, otherwise returns an array of info about them. |
||
643 | * @return void|array Either displays a list of users or returns an array of info about them, depending on output_method. |
||
644 | */ |
||
645 | function ssi_topPoster($topNumber = 1, $output_method = 'echo') |
||
646 | { |
||
647 | global $scripturl, $smcFunc; |
||
648 | |||
649 | // Find the latest poster. |
||
650 | $request = $smcFunc['db_query']('', ' |
||
651 | SELECT id_member, real_name, posts |
||
652 | FROM {db_prefix}members |
||
653 | ORDER BY posts DESC |
||
654 | LIMIT ' . $topNumber, |
||
655 | array( |
||
656 | ) |
||
657 | ); |
||
658 | $return = array(); |
||
659 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
660 | $return[] = array( |
||
661 | 'id' => $row['id_member'], |
||
662 | 'name' => $row['real_name'], |
||
663 | 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], |
||
664 | 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', |
||
665 | 'posts' => $row['posts'] |
||
666 | ); |
||
667 | $smcFunc['db_free_result']($request); |
||
668 | |||
669 | // If mods want to do somthing with this list of members, let them do that now. |
||
670 | call_integration_hook('integrate_ssi_topPoster', array(&$return)); |
||
671 | |||
672 | // Just return all the top posters. |
||
673 | if ($output_method != 'echo') |
||
674 | return $return; |
||
675 | |||
676 | // Make a quick array to list the links in. |
||
677 | $temp_array = array(); |
||
678 | foreach ($return as $member) |
||
679 | $temp_array[] = $member['link']; |
||
680 | |||
681 | echo implode(', ', $temp_array); |
||
682 | } |
||
683 | |||
684 | /** |
||
685 | * Shows a list of top boards based on activity |
||
686 | * @param int $num_top How many boards to display |
||
687 | * @param string $output_method The output method. If 'echo', displays a list of boards, otherwise returns an array of info about them. |
||
688 | * @return void|array Displays a list of the top boards or returns an array of info about them, depending on output_method. |
||
689 | */ |
||
690 | function ssi_topBoards($num_top = 10, $output_method = 'echo') |
||
691 | { |
||
692 | global $txt, $scripturl, $user_info, $modSettings, $smcFunc; |
||
693 | |||
694 | // Find boards with lots of posts. |
||
695 | $request = $smcFunc['db_query']('', ' |
||
696 | SELECT |
||
697 | b.name, b.num_topics, b.num_posts, b.id_board,' . (!$user_info['is_guest'] ? ' 1 AS is_read' : ' |
||
698 | (IFNULL(lb.id_msg, 0) >= b.id_last_msg) AS is_read') . ' |
||
699 | FROM {db_prefix}boards AS b |
||
700 | LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member}) |
||
701 | WHERE {query_wanna_see_board}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' |
||
702 | AND b.id_board != {int:recycle_board}' : '') . ' |
||
703 | ORDER BY b.num_posts DESC |
||
704 | LIMIT ' . $num_top, |
||
705 | array( |
||
706 | 'current_member' => $user_info['id'], |
||
707 | 'recycle_board' => (int) $modSettings['recycle_board'], |
||
708 | ) |
||
709 | ); |
||
710 | $boards = array(); |
||
711 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
712 | $boards[] = array( |
||
713 | 'id' => $row['id_board'], |
||
714 | 'num_posts' => $row['num_posts'], |
||
715 | 'num_topics' => $row['num_topics'], |
||
716 | 'name' => $row['name'], |
||
717 | 'new' => empty($row['is_read']), |
||
718 | 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', |
||
719 | 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['name'] . '</a>' |
||
720 | ); |
||
721 | $smcFunc['db_free_result']($request); |
||
722 | |||
723 | // If mods want to do somthing with this list of boards, let them do that now. |
||
724 | call_integration_hook('integrate_ssi_topBoards', array(&$boards)); |
||
725 | |||
726 | // If we shouldn't output or have nothing to output, just jump out. |
||
727 | if ($output_method != 'echo' || empty($boards)) |
||
728 | return $boards; |
||
729 | |||
730 | echo ' |
||
731 | <table class="ssi_table"> |
||
732 | <tr> |
||
733 | <th style="text-align: left">', $txt['board'], '</th> |
||
734 | <th style="text-align: left">', $txt['board_topics'], '</th> |
||
735 | <th style="text-align: left">', $txt['posts'], '</th> |
||
736 | </tr>'; |
||
737 | foreach ($boards as $sBoard) |
||
738 | echo ' |
||
739 | <tr> |
||
740 | <td>', $sBoard['link'], $sBoard['new'] ? ' <a href="' . $sBoard['href'] . '"><span class="new_posts">' . $txt['new'] . '</span></a>' : '', '</td> |
||
741 | <td style="text-align: right">', comma_format($sBoard['num_topics']), '</td> |
||
742 | <td style="text-align: right">', comma_format($sBoard['num_posts']), '</td> |
||
743 | </tr>'; |
||
744 | echo ' |
||
745 | </table>'; |
||
746 | } |
||
747 | |||
748 | // Shows the top topics. |
||
749 | /** |
||
750 | * Shows a list of top topics based on views or replies |
||
751 | * @param string $type Can be either replies or views |
||
752 | * @param int $num_topics How many topics to display |
||
753 | * @param string $output_method The output method. If 'echo', displays a list of topics, otherwise returns an array of info about them. |
||
754 | * @return void|array Either displays a list of topics or returns an array of info about them, depending on output_method. |
||
755 | */ |
||
756 | function ssi_topTopics($type = 'replies', $num_topics = 10, $output_method = 'echo') |
||
757 | { |
||
758 | global $txt, $scripturl, $modSettings, $smcFunc; |
||
759 | |||
760 | if ($modSettings['totalMessages'] > 100000) |
||
761 | { |
||
762 | // @todo Why don't we use {query(_wanna)_see_board}? |
||
763 | $request = $smcFunc['db_query']('', ' |
||
764 | SELECT id_topic |
||
765 | FROM {db_prefix}topics |
||
766 | WHERE num_' . ($type != 'replies' ? 'views' : 'replies') . ' != 0' . ($modSettings['postmod_active'] ? ' |
||
767 | AND approved = {int:is_approved}' : '') . ' |
||
768 | ORDER BY num_' . ($type != 'replies' ? 'views' : 'replies') . ' DESC |
||
769 | LIMIT {int:limit}', |
||
770 | array( |
||
771 | 'is_approved' => 1, |
||
772 | 'limit' => $num_topics > 100 ? ($num_topics + ($num_topics / 2)) : 100, |
||
773 | ) |
||
774 | ); |
||
775 | $topic_ids = array(); |
||
776 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
777 | $topic_ids[] = $row['id_topic']; |
||
778 | $smcFunc['db_free_result']($request); |
||
779 | } |
||
780 | else |
||
781 | $topic_ids = array(); |
||
782 | |||
783 | $request = $smcFunc['db_query']('', ' |
||
784 | SELECT m.subject, m.id_topic, t.num_views, t.num_replies |
||
785 | FROM {db_prefix}topics AS t |
||
786 | INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) |
||
787 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) |
||
788 | WHERE {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' |
||
789 | AND t.approved = {int:is_approved}' : '') . (!empty($topic_ids) ? ' |
||
790 | AND t.id_topic IN ({array_int:topic_list})' : '') . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' |
||
791 | AND b.id_board != {int:recycle_enable}' : '') . ' |
||
792 | ORDER BY t.num_' . ($type != 'replies' ? 'views' : 'replies') . ' DESC |
||
793 | LIMIT {int:limit}', |
||
794 | array( |
||
795 | 'topic_list' => $topic_ids, |
||
796 | 'is_approved' => 1, |
||
797 | 'recycle_enable' => $modSettings['recycle_board'], |
||
798 | 'limit' => $num_topics, |
||
799 | ) |
||
800 | ); |
||
801 | $topics = array(); |
||
802 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
803 | { |
||
804 | censorText($row['subject']); |
||
805 | |||
806 | $topics[] = array( |
||
807 | 'id' => $row['id_topic'], |
||
808 | 'subject' => $row['subject'], |
||
809 | 'num_replies' => $row['num_replies'], |
||
810 | 'num_views' => $row['num_views'], |
||
811 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0', |
||
812 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['subject'] . '</a>', |
||
813 | ); |
||
814 | } |
||
815 | $smcFunc['db_free_result']($request); |
||
816 | |||
817 | // If mods want to do somthing with this list of topics, let them do that now. |
||
818 | call_integration_hook('integrate_ssi_topTopics', array(&$topics, $type)); |
||
819 | |||
820 | if ($output_method != 'echo' || empty($topics)) |
||
821 | return $topics; |
||
822 | |||
823 | echo ' |
||
824 | <table class="ssi_table"> |
||
825 | <tr> |
||
826 | <th style="text-align: left"></th> |
||
827 | <th style="text-align: left">', $txt['views'], '</th> |
||
828 | <th style="text-align: left">', $txt['replies'], '</th> |
||
829 | </tr>'; |
||
830 | foreach ($topics as $sTopic) |
||
831 | echo ' |
||
832 | <tr> |
||
833 | <td style="text-align: left"> |
||
834 | ', $sTopic['link'], ' |
||
835 | </td> |
||
836 | <td style="text-align: right">', comma_format($sTopic['num_views']), '</td> |
||
837 | <td style="text-align: right">', comma_format($sTopic['num_replies']), '</td> |
||
838 | </tr>'; |
||
839 | echo ' |
||
840 | </table>'; |
||
841 | } |
||
842 | |||
843 | /** |
||
844 | * Top topics based on replies |
||
845 | * @param int $num_topics How many topics to show |
||
846 | * @param string $output_method The output method. If 'echo', displays a list of topics, otherwise returns an array of info about them |
||
847 | * @return void|array Either displays a list of top topics or returns an array of info about them, depending on output_method. |
||
848 | */ |
||
849 | function ssi_topTopicsReplies($num_topics = 10, $output_method = 'echo') |
||
850 | { |
||
851 | return ssi_topTopics('replies', $num_topics, $output_method); |
||
852 | } |
||
853 | |||
854 | /** |
||
855 | * Top topics based on views |
||
856 | * @param int $num_topics How many topics to show |
||
857 | * @param string $output_method The output method. If 'echo', displays a list of topics, otherwise returns an array of info about them |
||
858 | * @return void|array Either displays a list of top topics or returns an array of info about them, depending on output_method. |
||
859 | */ |
||
860 | function ssi_topTopicsViews($num_topics = 10, $output_method = 'echo') |
||
861 | { |
||
862 | return ssi_topTopics('views', $num_topics, $output_method); |
||
863 | } |
||
864 | |||
865 | /** |
||
866 | * Show a link to the latest member: Please welcome, Someone, our latest member. |
||
867 | * @param string $output_method The output method. If 'echo', returns a string with a link to the latest member's profile, otherwise returns an array of info about them. |
||
868 | * @return void|array Displays a "welcome" message for the latest member or returns an array of info about them, depending on output_method. |
||
869 | */ |
||
870 | function ssi_latestMember($output_method = 'echo') |
||
871 | { |
||
872 | global $txt, $context; |
||
873 | |||
874 | if ($output_method == 'echo') |
||
875 | echo ' |
||
876 | ', sprintf($txt['welcome_newest_member'], $context['common_stats']['latest_member']['link']), '<br>'; |
||
877 | else |
||
878 | return $context['common_stats']['latest_member']; |
||
879 | } |
||
880 | |||
881 | /** |
||
882 | * Fetches a random member. |
||
883 | * @param string $random_type If 'day', only fetches a new random member once a day. |
||
884 | * @param string $output_method The output method. If 'echo', displays a link to the member's profile, otherwise returns an array of info about them. |
||
885 | * @return void|array Displays a link to a random member's profile or returns an array of info about them depending on output_method. |
||
886 | */ |
||
887 | function ssi_randomMember($random_type = '', $output_method = 'echo') |
||
888 | { |
||
889 | global $modSettings; |
||
890 | |||
891 | // If we're looking for something to stay the same each day then seed the generator. |
||
892 | if ($random_type == 'day') |
||
893 | { |
||
894 | // Set the seed to change only once per day. |
||
895 | mt_srand(floor(time() / 86400)); |
||
896 | } |
||
897 | |||
898 | // Get the lowest ID we're interested in. |
||
899 | $member_id = mt_rand(1, $modSettings['latestMember']); |
||
900 | |||
901 | $where_query = ' |
||
902 | id_member >= {int:selected_member} |
||
903 | AND is_activated = {int:is_activated}'; |
||
904 | |||
905 | $query_where_params = array( |
||
906 | 'selected_member' => $member_id, |
||
907 | 'is_activated' => 1, |
||
908 | ); |
||
909 | |||
910 | $result = ssi_queryMembers($where_query, $query_where_params, 1, 'id_member ASC', $output_method); |
||
911 | |||
912 | // If we got nothing do the reverse - in case of unactivated members. |
||
913 | if (empty($result)) |
||
914 | { |
||
915 | $where_query = ' |
||
916 | id_member <= {int:selected_member} |
||
917 | AND is_activated = {int:is_activated}'; |
||
918 | |||
919 | $query_where_params = array( |
||
920 | 'selected_member' => $member_id, |
||
921 | 'is_activated' => 1, |
||
922 | ); |
||
923 | |||
924 | $result = ssi_queryMembers($where_query, $query_where_params, 1, 'id_member DESC', $output_method); |
||
925 | } |
||
926 | |||
927 | // Just to be sure put the random generator back to something... random. |
||
928 | if ($random_type != '') |
||
929 | mt_srand(time()); |
||
930 | |||
931 | return $result; |
||
932 | } |
||
933 | |||
934 | /** |
||
935 | * Fetch specific members |
||
936 | * @param array $member_ids The IDs of the members to fetch |
||
937 | * @param string $output_method The output method. If 'echo', displays a list of links to the members' profiles, otherwise returns an array of info about them. |
||
938 | * @return void|array Displays links to the specified members' profiles or returns an array of info about them, depending on output_method. |
||
939 | */ |
||
940 | function ssi_fetchMember($member_ids = array(), $output_method = 'echo') |
||
941 | { |
||
942 | if (empty($member_ids)) |
||
943 | return; |
||
944 | |||
945 | // Can have more than one member if you really want... |
||
946 | $member_ids = is_array($member_ids) ? $member_ids : array($member_ids); |
||
947 | |||
948 | // Restrict it right! |
||
949 | $query_where = ' |
||
950 | id_member IN ({array_int:member_list})'; |
||
951 | |||
952 | $query_where_params = array( |
||
953 | 'member_list' => $member_ids, |
||
954 | ); |
||
955 | |||
956 | // Then make the query and dump the data. |
||
957 | return ssi_queryMembers($query_where, $query_where_params, '', 'id_member', $output_method); |
||
958 | } |
||
959 | |||
960 | /** |
||
961 | * Get al members in the specified group |
||
962 | * @param int $group_id The ID of the group to get members from |
||
963 | * @param string $output_method The output method. If 'echo', returns a list of group members, otherwise returns an array of info about them. |
||
964 | * @return void|array Displays a list of group members or returns an array of info about them, depending on output_method. |
||
965 | */ |
||
966 | function ssi_fetchGroupMembers($group_id = null, $output_method = 'echo') |
||
967 | { |
||
968 | if ($group_id === null) |
||
969 | return; |
||
970 | |||
971 | $query_where = ' |
||
972 | id_group = {int:id_group} |
||
973 | OR id_post_group = {int:id_group} |
||
974 | OR FIND_IN_SET({int:id_group}, additional_groups) != 0'; |
||
975 | |||
976 | $query_where_params = array( |
||
977 | 'id_group' => $group_id, |
||
978 | ); |
||
979 | |||
980 | return ssi_queryMembers($query_where, $query_where_params, '', 'real_name', $output_method); |
||
981 | } |
||
982 | |||
983 | /** |
||
984 | * Pulls info about members based on the specified parameters. Used by other functions to eliminate duplication. |
||
985 | * @param string $query_where The info for the WHERE clause of the query |
||
986 | * @param array $query_where_params The parameters for the WHERE clause |
||
987 | * @param string|int $query_limit The number of rows to return or an empty string to return all |
||
988 | * @param string $query_order The info for the ORDER BY clause of the query |
||
989 | * @param string $output_method The output method. If 'echo', displays a list of members, otherwise returns an array of info about them |
||
990 | * @return void|array Displays a list of members or returns an array of info about them, depending on output_method. |
||
991 | */ |
||
992 | function ssi_queryMembers($query_where = null, $query_where_params = array(), $query_limit = '', $query_order = 'id_member DESC', $output_method = 'echo') |
||
993 | { |
||
994 | global $smcFunc, $memberContext; |
||
995 | |||
996 | if ($query_where === null) |
||
997 | return; |
||
998 | |||
999 | // Fetch the members in question. |
||
1000 | $request = $smcFunc['db_query']('', ' |
||
1001 | SELECT id_member |
||
1002 | FROM {db_prefix}members |
||
1003 | WHERE ' . $query_where . ' |
||
1004 | ORDER BY ' . $query_order . ' |
||
1005 | ' . ($query_limit == '' ? '' : 'LIMIT ' . $query_limit), |
||
1006 | array_merge($query_where_params, array( |
||
1007 | )) |
||
1008 | ); |
||
1009 | $members = array(); |
||
1010 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1011 | $members[] = $row['id_member']; |
||
1012 | $smcFunc['db_free_result']($request); |
||
1013 | |||
1014 | if (empty($members)) |
||
1015 | return array(); |
||
1016 | |||
1017 | // If mods want to do somthing with this list of members, let them do that now. |
||
1018 | call_integration_hook('integrate_ssi_queryMembers', array(&$members)); |
||
1019 | |||
1020 | // Load the members. |
||
1021 | loadMemberData($members); |
||
1022 | |||
1023 | // Draw the table! |
||
1024 | if ($output_method == 'echo') |
||
1025 | echo ' |
||
1026 | <table style="border: none" class="ssi_table">'; |
||
1027 | |||
1028 | $query_members = array(); |
||
1029 | foreach ($members as $member) |
||
1030 | { |
||
1031 | // Load their context data. |
||
1032 | if (!loadMemberContext($member)) |
||
1033 | continue; |
||
1034 | |||
1035 | // Store this member's information. |
||
1036 | $query_members[$member] = $memberContext[$member]; |
||
1037 | |||
1038 | // Only do something if we're echo'ing. |
||
1039 | if ($output_method == 'echo') |
||
1040 | echo ' |
||
1041 | <tr> |
||
1042 | <td style="text-align: right; vertical-align: top; white-space: nowrap"> |
||
1043 | ', $query_members[$member]['link'], ' |
||
1044 | <br>', $query_members[$member]['blurb'], ' |
||
1045 | <br>', $query_members[$member]['avatar']['image'], ' |
||
1046 | </td> |
||
1047 | </tr>'; |
||
1048 | } |
||
1049 | |||
1050 | // End the table if appropriate. |
||
1051 | if ($output_method == 'echo') |
||
1052 | echo ' |
||
1053 | </table>'; |
||
1054 | |||
1055 | // Send back the data. |
||
1056 | return $query_members; |
||
1057 | } |
||
1058 | |||
1059 | /** |
||
1060 | * Show some basic stats: Total This: XXXX, etc. |
||
1061 | * @param string $output_method The output method. If 'echo', displays the stats, otherwise returns an array of info about them |
||
1062 | * @return void|array Doesn't return anything if the user can't view stats. Otherwise either displays the stats or returns an array of info about them, depending on output_method. |
||
1063 | */ |
||
1064 | function ssi_boardStats($output_method = 'echo') |
||
1065 | { |
||
1066 | global $txt, $scripturl, $modSettings, $smcFunc; |
||
1067 | |||
1068 | if (!allowedTo('view_stats')) |
||
1069 | return; |
||
1070 | |||
1071 | $totals = array( |
||
1072 | 'members' => $modSettings['totalMembers'], |
||
1073 | 'posts' => $modSettings['totalMessages'], |
||
1074 | 'topics' => $modSettings['totalTopics'] |
||
1075 | ); |
||
1076 | |||
1077 | $result = $smcFunc['db_query']('', ' |
||
1078 | SELECT COUNT(*) |
||
1079 | FROM {db_prefix}boards', |
||
1080 | array( |
||
1081 | ) |
||
1082 | ); |
||
1083 | list ($totals['boards']) = $smcFunc['db_fetch_row']($result); |
||
1084 | $smcFunc['db_free_result']($result); |
||
1085 | |||
1086 | $result = $smcFunc['db_query']('', ' |
||
1087 | SELECT COUNT(*) |
||
1088 | FROM {db_prefix}categories', |
||
1089 | array( |
||
1090 | ) |
||
1091 | ); |
||
1092 | list ($totals['categories']) = $smcFunc['db_fetch_row']($result); |
||
1093 | $smcFunc['db_free_result']($result); |
||
1094 | |||
1095 | // If mods want to do somthing with the board stats, let them do that now. |
||
1096 | call_integration_hook('integrate_ssi_boardStats', array(&$totals)); |
||
1097 | |||
1098 | if ($output_method != 'echo') |
||
1099 | return $totals; |
||
1100 | |||
1101 | echo ' |
||
1102 | ', $txt['total_members'], ': <a href="', $scripturl . '?action=mlist">', comma_format($totals['members']), '</a><br> |
||
1103 | ', $txt['total_posts'], ': ', comma_format($totals['posts']), '<br> |
||
1104 | ', $txt['total_topics'], ': ', comma_format($totals['topics']), ' <br> |
||
1105 | ', $txt['total_cats'], ': ', comma_format($totals['categories']), '<br> |
||
1106 | ', $txt['total_boards'], ': ', comma_format($totals['boards']); |
||
1107 | } |
||
1108 | |||
1109 | /** |
||
1110 | * Shows a list of online users: YY Guests, ZZ Users and then a list... |
||
1111 | * @param string $output_method The output method. If 'echo', displays a list, otherwise returns an array of info about the online users. |
||
1112 | * @return void|array Either displays a list of online users or returns an array of info about them, depending on output_method. |
||
1113 | */ |
||
1114 | function ssi_whosOnline($output_method = 'echo') |
||
1115 | { |
||
1116 | global $user_info, $txt, $sourcedir, $settings; |
||
1117 | |||
1118 | require_once($sourcedir . '/Subs-MembersOnline.php'); |
||
1119 | $membersOnlineOptions = array( |
||
1120 | 'show_hidden' => allowedTo('moderate_forum'), |
||
1121 | ); |
||
1122 | $return = getMembersOnlineStats($membersOnlineOptions); |
||
1123 | |||
1124 | // If mods want to do somthing with the list of who is online, let them do that now. |
||
1125 | call_integration_hook('integrate_ssi_whosOnline', array(&$return)); |
||
1126 | |||
1127 | // Add some redundancy for backwards compatibility reasons. |
||
1128 | if ($output_method != 'echo') |
||
1129 | return $return + array( |
||
1130 | 'users' => $return['users_online'], |
||
1131 | 'guests' => $return['num_guests'], |
||
1132 | 'hidden' => $return['num_users_hidden'], |
||
1133 | 'buddies' => $return['num_buddies'], |
||
1134 | 'num_users' => $return['num_users_online'], |
||
1135 | 'total_users' => $return['num_users_online'] + $return['num_guests'], |
||
1136 | ); |
||
1137 | |||
1138 | echo ' |
||
1139 | ', 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']; |
||
1140 | |||
1141 | $bracketList = array(); |
||
1142 | View Code Duplication | if (!empty($user_info['buddies'])) |
|
1143 | $bracketList[] = comma_format($return['num_buddies']) . ' ' . ($return['num_buddies'] == 1 ? $txt['buddy'] : $txt['buddies']); |
||
1144 | View Code Duplication | if (!empty($return['num_spiders'])) |
|
1145 | $bracketList[] = comma_format($return['num_spiders']) . ' ' . ($return['num_spiders'] == 1 ? $txt['spider'] : $txt['spiders']); |
||
1146 | if (!empty($return['num_users_hidden'])) |
||
1147 | $bracketList[] = comma_format($return['num_users_hidden']) . ' ' . $txt['hidden']; |
||
1148 | |||
1149 | if (!empty($bracketList)) |
||
1150 | echo ' (' . implode(', ', $bracketList) . ')'; |
||
1151 | |||
1152 | echo '<br> |
||
1153 | ', implode(', ', $return['list_users_online']); |
||
1154 | |||
1155 | // Showing membergroups? |
||
1156 | View Code Duplication | if (!empty($settings['show_group_key']) && !empty($return['membergroups'])) |
|
1157 | echo '<br> |
||
1158 | [' . implode('] [', $return['membergroups']) . ']'; |
||
1159 | } |
||
1160 | |||
1161 | /** |
||
1162 | * Just like whosOnline except it also logs the online presence. |
||
1163 | * @param string $output_method The output method. If 'echo', displays a list, otherwise returns an array of info about the online users. |
||
1164 | * @return void|array Either displays a list of online users or returns an aray of info about them, depending on output_method. |
||
1165 | */ |
||
1166 | function ssi_logOnline($output_method = 'echo') |
||
1167 | { |
||
1168 | writeLog(); |
||
1169 | |||
1170 | if ($output_method != 'echo') |
||
1171 | return ssi_whosOnline($output_method); |
||
1172 | else |
||
1173 | ssi_whosOnline($output_method); |
||
1174 | } |
||
1175 | |||
1176 | // Shows a login box. |
||
1177 | /** |
||
1178 | * Shows a login box |
||
1179 | * @param string $redirect_to The URL to redirect the user to after they login |
||
1180 | * @param string $output_method The output method. If 'echo' and the user is a guest, displays a login box, otherwise returns whether the user is a guest |
||
1181 | * @return void|bool Either displays a login box or returns whether the user is a guest, depending on whether the user is logged in and output_method. |
||
1182 | */ |
||
1183 | function ssi_login($redirect_to = '', $output_method = 'echo') |
||
1184 | { |
||
1185 | global $scripturl, $txt, $user_info, $context; |
||
1186 | |||
1187 | if ($redirect_to != '') |
||
1188 | $_SESSION['login_url'] = $redirect_to; |
||
1189 | |||
1190 | if ($output_method != 'echo' || !$user_info['is_guest']) |
||
1191 | return $user_info['is_guest']; |
||
1192 | |||
1193 | // Create a login token |
||
1194 | createToken('login'); |
||
1195 | |||
1196 | echo ' |
||
1197 | <form action="', $scripturl, '?action=login2" method="post" accept-charset="', $context['character_set'], '"> |
||
1198 | <table style="border: none" class="ssi_table"> |
||
1199 | <tr> |
||
1200 | <td style="text-align: right; border-spacing: 1"><label for="user">', $txt['username'], ':</label> </td> |
||
1201 | <td><input type="text" id="user" name="user" size="9" value="', $user_info['username'], '" class="input_text"></td> |
||
1202 | </tr><tr> |
||
1203 | <td style="text-align: right; border-spacing: 1"><label for="passwrd">', $txt['password'], ':</label> </td> |
||
1204 | <td><input type="password" name="passwrd" id="passwrd" size="9" class="input_password"></td> |
||
1205 | </tr> |
||
1206 | <tr> |
||
1207 | <td> |
||
1208 | <input type="hidden" name="cookielength" value="-1"> |
||
1209 | <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
||
1210 | <input type="hidden" name="', $context['login_token_var'], '" value="', $context['login_token'], '"> |
||
1211 | </td> |
||
1212 | <td><input type="submit" value="', $txt['login'], '" class="button_submit"></td> |
||
1213 | </tr> |
||
1214 | </table> |
||
1215 | </form>'; |
||
1216 | |||
1217 | } |
||
1218 | |||
1219 | /** |
||
1220 | * Show the top poll based on votes |
||
1221 | * @param string $output_method The output method. If 'echo', displays the poll, otherwise returns an array of info about it |
||
1222 | * @return void|array Either shows the top poll or returns an array of info about it, depending on output_method. |
||
1223 | */ |
||
1224 | function ssi_topPoll($output_method = 'echo') |
||
1225 | { |
||
1226 | // Just use recentPoll, no need to duplicate code... |
||
1227 | return ssi_recentPoll(true, $output_method); |
||
1228 | } |
||
1229 | |||
1230 | // Show the most recently posted poll. |
||
1231 | /** |
||
1232 | * Shows the most recent poll |
||
1233 | * @param bool $topPollInstead Whether to show the top poll (based on votes) instead of the most recent one |
||
1234 | * @param string $output_method The output method. If 'echo', displays the poll, otherwise returns an array of info about it. |
||
1235 | * @return void|array Either shows the poll or returns an array of info about it, depending on output_method. |
||
1236 | */ |
||
1237 | function ssi_recentPoll($topPollInstead = false, $output_method = 'echo') |
||
1238 | { |
||
1239 | global $txt, $boardurl, $user_info, $context, $smcFunc, $modSettings; |
||
1240 | |||
1241 | $boardsAllowed = array_intersect(boardsAllowedTo('poll_view'), boardsAllowedTo('poll_vote')); |
||
1242 | |||
1243 | if (empty($boardsAllowed)) |
||
1244 | return array(); |
||
1245 | |||
1246 | $request = $smcFunc['db_query']('', ' |
||
1247 | SELECT p.id_poll, p.question, t.id_topic, p.max_votes, p.guest_vote, p.hide_results, p.expire_time |
||
1248 | FROM {db_prefix}polls AS p |
||
1249 | INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ') |
||
1250 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)' . ($topPollInstead ? ' |
||
1251 | INNER JOIN {db_prefix}poll_choices AS pc ON (pc.id_poll = p.id_poll)' : '') . ' |
||
1252 | 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}) |
||
1253 | WHERE p.voting_locked = {int:voting_opened} |
||
1254 | AND (p.expire_time = {int:no_expiration} OR {int:current_time} < p.expire_time) |
||
1255 | AND ' . ($user_info['is_guest'] ? 'p.guest_vote = {int:guest_vote_allowed}' : 'lp.id_choice IS NULL') . ' |
||
1256 | AND {query_wanna_see_board}' . (!in_array(0, $boardsAllowed) ? ' |
||
1257 | AND b.id_board IN ({array_int:boards_allowed_list})' : '') . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' |
||
1258 | AND b.id_board != {int:recycle_enable}' : '') . ' |
||
1259 | ORDER BY ' . ($topPollInstead ? 'pc.votes' : 'p.id_poll') . ' DESC |
||
1260 | LIMIT 1', |
||
1261 | array( |
||
1262 | 'current_member' => $user_info['id'], |
||
1263 | 'boards_allowed_list' => $boardsAllowed, |
||
1264 | 'is_approved' => 1, |
||
1265 | 'guest_vote_allowed' => 1, |
||
1266 | 'no_member' => 0, |
||
1267 | 'voting_opened' => 0, |
||
1268 | 'no_expiration' => 0, |
||
1269 | 'current_time' => time(), |
||
1270 | 'recycle_enable' => $modSettings['recycle_board'], |
||
1271 | ) |
||
1272 | ); |
||
1273 | $row = $smcFunc['db_fetch_assoc']($request); |
||
1274 | $smcFunc['db_free_result']($request); |
||
1275 | |||
1276 | // This user has voted on all the polls. |
||
1277 | if (empty($row) || !is_array($row)) |
||
1278 | return array(); |
||
1279 | |||
1280 | // If this is a guest who's voted we'll through ourselves to show poll to show the results. |
||
1281 | if ($user_info['is_guest'] && (!$row['guest_vote'] || (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote']))))) |
||
1282 | return ssi_showPoll($row['id_topic'], $output_method); |
||
1283 | |||
1284 | $request = $smcFunc['db_query']('', ' |
||
1285 | SELECT COUNT(DISTINCT id_member) |
||
1286 | FROM {db_prefix}log_polls |
||
1287 | WHERE id_poll = {int:current_poll}', |
||
1288 | array( |
||
1289 | 'current_poll' => $row['id_poll'], |
||
1290 | ) |
||
1291 | ); |
||
1292 | list ($total) = $smcFunc['db_fetch_row']($request); |
||
1293 | $smcFunc['db_free_result']($request); |
||
1294 | |||
1295 | $request = $smcFunc['db_query']('', ' |
||
1296 | SELECT id_choice, label, votes |
||
1297 | FROM {db_prefix}poll_choices |
||
1298 | WHERE id_poll = {int:current_poll}', |
||
1299 | array( |
||
1300 | 'current_poll' => $row['id_poll'], |
||
1301 | ) |
||
1302 | ); |
||
1303 | $sOptions = array(); |
||
1304 | View Code Duplication | while ($rowChoice = $smcFunc['db_fetch_assoc']($request)) |
|
1305 | { |
||
1306 | censorText($rowChoice['label']); |
||
1307 | |||
1308 | $sOptions[$rowChoice['id_choice']] = array($rowChoice['label'], $rowChoice['votes']); |
||
1309 | } |
||
1310 | $smcFunc['db_free_result']($request); |
||
1311 | |||
1312 | // Can they view it? |
||
1313 | $is_expired = !empty($row['expire_time']) && $row['expire_time'] < time(); |
||
1314 | $allow_view_results = allowedTo('moderate_board') || $row['hide_results'] == 0 || $is_expired; |
||
1315 | |||
1316 | $return = array( |
||
1317 | 'id' => $row['id_poll'], |
||
1318 | 'image' => 'poll', |
||
1319 | 'question' => $row['question'], |
||
1320 | 'total_votes' => $total, |
||
1321 | 'is_locked' => false, |
||
1322 | 'topic' => $row['id_topic'], |
||
1323 | 'allow_view_results' => $allow_view_results, |
||
1324 | 'options' => array() |
||
1325 | ); |
||
1326 | |||
1327 | // Calculate the percentages and bar lengths... |
||
1328 | $divisor = $return['total_votes'] == 0 ? 1 : $return['total_votes']; |
||
1329 | foreach ($sOptions as $i => $option) |
||
1330 | { |
||
1331 | $bar = floor(($option[1] * 100) / $divisor); |
||
1332 | $return['options'][$i] = array( |
||
1333 | 'id' => 'options-' . ($topPollInstead ? 'top-' : 'recent-') . $i, |
||
1334 | 'percent' => $bar, |
||
1335 | 'votes' => $option[1], |
||
1336 | 'option' => parse_bbc($option[0]), |
||
1337 | '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') . '">' |
||
1338 | ); |
||
1339 | } |
||
1340 | |||
1341 | $return['allowed_warning'] = $row['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($sOptions), $row['max_votes'])) : ''; |
||
1342 | |||
1343 | // If mods want to do somthing with this list of polls, let them do that now. |
||
1344 | call_integration_hook('integrate_ssi_recentPoll', array(&$return, $topPollInstead)); |
||
1345 | |||
1346 | if ($output_method != 'echo') |
||
1347 | return $return; |
||
1348 | |||
1349 | if ($allow_view_results) |
||
1350 | { |
||
1351 | echo ' |
||
1352 | <form class="ssi_poll" action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '"> |
||
1353 | <strong>', $return['question'], '</strong><br> |
||
1354 | ', !empty($return['allowed_warning']) ? $return['allowed_warning'] . '<br>' : ''; |
||
1355 | |||
1356 | View Code Duplication | foreach ($return['options'] as $option) |
|
1357 | echo ' |
||
1358 | <label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label><br>'; |
||
1359 | |||
1360 | echo ' |
||
1361 | <input type="submit" value="', $txt['poll_vote'], '" class="button_submit"> |
||
1362 | <input type="hidden" name="poll" value="', $return['id'], '"> |
||
1363 | <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '"> |
||
1364 | </form>'; |
||
1365 | } |
||
1366 | else |
||
1367 | echo $txt['poll_cannot_see']; |
||
1368 | } |
||
1369 | |||
1370 | /** |
||
1371 | * Shows the poll from the specified topic |
||
1372 | * @param null|int $topic The topic to show the poll from. If null, $_REQUEST['ssi_topic'] will be used instead. |
||
1373 | * @param string $output_method The output method. If 'echo', displays the poll, otherwise returns an array of info about it. |
||
1374 | * @return void|array Either displays the poll or returns an array of info about it, depending on output_method. |
||
1375 | */ |
||
1376 | function ssi_showPoll($topic = null, $output_method = 'echo') |
||
1377 | { |
||
1378 | global $txt, $boardurl, $user_info, $context, $smcFunc, $modSettings; |
||
1379 | |||
1380 | $boardsAllowed = boardsAllowedTo('poll_view'); |
||
1381 | |||
1382 | if (empty($boardsAllowed)) |
||
1383 | return array(); |
||
1384 | |||
1385 | if ($topic === null && isset($_REQUEST['ssi_topic'])) |
||
1386 | $topic = (int) $_REQUEST['ssi_topic']; |
||
1387 | else |
||
1388 | $topic = (int) $topic; |
||
1389 | |||
1390 | $request = $smcFunc['db_query']('', ' |
||
1391 | SELECT |
||
1392 | p.id_poll, p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.guest_vote, b.id_board |
||
1393 | FROM {db_prefix}topics AS t |
||
1394 | INNER JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll) |
||
1395 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) |
||
1396 | WHERE t.id_topic = {int:current_topic} |
||
1397 | AND {query_see_board}' . (!in_array(0, $boardsAllowed) ? ' |
||
1398 | AND b.id_board IN ({array_int:boards_allowed_see})' : '') . ($modSettings['postmod_active'] ? ' |
||
1399 | AND t.approved = {int:is_approved}' : '') . ' |
||
1400 | LIMIT 1', |
||
1401 | array( |
||
1402 | 'current_topic' => $topic, |
||
1403 | 'boards_allowed_see' => $boardsAllowed, |
||
1404 | 'is_approved' => 1, |
||
1405 | ) |
||
1406 | ); |
||
1407 | |||
1408 | // Either this topic has no poll, or the user cannot view it. |
||
1409 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1410 | return array(); |
||
1411 | |||
1412 | $row = $smcFunc['db_fetch_assoc']($request); |
||
1413 | $smcFunc['db_free_result']($request); |
||
1414 | |||
1415 | // Check if they can vote. |
||
1416 | $already_voted = false; |
||
1417 | if (!empty($row['expire_time']) && $row['expire_time'] < time()) |
||
1418 | $allow_vote = false; |
||
1419 | elseif ($user_info['is_guest']) |
||
1420 | { |
||
1421 | // There's a difference between "allowed to vote" and "already voted"... |
||
1422 | $allow_vote = $row['guest_vote']; |
||
1423 | |||
1424 | // Did you already vote? |
||
1425 | if (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote']))) |
||
1426 | { |
||
1427 | $already_voted = true; |
||
1428 | } |
||
1429 | } |
||
1430 | elseif (!empty($row['voting_locked']) || !allowedTo('poll_vote', $row['id_board'])) |
||
1431 | $allow_vote = false; |
||
1432 | else |
||
1433 | { |
||
1434 | $request = $smcFunc['db_query']('', ' |
||
1435 | SELECT id_member |
||
1436 | FROM {db_prefix}log_polls |
||
1437 | WHERE id_poll = {int:current_poll} |
||
1438 | AND id_member = {int:current_member} |
||
1439 | LIMIT 1', |
||
1440 | array( |
||
1441 | 'current_member' => $user_info['id'], |
||
1442 | 'current_poll' => $row['id_poll'], |
||
1443 | ) |
||
1444 | ); |
||
1445 | $allow_vote = $smcFunc['db_num_rows']($request) == 0; |
||
1446 | $already_voted = $allow_vote; |
||
1447 | $smcFunc['db_free_result']($request); |
||
1448 | } |
||
1449 | |||
1450 | // Can they view? |
||
1451 | $is_expired = !empty($row['expire_time']) && $row['expire_time'] < time(); |
||
1452 | $allow_view_results = allowedTo('moderate_board') || $row['hide_results'] == 0 || ($row['hide_results'] == 1 && $already_voted) || $is_expired; |
||
1453 | |||
1454 | $request = $smcFunc['db_query']('', ' |
||
1455 | SELECT COUNT(DISTINCT id_member) |
||
1456 | FROM {db_prefix}log_polls |
||
1457 | WHERE id_poll = {int:current_poll}', |
||
1458 | array( |
||
1459 | 'current_poll' => $row['id_poll'], |
||
1460 | ) |
||
1461 | ); |
||
1462 | list ($total) = $smcFunc['db_fetch_row']($request); |
||
1463 | $smcFunc['db_free_result']($request); |
||
1464 | |||
1465 | $request = $smcFunc['db_query']('', ' |
||
1466 | SELECT id_choice, label, votes |
||
1467 | FROM {db_prefix}poll_choices |
||
1468 | WHERE id_poll = {int:current_poll}', |
||
1469 | array( |
||
1470 | 'current_poll' => $row['id_poll'], |
||
1471 | ) |
||
1472 | ); |
||
1473 | $sOptions = array(); |
||
1474 | $total_votes = 0; |
||
1475 | View Code Duplication | while ($rowChoice = $smcFunc['db_fetch_assoc']($request)) |
|
1476 | { |
||
1477 | censorText($rowChoice['label']); |
||
1478 | |||
1479 | $sOptions[$rowChoice['id_choice']] = array($rowChoice['label'], $rowChoice['votes']); |
||
1480 | $total_votes += $rowChoice['votes']; |
||
1481 | } |
||
1482 | $smcFunc['db_free_result']($request); |
||
1483 | |||
1484 | $return = array( |
||
1485 | 'id' => $row['id_poll'], |
||
1486 | 'image' => empty($row['voting_locked']) ? 'poll' : 'locked_poll', |
||
1487 | 'question' => $row['question'], |
||
1488 | 'total_votes' => $total, |
||
1489 | 'is_locked' => !empty($row['voting_locked']), |
||
1490 | 'allow_vote' => $allow_vote, |
||
1491 | 'allow_view_results' => $allow_view_results, |
||
1492 | 'topic' => $topic |
||
1493 | ); |
||
1494 | |||
1495 | // Calculate the percentages and bar lengths... |
||
1496 | $divisor = $total_votes == 0 ? 1 : $total_votes; |
||
1497 | foreach ($sOptions as $i => $option) |
||
1498 | { |
||
1499 | $bar = floor(($option[1] * 100) / $divisor); |
||
1500 | $return['options'][$i] = array( |
||
1501 | 'id' => 'options-' . $i, |
||
1502 | 'percent' => $bar, |
||
1503 | 'votes' => $option[1], |
||
1504 | 'option' => parse_bbc($option[0]), |
||
1505 | 'vote_button' => '<input type="' . ($row['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($row['max_votes'] > 1 ? 'check' : 'radio') . '">' |
||
1506 | ); |
||
1507 | } |
||
1508 | |||
1509 | $return['allowed_warning'] = $row['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($sOptions), $row['max_votes'])) : ''; |
||
1510 | |||
1511 | // If mods want to do somthing with this poll, let them do that now. |
||
1512 | call_integration_hook('integrate_ssi_showPoll', array(&$return)); |
||
1513 | |||
1514 | if ($output_method != 'echo') |
||
1515 | return $return; |
||
1516 | |||
1517 | if ($return['allow_vote']) |
||
1518 | { |
||
1519 | echo ' |
||
1520 | <form class="ssi_poll" action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '"> |
||
1521 | <strong>', $return['question'], '</strong><br> |
||
1522 | ', !empty($return['allowed_warning']) ? $return['allowed_warning'] . '<br>' : ''; |
||
1523 | |||
1524 | View Code Duplication | foreach ($return['options'] as $option) |
|
1525 | echo ' |
||
1526 | <label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label><br>'; |
||
1527 | |||
1528 | echo ' |
||
1529 | <input type="submit" value="', $txt['poll_vote'], '" class="button_submit"> |
||
1530 | <input type="hidden" name="poll" value="', $return['id'], '"> |
||
1531 | <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '"> |
||
1532 | </form>'; |
||
1533 | } |
||
1534 | else |
||
1535 | { |
||
1536 | echo ' |
||
1537 | <div class="ssi_poll"> |
||
1538 | <strong>', $return['question'], '</strong> |
||
1539 | <dl>'; |
||
1540 | |||
1541 | foreach ($return['options'] as $option) |
||
1542 | { |
||
1543 | echo ' |
||
1544 | <dt>', $option['option'], '</dt> |
||
1545 | <dd>'; |
||
1546 | |||
1547 | if ($return['allow_view_results']) |
||
1548 | { |
||
1549 | echo ' |
||
1550 | <div class="ssi_poll_bar" style="border: 1px solid #666; height: 1em"> |
||
1551 | <div class="ssi_poll_bar_fill" style="background: #ccf; height: 1em; width: ', $option['percent'], '%;"> |
||
1552 | </div> |
||
1553 | </div> |
||
1554 | ', $option['votes'], ' (', $option['percent'], '%)'; |
||
1555 | } |
||
1556 | |||
1557 | echo ' |
||
1558 | </dd>'; |
||
1559 | } |
||
1560 | |||
1561 | echo ' |
||
1562 | </dl>', ($return['allow_view_results'] ? ' |
||
1563 | <strong>'. $txt['poll_total_voters'] . ': ' . $return['total_votes'] . '</strong>' : ''), ' |
||
1564 | </div>'; |
||
1565 | } |
||
1566 | } |
||
1567 | |||
1568 | /** |
||
1569 | * Handles voting in a poll (done automatically) |
||
1570 | */ |
||
1571 | function ssi_pollVote() |
||
1572 | { |
||
1573 | global $context, $db_prefix, $user_info, $sc, $smcFunc, $sourcedir, $modSettings; |
||
1574 | |||
1575 | if (!isset($_POST[$context['session_var']]) || $_POST[$context['session_var']] != $sc || empty($_POST['options']) || !isset($_POST['poll'])) |
||
1576 | { |
||
1577 | echo '<!DOCTYPE html> |
||
1578 | <html> |
||
1579 | <head> |
||
1580 | <script> |
||
1581 | history.go(-1); |
||
1582 | </script> |
||
1583 | </head> |
||
1584 | <body>«</body> |
||
1585 | </html>'; |
||
1586 | return; |
||
1587 | } |
||
1588 | |||
1589 | // This can cause weird errors! (ie. copyright missing.) |
||
1590 | checkSession(); |
||
1591 | |||
1592 | $_POST['poll'] = (int) $_POST['poll']; |
||
1593 | |||
1594 | // Check if they have already voted, or voting is locked. |
||
1595 | $request = $smcFunc['db_query']('', ' |
||
1596 | SELECT |
||
1597 | p.id_poll, p.voting_locked, p.expire_time, p.max_votes, p.guest_vote, |
||
1598 | t.id_topic, |
||
1599 | IFNULL(lp.id_choice, -1) AS selected |
||
1600 | FROM {db_prefix}polls AS p |
||
1601 | INNER JOIN {db_prefix}topics AS t ON (t.id_poll = {int:current_poll}) |
||
1602 | INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) |
||
1603 | LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_poll = p.id_poll AND lp.id_member = {int:current_member}) |
||
1604 | WHERE p.id_poll = {int:current_poll} |
||
1605 | AND {query_see_board}' . ($modSettings['postmod_active'] ? ' |
||
1606 | AND t.approved = {int:is_approved}' : '') . ' |
||
1607 | LIMIT 1', |
||
1608 | array( |
||
1609 | 'current_member' => $user_info['id'], |
||
1610 | 'current_poll' => $_POST['poll'], |
||
1611 | 'is_approved' => 1, |
||
1612 | ) |
||
1613 | ); |
||
1614 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1615 | die; |
||
1616 | $row = $smcFunc['db_fetch_assoc']($request); |
||
1617 | $smcFunc['db_free_result']($request); |
||
1618 | |||
1619 | if (!empty($row['voting_locked']) || ($row['selected'] != -1 && !$user_info['is_guest']) || (!empty($row['expire_time']) && time() > $row['expire_time'])) |
||
1620 | redirectexit('topic=' . $row['id_topic'] . '.0'); |
||
1621 | |||
1622 | // Too many options checked? |
||
1623 | if (count($_REQUEST['options']) > $row['max_votes']) |
||
1624 | redirectexit('topic=' . $row['id_topic'] . '.0'); |
||
1625 | |||
1626 | // It's a guest who has already voted? |
||
1627 | if ($user_info['is_guest']) |
||
1628 | { |
||
1629 | // Guest voting disabled? |
||
1630 | if (!$row['guest_vote']) |
||
1631 | redirectexit('topic=' . $row['id_topic'] . '.0'); |
||
1632 | // Already voted? |
||
1633 | elseif (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote']))) |
||
1634 | redirectexit('topic=' . $row['id_topic'] . '.0'); |
||
1635 | } |
||
1636 | |||
1637 | $sOptions = array(); |
||
1638 | $inserts = array(); |
||
1639 | View Code Duplication | foreach ($_REQUEST['options'] as $id) |
|
1640 | { |
||
1641 | $id = (int) $id; |
||
1642 | |||
1643 | $sOptions[] = $id; |
||
1644 | $inserts[] = array($_POST['poll'], $user_info['id'], $id); |
||
1645 | } |
||
1646 | |||
1647 | // Add their vote in to the tally. |
||
1648 | $smcFunc['db_insert']('insert', |
||
1649 | $db_prefix . 'log_polls', |
||
1650 | array('id_poll' => 'int', 'id_member' => 'int', 'id_choice' => 'int'), |
||
1651 | $inserts, |
||
1652 | array('id_poll', 'id_member', 'id_choice') |
||
1653 | ); |
||
1654 | $smcFunc['db_query']('', ' |
||
1655 | UPDATE {db_prefix}poll_choices |
||
1656 | SET votes = votes + 1 |
||
1657 | WHERE id_poll = {int:current_poll} |
||
1658 | AND id_choice IN ({array_int:option_list})', |
||
1659 | array( |
||
1660 | 'option_list' => $sOptions, |
||
1661 | 'current_poll' => $_POST['poll'], |
||
1662 | ) |
||
1663 | ); |
||
1664 | |||
1665 | // Track the vote if a guest. |
||
1666 | if ($user_info['is_guest']) |
||
1667 | { |
||
1668 | $_COOKIE['guest_poll_vote'] = !empty($_COOKIE['guest_poll_vote']) ? ($_COOKIE['guest_poll_vote'] . ',' . $row['id_poll']) : $row['id_poll']; |
||
1669 | |||
1670 | require_once($sourcedir . '/Subs-Auth.php'); |
||
1671 | $cookie_url = url_parts(!empty($modSettings['localCookies']), !empty($modSettings['globalCookies'])); |
||
1672 | smf_setcookie('guest_poll_vote', $_COOKIE['guest_poll_vote'], time() + 2500000, $cookie_url[1], $cookie_url[0], false, false); |
||
1673 | } |
||
1674 | |||
1675 | redirectexit('topic=' . $row['id_topic'] . '.0'); |
||
1676 | } |
||
1677 | |||
1678 | // Show a search box. |
||
1679 | /** |
||
1680 | * Shows a search box |
||
1681 | * @param string $output_method The output method. If 'echo', displays a search box, otherwise returns the URL of the search page. |
||
1682 | * @return void|string Displays a search box or returns the URL to the search page depending on output_method. If you don't have permission to search, the function won't return anything. |
||
1683 | */ |
||
1684 | function ssi_quickSearch($output_method = 'echo') |
||
1685 | { |
||
1686 | global $scripturl, $txt, $context; |
||
1687 | |||
1688 | if (!allowedTo('search_posts')) |
||
1689 | return; |
||
1690 | |||
1691 | if ($output_method != 'echo') |
||
1692 | return $scripturl . '?action=search'; |
||
1693 | |||
1694 | echo ' |
||
1695 | <form action="', $scripturl, '?action=search2" method="post" accept-charset="', $context['character_set'], '"> |
||
1696 | <input type="hidden" name="advanced" value="0"><input type="text" name="ssi_search" size="30" class="input_text"> <input type="submit" value="', $txt['search'], '" class="button_submit"> |
||
1697 | </form>'; |
||
1698 | } |
||
1699 | |||
1700 | /** |
||
1701 | * Show a random forum news item |
||
1702 | * @param string $output_method The output method. If 'echo', shows the news item, otherwise returns it. |
||
1703 | * @return void|string Shows or returns a random forum news item, depending on output_method. |
||
1704 | */ |
||
1705 | function ssi_news($output_method = 'echo') |
||
1706 | { |
||
1707 | global $context; |
||
1708 | |||
1709 | $context['random_news_line'] = !empty($context['news_lines']) ? $context['news_lines'][mt_rand(0, count($context['news_lines']) - 1)] : ''; |
||
1710 | |||
1711 | // If mods want to do somthing with the news, let them do that now. Don't need to pass the news line itself, since it is already in $context. |
||
1712 | call_integration_hook('integrate_ssi_news'); |
||
1713 | |||
1714 | if ($output_method != 'echo') |
||
1715 | return $context['random_news_line']; |
||
1716 | |||
1717 | echo $context['random_news_line']; |
||
1718 | } |
||
1719 | |||
1720 | /** |
||
1721 | * Show today's birthdays. |
||
1722 | * @param string $output_method The output method. If 'echo', displays a list of users, otherwise returns an array of info about them. |
||
1723 | * @return void|array Displays a list of users or returns an array of info about them depending on output_method. |
||
1724 | */ |
||
1725 | function ssi_todaysBirthdays($output_method = 'echo') |
||
1726 | { |
||
1727 | global $scripturl, $modSettings, $user_info; |
||
1728 | |||
1729 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view') || !allowedTo('profile_view')) |
||
1730 | return; |
||
1731 | |||
1732 | $eventOptions = array( |
||
1733 | 'include_birthdays' => true, |
||
1734 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1735 | ); |
||
1736 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1737 | |||
1738 | // The ssi_todaysCalendar variants all use the same hook and just pass on $eventOptions so the hooked code can distinguish different cases if necessary |
||
1739 | call_integration_hook('integrate_ssi_calendar', array(&$return, $eventOptions)); |
||
1740 | |||
1741 | if ($output_method != 'echo') |
||
1742 | return $return['calendar_birthdays']; |
||
1743 | |||
1744 | foreach ($return['calendar_birthdays'] as $member) |
||
1745 | echo ' |
||
1746 | <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'] ? ', ' : ''); |
||
1747 | } |
||
1748 | |||
1749 | /** |
||
1750 | * Shows today's holidays. |
||
1751 | * @param string $output_method The output method. If 'echo', displays a list of holidays, otherwise returns an array of info about them. |
||
1752 | * @return void|array Displays a list of holidays or returns an array of info about them depending on output_method |
||
1753 | */ |
||
1754 | function ssi_todaysHolidays($output_method = 'echo') |
||
1755 | { |
||
1756 | global $modSettings, $user_info; |
||
1757 | |||
1758 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1759 | return; |
||
1760 | |||
1761 | $eventOptions = array( |
||
1762 | 'include_holidays' => true, |
||
1763 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1764 | ); |
||
1765 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1766 | |||
1767 | // The ssi_todaysCalendar variants all use the same hook and just pass on $eventOptions so the hooked code can distinguish different cases if necessary |
||
1768 | call_integration_hook('integrate_ssi_calendar', array(&$return, $eventOptions)); |
||
1769 | |||
1770 | if ($output_method != 'echo') |
||
1771 | return $return['calendar_holidays']; |
||
1772 | |||
1773 | echo ' |
||
1774 | ', implode(', ', $return['calendar_holidays']); |
||
1775 | } |
||
1776 | |||
1777 | /** |
||
1778 | * @param string $output_method The output method. If 'echo', displays a list of events, otherwise returns an array of info about them. |
||
1779 | * @return void|array Displays a list of events or returns an array of info about them depending on output_method |
||
1780 | */ |
||
1781 | function ssi_todaysEvents($output_method = 'echo') |
||
1782 | { |
||
1783 | global $modSettings, $user_info; |
||
1784 | |||
1785 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1786 | return; |
||
1787 | |||
1788 | $eventOptions = array( |
||
1789 | 'include_events' => true, |
||
1790 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1791 | ); |
||
1792 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1793 | |||
1794 | // The ssi_todaysCalendar variants all use the same hook and just pass on $eventOptions so the hooked code can distinguish different cases if necessary |
||
1795 | call_integration_hook('integrate_ssi_calendar', array(&$return, $eventOptions)); |
||
1796 | |||
1797 | if ($output_method != 'echo') |
||
1798 | return $return['calendar_events']; |
||
1799 | |||
1800 | View Code Duplication | foreach ($return['calendar_events'] as $event) |
|
1801 | { |
||
1802 | if ($event['can_edit']) |
||
1803 | echo ' |
||
1804 | <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> '; |
||
1805 | echo ' |
||
1806 | ' . $event['link'] . (!$event['is_last'] ? ', ' : ''); |
||
1807 | } |
||
1808 | } |
||
1809 | |||
1810 | /** |
||
1811 | * Shows today's calendar items (events, birthdays and holidays) |
||
1812 | * @param string $output_method The output method. If 'echo', displays a list of calendar items, otherwise returns an array of info about them. |
||
1813 | * @return void|array Displays a list of calendar items or returns an array of info about them depending on output_method |
||
1814 | */ |
||
1815 | function ssi_todaysCalendar($output_method = 'echo') |
||
1816 | { |
||
1817 | global $modSettings, $txt, $scripturl, $user_info; |
||
1818 | |||
1819 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
1820 | return; |
||
1821 | |||
1822 | $eventOptions = array( |
||
1823 | 'include_birthdays' => allowedTo('profile_view'), |
||
1824 | 'include_holidays' => true, |
||
1825 | 'include_events' => true, |
||
1826 | 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], |
||
1827 | ); |
||
1828 | $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions)); |
||
1829 | |||
1830 | // The ssi_todaysCalendar variants all use the same hook and just pass on $eventOptions so the hooked code can distinguish different cases if necessary |
||
1831 | call_integration_hook('integrate_ssi_calendar', array(&$return, $eventOptions)); |
||
1832 | |||
1833 | if ($output_method != 'echo') |
||
1834 | return $return; |
||
1835 | |||
1836 | if (!empty($return['calendar_holidays'])) |
||
1837 | echo ' |
||
1838 | <span class="holiday">' . $txt['calendar_prompt'] . ' ' . implode(', ', $return['calendar_holidays']) . '<br></span>'; |
||
1839 | if (!empty($return['calendar_birthdays'])) |
||
1840 | { |
||
1841 | echo ' |
||
1842 | <span class="birthday">' . $txt['birthdays_upcoming'] . '</span> '; |
||
1843 | View Code Duplication | foreach ($return['calendar_birthdays'] as $member) |
|
1844 | echo ' |
||
1845 | <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'] ? ', ' : ''; |
||
1846 | echo ' |
||
1847 | <br>'; |
||
1848 | } |
||
1849 | if (!empty($return['calendar_events'])) |
||
1850 | { |
||
1851 | echo ' |
||
1852 | <span class="event">' . $txt['events_upcoming'] . '</span> '; |
||
1853 | View Code Duplication | foreach ($return['calendar_events'] as $event) |
|
1854 | { |
||
1855 | if ($event['can_edit']) |
||
1856 | echo ' |
||
1857 | <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> '; |
||
1858 | echo ' |
||
1859 | ' . $event['link'] . (!$event['is_last'] ? ', ' : ''); |
||
1860 | } |
||
1861 | } |
||
1862 | } |
||
1863 | |||
1864 | /** |
||
1865 | * Show the latest news, with a template... by board. |
||
1866 | * @param null|int $board The ID of the board to get the info from. Defaults to $board or $_GET['board'] if not set. |
||
1867 | * @param null|int $limit How many items to show. Defaults to $_GET['limit'] or 5 if not set. |
||
1868 | * @param null|int $start Start with the specified item. Defaults to $_GET['start'] or 0 if not set. |
||
1869 | * @param null|int $length How many characters to show from each post. Defaults to $_GET['length'] or 0 (no limit) if not set. |
||
1870 | * @param string $output_method The output method. If 'echo', displays the news items, otherwise returns an array of info about them. |
||
1871 | * @return void|array Displays the news items or returns an array of info about them, depending on output_method. |
||
1872 | */ |
||
1873 | function ssi_boardNews($board = null, $limit = null, $start = null, $length = null, $output_method = 'echo') |
||
1874 | { |
||
1875 | global $scripturl, $txt, $settings, $modSettings, $context; |
||
1876 | global $smcFunc; |
||
1877 | |||
1878 | loadLanguage('Stats'); |
||
1879 | |||
1880 | // Must be integers.... |
||
1881 | if ($limit === null) |
||
1882 | $limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 5; |
||
1883 | else |
||
1884 | $limit = (int) $limit; |
||
1885 | |||
1886 | if ($start === null) |
||
1887 | $start = isset($_GET['start']) ? (int) $_GET['start'] : 0; |
||
1888 | else |
||
1889 | $start = (int) $start; |
||
1890 | |||
1891 | if ($board !== null) |
||
1892 | $board = (int) $board; |
||
1893 | elseif (isset($_GET['board'])) |
||
1894 | $board = (int) $_GET['board']; |
||
1895 | |||
1896 | if ($length === null) |
||
1897 | $length = isset($_GET['length']) ? (int) $_GET['length'] : 0; |
||
1898 | else |
||
1899 | $length = (int) $length; |
||
1900 | |||
1901 | $limit = max(0, $limit); |
||
1902 | $start = max(0, $start); |
||
1903 | |||
1904 | // Make sure guests can see this board. |
||
1905 | $request = $smcFunc['db_query']('', ' |
||
1906 | SELECT id_board |
||
1907 | FROM {db_prefix}boards |
||
1908 | WHERE ' . ($board === null ? '' : 'id_board = {int:current_board} |
||
1909 | AND ') . 'FIND_IN_SET(-1, member_groups) != 0 |
||
1910 | LIMIT 1', |
||
1911 | array( |
||
1912 | 'current_board' => $board, |
||
1913 | ) |
||
1914 | ); |
||
1915 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1916 | { |
||
1917 | if ($output_method == 'echo') |
||
1918 | die($txt['ssi_no_guests']); |
||
1919 | else |
||
1920 | return array(); |
||
1921 | } |
||
1922 | list ($board) = $smcFunc['db_fetch_row']($request); |
||
1923 | $smcFunc['db_free_result']($request); |
||
1924 | |||
1925 | $icon_sources = array(); |
||
1926 | foreach ($context['stable_icons'] as $icon) |
||
1927 | $icon_sources[$icon] = 'images_url'; |
||
1928 | |||
1929 | if (!empty($modSettings['enable_likes'])) |
||
1930 | { |
||
1931 | $context['can_like'] = allowedTo('likes_like'); |
||
1932 | $context['can_see_likes'] = allowedTo('likes_view'); |
||
1933 | } |
||
1934 | |||
1935 | // Find the post ids. |
||
1936 | $request = $smcFunc['db_query']('', ' |
||
1937 | SELECT t.id_first_msg |
||
1938 | FROM {db_prefix}topics as t |
||
1939 | LEFT JOIN {db_prefix}boards as b ON (b.id_board = t.id_board) |
||
1940 | WHERE t.id_board = {int:current_board}' . ($modSettings['postmod_active'] ? ' |
||
1941 | AND t.approved = {int:is_approved}' : '') . ' |
||
1942 | AND {query_see_board} |
||
1943 | ORDER BY t.id_first_msg DESC |
||
1944 | LIMIT ' . $start . ', ' . $limit, |
||
1945 | array( |
||
1946 | 'current_board' => $board, |
||
1947 | 'is_approved' => 1, |
||
1948 | ) |
||
1949 | ); |
||
1950 | $posts = array(); |
||
1951 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1952 | $posts[] = $row['id_first_msg']; |
||
1953 | $smcFunc['db_free_result']($request); |
||
1954 | |||
1955 | if (empty($posts)) |
||
1956 | return array(); |
||
1957 | |||
1958 | // Find the posts. |
||
1959 | $request = $smcFunc['db_query']('', ' |
||
1960 | SELECT |
||
1961 | m.icon, m.subject, m.body, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.likes, |
||
1962 | t.num_replies, t.id_topic, m.id_member, m.smileys_enabled, m.id_msg, t.locked, t.id_last_msg, m.id_board |
||
1963 | FROM {db_prefix}topics AS t |
||
1964 | INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) |
||
1965 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) |
||
1966 | WHERE t.id_first_msg IN ({array_int:post_list}) |
||
1967 | ORDER BY t.id_first_msg DESC |
||
1968 | LIMIT ' . count($posts), |
||
1969 | array( |
||
1970 | 'post_list' => $posts, |
||
1971 | ) |
||
1972 | ); |
||
1973 | $return = array(); |
||
1974 | $recycle_board = !empty($modSettings['recycle_enable']) && !empty($modSettings['recycle_board']) ? (int) $modSettings['recycle_board'] : 0; |
||
1975 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1976 | { |
||
1977 | // If we want to limit the length of the post. |
||
1978 | if (!empty($length) && $smcFunc['strlen']($row['body']) > $length) |
||
1979 | { |
||
1980 | $row['body'] = $smcFunc['substr']($row['body'], 0, $length); |
||
1981 | $cutoff = false; |
||
1982 | |||
1983 | $last_space = strrpos($row['body'], ' '); |
||
1984 | $last_open = strrpos($row['body'], '<'); |
||
1985 | $last_close = strrpos($row['body'], '>'); |
||
1986 | if (empty($last_space) || ($last_space == $last_open + 3 && (empty($last_close) || (!empty($last_close) && $last_close < $last_open))) || $last_space < $last_open || $last_open == $length - 6) |
||
1987 | $cutoff = $last_open; |
||
1988 | elseif (empty($last_close) || $last_close < $last_open) |
||
1989 | $cutoff = $last_space; |
||
1990 | |||
1991 | if ($cutoff !== false) |
||
1992 | $row['body'] = $smcFunc['substr']($row['body'], 0, $cutoff); |
||
1993 | $row['body'] .= '...'; |
||
1994 | } |
||
1995 | |||
1996 | $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']); |
||
1997 | |||
1998 | if (!empty($recycle_board) && $row['id_board'] == $recycle_board) |
||
1999 | $row['icon'] = 'recycled'; |
||
2000 | |||
2001 | // Check that this message icon is there... |
||
2002 | View Code Duplication | if (!empty($modSettings['messageIconChecks_enable']) && !isset($icon_sources[$row['icon']])) |
|
2003 | $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url'; |
||
2004 | |||
2005 | censorText($row['subject']); |
||
2006 | censorText($row['body']); |
||
2007 | |||
2008 | $return[] = array( |
||
2009 | 'id' => $row['id_topic'], |
||
2010 | 'message_id' => $row['id_msg'], |
||
2011 | 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.png" alt="' . $row['icon'] . '">', |
||
2012 | 'subject' => $row['subject'], |
||
2013 | 'time' => timeformat($row['poster_time']), |
||
2014 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
2015 | 'body' => $row['body'], |
||
2016 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0', |
||
2017 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['num_replies'] . ' ' . ($row['num_replies'] == 1 ? $txt['ssi_comment'] : $txt['ssi_comments']) . '</a>', |
||
2018 | 'replies' => $row['num_replies'], |
||
2019 | 'comment_href' => !empty($row['locked']) ? '' : $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'], |
||
2020 | '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>', |
||
2021 | 'new_comment' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . '">' . $txt['ssi_write_comment'] . '</a>', |
||
2022 | 'poster' => array( |
||
2023 | 'id' => $row['id_member'], |
||
2024 | 'name' => $row['poster_name'], |
||
2025 | 'href' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : '', |
||
2026 | 'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name'] |
||
2027 | ), |
||
2028 | 'locked' => !empty($row['locked']), |
||
2029 | 'is_last' => false, |
||
2030 | // Nasty ternary for likes not messing around the "is_last" check. |
||
2031 | 'likes' => !empty($modSettings['enable_likes']) ? array( |
||
2032 | 'count' => $row['likes'], |
||
2033 | 'you' => in_array($row['id_msg'], prepareLikesContext((int) $row['id_topic'])), |
||
2034 | 'can_like' => !$context['user']['is_guest'] && $row['id_member'] != $context['user']['id'] && !empty($context['can_like']), |
||
2035 | ) : array(), |
||
2036 | ); |
||
2037 | } |
||
2038 | $smcFunc['db_free_result']($request); |
||
2039 | |||
2040 | if (empty($return)) |
||
2041 | return $return; |
||
2042 | |||
2043 | $return[count($return) - 1]['is_last'] = true; |
||
2044 | |||
2045 | // If mods want to do somthing with this list of posts, let them do that now. |
||
2046 | call_integration_hook('integrate_ssi_boardNews', array(&$return)); |
||
2047 | |||
2048 | if ($output_method != 'echo') |
||
2049 | return $return; |
||
2050 | |||
2051 | foreach ($return as $news) |
||
2052 | { |
||
2053 | echo ' |
||
2054 | <div class="news_item"> |
||
2055 | <h3 class="news_header"> |
||
2056 | ', $news['icon'], ' |
||
2057 | <a href="', $news['href'], '">', $news['subject'], '</a> |
||
2058 | </h3> |
||
2059 | <div class="news_timestamp">', $news['time'], ' ', $txt['by'], ' ', $news['poster']['link'], '</div> |
||
2060 | <div class="news_body" style="padding: 2ex 0;">', $news['body'], '</div> |
||
2061 | ', $news['link'], $news['locked'] ? '' : ' | ' . $news['comment_link'], ''; |
||
2062 | |||
2063 | |||
2064 | // Is there any likes to show? |
||
2065 | if (!empty($modSettings['enable_likes'])) |
||
2066 | { |
||
2067 | echo ' |
||
2068 | <ul>'; |
||
2069 | |||
2070 | if (!empty($news['likes']['can_like'])) |
||
2071 | { |
||
2072 | echo ' |
||
2073 | <li class="like_button" id="msg_', $news['message_id'], '_likes"><a href="', $scripturl, '?action=likes;ltype=msg;sa=like;like=', $news['message_id'], ';', $context['session_var'], '=', $context['session_id'], '" class="msg_like"><span class="', $news['likes']['you'] ? 'unlike' : 'like', '"></span>', $news['likes']['you'] ? $txt['unlike'] : $txt['like'], '</a></li>'; |
||
2074 | } |
||
2075 | |||
2076 | View Code Duplication | if (!empty($news['likes']['count']) && !empty($context['can_see_likes'])) |
|
2077 | { |
||
2078 | $context['some_likes'] = true; |
||
2079 | $count = $news['likes']['count']; |
||
2080 | $base = 'likes_'; |
||
2081 | if ($news['likes']['you']) |
||
2082 | { |
||
2083 | $base = 'you_' . $base; |
||
2084 | $count--; |
||
2085 | } |
||
2086 | $base .= (isset($txt[$base . $count])) ? $count : 'n'; |
||
2087 | |||
2088 | echo ' |
||
2089 | <li class="like_count smalltext">', sprintf($txt[$base], $scripturl . '?action=likes;sa=view;ltype=msg;like=' . $news['message_id'] . ';' . $context['session_var'] . '=' . $context['session_id'], comma_format($count)), '</li>'; |
||
2090 | } |
||
2091 | |||
2092 | echo ' |
||
2093 | </ul>'; |
||
2094 | } |
||
2095 | |||
2096 | |||
2097 | // Close the main div. |
||
2098 | echo ' |
||
2099 | </div>'; |
||
2100 | |||
2101 | if (!$news['is_last']) |
||
2102 | echo ' |
||
2103 | <hr>'; |
||
2104 | } |
||
2105 | } |
||
2106 | |||
2107 | /** |
||
2108 | * Show the most recent events |
||
2109 | * @param int $max_events The maximum number of events to show |
||
2110 | * @param string $output_method The output method. If 'echo', displays the events, otherwise returns an array of info about them. |
||
2111 | * @return void|array Displays the events or returns an array of info about them, depending on output_method. |
||
2112 | */ |
||
2113 | function ssi_recentEvents($max_events = 7, $output_method = 'echo') |
||
2114 | { |
||
2115 | global $user_info, $scripturl, $modSettings, $txt, $context, $smcFunc; |
||
2116 | |||
2117 | if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view')) |
||
2118 | return; |
||
2119 | |||
2120 | // Find all events which are happening in the near future that the member can see. |
||
2121 | $request = $smcFunc['db_query']('', ' |
||
2122 | SELECT |
||
2123 | cal.id_event, cal.start_date, cal.end_date, cal.title, cal.id_member, cal.id_topic, |
||
2124 | cal.start_time, cal.end_time, cal.timezone, cal.location, |
||
2125 | cal.id_board, t.id_first_msg, t.approved |
||
2126 | FROM {db_prefix}calendar AS cal |
||
2127 | LEFT JOIN {db_prefix}boards AS b ON (b.id_board = cal.id_board) |
||
2128 | LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = cal.id_topic) |
||
2129 | WHERE cal.start_date <= {date:current_date} |
||
2130 | AND cal.end_date >= {date:current_date} |
||
2131 | AND (cal.id_board = {int:no_board} OR {query_wanna_see_board}) |
||
2132 | ORDER BY cal.start_date DESC |
||
2133 | LIMIT ' . $max_events, |
||
2134 | array( |
||
2135 | 'current_date' => strftime('%Y-%m-%d', forum_time(false)), |
||
2136 | 'no_board' => 0, |
||
2137 | ) |
||
2138 | ); |
||
2139 | $return = array(); |
||
2140 | $duplicates = array(); |
||
2141 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
2142 | { |
||
2143 | // 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. |
||
2144 | if (!empty($duplicates[$row['title'] . $row['id_topic']])) |
||
2145 | continue; |
||
2146 | |||
2147 | // Censor the title. |
||
2148 | censorText($row['title']); |
||
2149 | |||
2150 | if ($row['start_date'] < strftime('%Y-%m-%d', forum_time(false))) |
||
2151 | $date = strftime('%Y-%m-%d', forum_time(false)); |
||
2152 | else |
||
2153 | $date = $row['start_date']; |
||
2154 | |||
2155 | // If the topic it is attached to is not approved then don't link it. |
||
2156 | if (!empty($row['id_first_msg']) && !$row['approved']) |
||
2157 | $row['id_board'] = $row['id_topic'] = $row['id_first_msg'] = 0; |
||
2158 | |||
2159 | $allday = (empty($row['start_time']) || empty($row['end_time']) || empty($row['timezone']) || !in_array($row['timezone'], timezone_identifiers_list(DateTimeZone::ALL_WITH_BC))) ? true : false; |
||
2160 | |||
2161 | $return[$date][] = array( |
||
2162 | 'id' => $row['id_event'], |
||
2163 | 'title' => $row['title'], |
||
2164 | 'location' => $row['location'], |
||
2165 | 'can_edit' => allowedTo('calendar_edit_any') || ($row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own')), |
||
2166 | 'modify_href' => $scripturl . '?action=' . ($row['id_board'] == 0 ? 'calendar;sa=post;' : 'post;msg=' . $row['id_first_msg'] . ';topic=' . $row['id_topic'] . '.0;calendar;') . 'eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
||
2167 | 'href' => $row['id_board'] == 0 ? '' : $scripturl . '?topic=' . $row['id_topic'] . '.0', |
||
2168 | 'link' => $row['id_board'] == 0 ? $row['title'] : '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['title'] . '</a>', |
||
2169 | 'start_date' => $row['start_date'], |
||
2170 | 'end_date' => $row['end_date'], |
||
2171 | 'start_time' => !$allday ? $row['start_time'] : null, |
||
2172 | 'end_time' => !$allday ? $row['end_time'] : null, |
||
2173 | 'tz' => !$allday ? $row['timezone'] : null, |
||
2174 | 'allday' => $allday, |
||
2175 | 'is_last' => false |
||
2176 | ); |
||
2177 | |||
2178 | // Let's not show this one again, huh? |
||
2179 | $duplicates[$row['title'] . $row['id_topic']] = true; |
||
2180 | } |
||
2181 | $smcFunc['db_free_result']($request); |
||
2182 | |||
2183 | foreach ($return as $mday => $array) |
||
2184 | $return[$mday][count($array) - 1]['is_last'] = true; |
||
2185 | |||
2186 | // If mods want to do somthing with this list of events, let them do that now. |
||
2187 | call_integration_hook('integrate_ssi_recentEvents', array(&$return)); |
||
2188 | |||
2189 | if ($output_method != 'echo' || empty($return)) |
||
2190 | return $return; |
||
2191 | |||
2192 | // Well the output method is echo. |
||
2193 | echo ' |
||
2194 | <span class="event">' . $txt['events'] . '</span> '; |
||
2195 | foreach ($return as $mday => $array) |
||
2196 | foreach ($array as $event) |
||
2197 | { |
||
2198 | if ($event['can_edit']) |
||
2199 | echo ' |
||
2200 | <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> '; |
||
2201 | |||
2202 | echo ' |
||
2203 | ' . $event['link'] . (!$event['is_last'] ? ', ' : ''); |
||
2204 | } |
||
2205 | } |
||
2206 | |||
2207 | /** |
||
2208 | * Checks whether the specified password is correct for the specified user. |
||
2209 | * @param int|string $id The ID or username of a user |
||
2210 | * @param string $password The password to check |
||
2211 | * @param bool $is_username If true, treats $id as a username rather than a user ID |
||
2212 | * @return bool Whether or not the password is correct. |
||
2213 | */ |
||
2214 | function ssi_checkPassword($id = null, $password = null, $is_username = false) |
||
2215 | { |
||
2216 | global $smcFunc; |
||
2217 | |||
2218 | // If $id is null, this was most likely called from a query string and should do nothing. |
||
2219 | if ($id === null) |
||
2220 | return; |
||
2221 | |||
2222 | $request = $smcFunc['db_query']('', ' |
||
2223 | SELECT passwd, member_name, is_activated |
||
2224 | FROM {db_prefix}members |
||
2225 | WHERE ' . ($is_username ? 'member_name' : 'id_member') . ' = {string:id} |
||
2226 | LIMIT 1', |
||
2227 | array( |
||
2228 | 'id' => $id, |
||
2229 | ) |
||
2230 | ); |
||
2231 | list ($pass, $user, $active) = $smcFunc['db_fetch_row']($request); |
||
2232 | $smcFunc['db_free_result']($request); |
||
2233 | |||
2234 | return hash_verify_password($user, $password, $pass) && $active == 1; |
||
2235 | } |
||
2236 | |||
2237 | /** |
||
2238 | * Shows the most recent attachments that the user can see |
||
2239 | * @param int $num_attachments How many to show |
||
2240 | * @param array $attachment_ext Only shows attachments with the specified extensions ('jpg', 'gif', etc.) if set |
||
2241 | * @param string $output_method The output method. If 'echo', displays a table with links/info, otherwise returns an array with information about the attachments |
||
2242 | * @return void|array Displays a table of attachment info or returns an array containing info about the attachments, depending on output_method. |
||
2243 | */ |
||
2244 | function ssi_recentAttachments($num_attachments = 10, $attachment_ext = array(), $output_method = 'echo') |
||
2245 | { |
||
2246 | global $smcFunc, $modSettings, $scripturl, $txt, $settings; |
||
2247 | |||
2248 | // We want to make sure that we only get attachments for boards that we can see *if* any. |
||
2249 | $attachments_boards = boardsAllowedTo('view_attachments'); |
||
2250 | |||
2251 | // No boards? Adios amigo. |
||
2252 | if (empty($attachments_boards)) |
||
2253 | return array(); |
||
2254 | |||
2255 | // Is it an array? |
||
2256 | $attachment_ext = (array) $attachment_ext; |
||
2257 | |||
2258 | // Lets build the query. |
||
2259 | $request = $smcFunc['db_query']('', ' |
||
2260 | SELECT |
||
2261 | att.id_attach, att.id_msg, att.filename, IFNULL(att.size, 0) AS filesize, att.downloads, mem.id_member, |
||
2262 | IFNULL(mem.real_name, m.poster_name) AS poster_name, m.id_topic, m.subject, t.id_board, m.poster_time, |
||
2263 | 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') . ' |
||
2264 | FROM {db_prefix}attachments AS att |
||
2265 | INNER JOIN {db_prefix}messages AS m ON (m.id_msg = att.id_msg) |
||
2266 | INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) |
||
2267 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ' |
||
2268 | LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = att.id_thumb)') . ' |
||
2269 | WHERE att.attachment_type = 0' . ($attachments_boards === array(0) ? '' : ' |
||
2270 | AND m.id_board IN ({array_int:boards_can_see})') . (!empty($attachment_ext) ? ' |
||
2271 | AND att.fileext IN ({array_string:attachment_ext})' : '') . |
||
2272 | (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : ' |
||
2273 | AND t.approved = {int:is_approved} |
||
2274 | AND m.approved = {int:is_approved} |
||
2275 | AND att.approved = {int:is_approved}') . ' |
||
2276 | ORDER BY att.id_attach DESC |
||
2277 | LIMIT {int:num_attachments}', |
||
2278 | array( |
||
2279 | 'boards_can_see' => $attachments_boards, |
||
2280 | 'attachment_ext' => $attachment_ext, |
||
2281 | 'num_attachments' => $num_attachments, |
||
2282 | 'is_approved' => 1, |
||
2283 | ) |
||
2284 | ); |
||
2285 | |||
2286 | // We have something. |
||
2287 | $attachments = array(); |
||
2288 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
2289 | { |
||
2290 | $filename = preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename'])); |
||
2291 | |||
2292 | // Is it an image? |
||
2293 | $attachments[$row['id_attach']] = array( |
||
2294 | 'member' => array( |
||
2295 | 'id' => $row['id_member'], |
||
2296 | 'name' => $row['poster_name'], |
||
2297 | 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>', |
||
2298 | ), |
||
2299 | 'file' => array( |
||
2300 | 'filename' => $filename, |
||
2301 | 'filesize' => round($row['filesize'] / 1024, 2) . $txt['kilobyte'], |
||
2302 | 'downloads' => $row['downloads'], |
||
2303 | 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'], |
||
2304 | '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>', |
||
2305 | 'is_image' => !empty($row['width']) && !empty($row['height']) && !empty($modSettings['attachmentShowImages']), |
||
2306 | ), |
||
2307 | 'topic' => array( |
||
2308 | 'id' => $row['id_topic'], |
||
2309 | 'subject' => $row['subject'], |
||
2310 | 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], |
||
2311 | 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '">' . $row['subject'] . '</a>', |
||
2312 | 'time' => timeformat($row['poster_time']), |
||
2313 | ), |
||
2314 | ); |
||
2315 | |||
2316 | // Images. |
||
2317 | if ($attachments[$row['id_attach']]['file']['is_image']) |
||
2318 | { |
||
2319 | $id_thumb = empty($row['id_thumb']) ? $row['id_attach'] : $row['id_thumb']; |
||
2320 | $attachments[$row['id_attach']]['file']['image'] = array( |
||
2321 | 'id' => $id_thumb, |
||
2322 | 'width' => $row['width'], |
||
2323 | 'height' => $row['height'], |
||
2324 | 'img' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image" alt="' . $filename . '">', |
||
2325 | 'thumb' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '">', |
||
2326 | 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image', |
||
2327 | '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>', |
||
2328 | ); |
||
2329 | } |
||
2330 | } |
||
2331 | $smcFunc['db_free_result']($request); |
||
2332 | |||
2333 | // If mods want to do somthing with this list of attachments, let them do that now. |
||
2334 | call_integration_hook('integrate_ssi_recentAttachments', array(&$attachments)); |
||
2335 | |||
2336 | // So you just want an array? Here you can have it. |
||
2337 | if ($output_method == 'array' || empty($attachments)) |
||
2338 | return $attachments; |
||
2339 | |||
2340 | // Give them the default. |
||
2341 | echo ' |
||
2342 | <table class="ssi_downloads"> |
||
2343 | <tr> |
||
2344 | <th style="text-align: left; padding: 2">', $txt['file'], '</th> |
||
2345 | <th style="text-align: left; padding: 2">', $txt['posted_by'], '</th> |
||
2346 | <th style="text-align: left; padding: 2">', $txt['downloads'], '</th> |
||
2347 | <th style="text-align: left; padding: 2">', $txt['filesize'], '</th> |
||
2348 | </tr>'; |
||
2349 | foreach ($attachments as $attach) |
||
2350 | echo ' |
||
2351 | <tr> |
||
2352 | <td>', $attach['file']['link'], '</td> |
||
2353 | <td>', $attach['member']['link'], '</td> |
||
2354 | <td style="text-align: center">', $attach['file']['downloads'], '</td> |
||
2355 | <td>', $attach['file']['filesize'], '</td> |
||
2356 | </tr>'; |
||
2357 | echo ' |
||
2358 | </table>'; |
||
2359 | } |
||
2360 | |||
2361 | ?> |
If you suppress an error, we recommend checking for the error condition explicitly: