Subs-MembersOnline.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. /**
  3. * Simple Machines Forum (SMF)
  4. *
  5. * @package SMF
  6. * @author Simple Machines http://www.simplemachines.org
  7. * @copyright 2011 Simple Machines
  8. * @license http://www.simplemachines.org/about/smf/license.php BSD
  9. *
  10. * @version 2.1 Alpha 1
  11. */
  12. if (!defined('SMF'))
  13. die('Hacking attempt...');
  14. /* This file currently only holds the function for showing a list of online
  15. users used by the board index and SSI. In the future it'll also contain
  16. functions used by the Who's online page.
  17. array getMembersOnlineStats(array membersOnlineOptions)
  18. - retrieve a list and several other statistics of the users currently
  19. online on the forum.
  20. - used by the board index and SSI.
  21. - also returns the membergroups of the users that are currently online.
  22. - (optionally) hides members that chose to hide their online presense.
  23. */
  24. //
  25. /**
  26. * Retrieve a list and several other statistics of the users currently online.
  27. * - retrieve a list and several other statistics of the users currently
  28. * online on the forum.
  29. * - used by the board index and SSI.
  30. * - also returns the membergroups of the users that are currently online.
  31. * - (optionally) hides members that chose to hide their online presense.
  32. * @param array $membersOnlineOptions
  33. * @return array
  34. */
  35. function getMembersOnlineStats($membersOnlineOptions)
  36. {
  37. global $smcFunc, $context, $scripturl, $user_info, $modSettings, $txt;
  38. // The list can be sorted in several ways.
  39. $allowed_sort_options = array(
  40. '', // No sorting.
  41. 'log_time',
  42. 'real_name',
  43. 'show_online',
  44. 'online_color',
  45. 'group_name',
  46. );
  47. // Default the sorting method to 'most recent online members first'.
  48. if (!isset($membersOnlineOptions['sort']))
  49. {
  50. $membersOnlineOptions['sort'] = 'log_time';
  51. $membersOnlineOptions['reverse_sort'] = true;
  52. }
  53. // Not allowed sort method? Bang! Error!
  54. elseif (!in_array($membersOnlineOptions['sort'], $allowed_sort_options))
  55. trigger_error('Sort method for getMembersOnlineStats() function is not allowed', E_USER_NOTICE);
  56. // Get it from the cache and send it back.
  57. if (($temp = cache_get_data('membersOnlineStats-' . $membersOnlineOptions['sort'], 240)) !== null)
  58. return $temp;
  59. // Initialize the array that'll be returned later on.
  60. $membersOnlineStats = array(
  61. 'users_online' => array(),
  62. 'list_users_online' => array(),
  63. 'online_groups' => array(),
  64. 'num_guests' => 0,
  65. 'num_spiders' => 0,
  66. 'num_buddies' => 0,
  67. 'num_users_hidden' => 0,
  68. 'num_users_online' => 0,
  69. );
  70. // Get any spiders if enabled.
  71. $spiders = array();
  72. $spider_finds = array();
  73. if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] < 3 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache']))
  74. $spiders = unserialize($modSettings['spider_name_cache']);
  75. // Load the users online right now.
  76. $request = $smcFunc['db_query']('', '
  77. SELECT
  78. lo.id_member, lo.log_time, lo.id_spider, mem.real_name, mem.member_name, mem.show_online,
  79. mg.online_color, mg.id_group, mg.group_name
  80. FROM {db_prefix}log_online AS lo
  81. LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
  82. LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_mem_group} THEN mem.id_post_group ELSE mem.id_group END)',
  83. array(
  84. 'reg_mem_group' => 0,
  85. )
  86. );
  87. while ($row = $smcFunc['db_fetch_assoc']($request))
  88. {
  89. if (empty($row['real_name']))
  90. {
  91. // Do we think it's a spider?
  92. if ($row['id_spider'] && isset($spiders[$row['id_spider']]))
  93. {
  94. $spider_finds[$row['id_spider']] = isset($spider_finds[$row['id_spider']]) ? $spider_finds[$row['id_spider']] + 1 : 1;
  95. $membersOnlineStats['num_spiders']++;
  96. }
  97. // Guests are only nice for statistics.
  98. $membersOnlineStats['num_guests']++;
  99. continue;
  100. }
  101. elseif (empty($row['show_online']) && empty($membersOnlineOptions['show_hidden']))
  102. {
  103. // Just increase the stats and don't add this hidden user to any list.
  104. $membersOnlineStats['num_users_hidden']++;
  105. continue;
  106. }
  107. // Some basic color coding...
  108. if (!empty($row['online_color']))
  109. $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
  110. else
  111. $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
  112. // Buddies get counted and highlighted.
  113. $is_buddy = in_array($row['id_member'], $user_info['buddies']);
  114. if ($is_buddy)
  115. {
  116. $membersOnlineStats['num_buddies']++;
  117. $link = '<strong>' . $link . '</strong>';
  118. }
  119. // A lot of useful information for each member.
  120. $membersOnlineStats['users_online'][$row[$membersOnlineOptions['sort']] . $row['member_name']] = array(
  121. 'id' => $row['id_member'],
  122. 'username' => $row['member_name'],
  123. 'name' => $row['real_name'],
  124. 'group' => $row['id_group'],
  125. 'href' => $scripturl . '?action=profile;u=' . $row['id_member'],
  126. 'link' => $link,
  127. 'is_buddy' => $is_buddy,
  128. 'hidden' => empty($row['show_online']),
  129. 'is_last' => false,
  130. );
  131. // This is the compact version, simply implode it to show.
  132. $membersOnlineStats['list_users_online'][$row[$membersOnlineOptions['sort']] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
  133. // Store all distinct (primary) membergroups that are shown.
  134. if (!isset($membersOnlineStats['online_groups'][$row['id_group']]))
  135. $membersOnlineStats['online_groups'][$row['id_group']] = array(
  136. 'id' => $row['id_group'],
  137. 'name' => $row['group_name'],
  138. 'color' => $row['online_color']
  139. );
  140. }
  141. $smcFunc['db_free_result']($request);
  142. // If there are spiders only and we're showing the detail, add them to the online list - at the bottom.
  143. if (!empty($spider_finds) && $modSettings['show_spider_online'] > 1)
  144. {
  145. $sort = $membersOnlineOptions['sort'] === 'log_time' && $membersOnlineOptions['reverse_sort'] ? 0 : 'zzz_';
  146. foreach ($spider_finds as $id => $count)
  147. {
  148. $link = $spiders[$id] . ($count > 1 ? ' (' . $count . ')' : '');
  149. $membersOnlineStats['users_online'][$sort . $spiders[$id]] = array(
  150. 'id' => 0,
  151. 'username' => $spiders[$id],
  152. 'name' => $link,
  153. 'group' => $txt['spiders'],
  154. 'href' => '',
  155. 'link' => $link,
  156. 'is_buddy' => false,
  157. 'hidden' => false,
  158. 'is_last' => false,
  159. );
  160. $membersOnlineStats['list_users_online'][$sort . $spiders[$id]] = $link;
  161. }
  162. }
  163. // Time to sort the list a bit.
  164. if (!empty($membersOnlineStats['users_online']))
  165. {
  166. // Determine the sort direction.
  167. $sortFunction = empty($membersOnlineOptions['reverse_sort']) ? 'ksort' : 'krsort';
  168. // Sort the two lists.
  169. $sortFunction($membersOnlineStats['users_online']);
  170. $sortFunction($membersOnlineStats['list_users_online']);
  171. // Mark the last list item as 'is_last'.
  172. $userKeys = array_keys($membersOnlineStats['users_online']);
  173. $membersOnlineStats['users_online'][end($userKeys)]['is_last'] = true;
  174. }
  175. // Also sort the membergroups.
  176. ksort($membersOnlineStats['online_groups']);
  177. // Hidden and non-hidden members make up all online members.
  178. $membersOnlineStats['num_users_online'] = count($membersOnlineStats['users_online']) + $membersOnlineStats['num_users_hidden'] - (isset($modSettings['show_spider_online']) && $modSettings['show_spider_online'] > 1 ? count($spider_finds) : 0);
  179. cache_put_data('membersOnlineStats-' . $membersOnlineOptions['sort'], $membersOnlineStats, 240);
  180. return $membersOnlineStats;
  181. }
  182. /**
  183. * Check if the number of users online is a record and store it.
  184. * @param int $total_users_online
  185. */
  186. function trackStatsUsersOnline($total_users_online)
  187. {
  188. global $modSettings, $smcFunc;
  189. $settingsToUpdate = array();
  190. // More members on now than ever were? Update it!
  191. if (!isset($modSettings['mostOnline']) || $total_users_online >= $modSettings['mostOnline'])
  192. $settingsToUpdate = array(
  193. 'mostOnline' => $total_users_online,
  194. 'mostDate' => time()
  195. );
  196. $date = strftime('%Y-%m-%d', forum_time(false));
  197. // No entry exists for today yet?
  198. if (!isset($modSettings['mostOnlineUpdated']) || $modSettings['mostOnlineUpdated'] != $date)
  199. {
  200. $request = $smcFunc['db_query']('', '
  201. SELECT most_on
  202. FROM {db_prefix}log_activity
  203. WHERE date = {date:date}
  204. LIMIT 1',
  205. array(
  206. 'date' => $date,
  207. )
  208. );
  209. // The log_activity hasn't got an entry for today?
  210. if ($smcFunc['db_num_rows']($request) === 0)
  211. {
  212. $smcFunc['db_insert']('ignore',
  213. '{db_prefix}log_activity',
  214. array('date' => 'date', 'most_on' => 'int'),
  215. array($date, $total_users_online),
  216. array('date')
  217. );
  218. }
  219. // There's an entry in log_activity on today...
  220. else
  221. {
  222. list ($modSettings['mostOnlineToday']) = $smcFunc['db_fetch_row']($request);
  223. if ($total_users_online > $modSettings['mostOnlineToday'])
  224. trackStats(array('most_on' => $total_users_online));
  225. $total_users_online = max($total_users_online, $modSettings['mostOnlineToday']);
  226. }
  227. $smcFunc['db_free_result']($request);
  228. $settingsToUpdate['mostOnlineUpdated'] = $date;
  229. $settingsToUpdate['mostOnlineToday'] = $total_users_online;
  230. }
  231. // Highest number of users online today?
  232. elseif ($total_users_online > $modSettings['mostOnlineToday'])
  233. {
  234. trackStats(array('most_on' => $total_users_online));
  235. $settingsToUpdate['mostOnlineToday'] = $total_users_online;
  236. }
  237. if (!empty($settingsToUpdate))
  238. updateSettings($settingsToUpdate);
  239. }
  240. ?>