PageRenderTime 43ms CodeModel.GetById 6ms RepoModel.GetById 1ms app.codeStats 0ms

/sources/subs/MembersOnline.subs.php

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