MyBB Community Forums

Full Version: How to get updated clock & who's online
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
What You will get is the current time updating every second (this also includes the date) and the users online updating at a rate set by the mybb setting settings->who'sonline->cut off time. personally I would change the cutoff time to something less than the default 15 minutes.

first thing to do is alter a couple of language strings in global.lang.php

1) welcome_current_time

from 
<strong>Current time:</strong> {1}

to

<strong>Current time:</strong> <span id="clock"></span>

2) welcome_back

from

<strong>Welcome back, {1}</strong>. You last visited: {2}


to

<strong>Welcome back, {1}</strong>. You last visited: <span id="lastvisit">{2}</span>

now a template edit find the template index_whosonline
and find the line 
<td class="trow1"><span class="smalltext">{$lang->online_note}<br />{$onlinemembers}</span></td>

and change it to
<td class="trow1" id="wol"><span class="smalltext">{$lang->online_note}<br />{$onlinemembers}</span></td>

all that's happend with these edits is id's have been added to elements so at this point nothing at all will change.
next create a new file call it scripts.js and place the following in it
jQuery(document).ready(function(){
   
    updateClock();
    wol();
    lastvisit();
    
   
});
 
  
function updateClock ()
    {
    var currentTime = new Date ( );
    var currentHours = currentTime.getHours ( );
    var currentMinutes = currentTime.getMinutes ( );
    var currentSeconds = currentTime.getSeconds ( );
    var d = new Date();
    var n = d.toLocaleDateString(); 
    // Pad the minutes and seconds with leading zeros, if required
    currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;
    currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;
 
    // Choose either "AM" or "PM" as appropriate
    var timeOfDay = ( currentHours < 12 ) ? "AM" : "PM";
 
    // Convert the hours component to 12-hour format if needed
    currentHours = ( currentHours > 12 ) ? currentHours - 12 : currentHours;
 
    // Convert an hours component of "0" to "12"
    currentHours = ( currentHours == 0 ) ? 12 : currentHours;
 
    // Compose the string for display
    var currentTimeString = n+", "+currentHours + ":" + currentMinutes + ":" + currentSeconds + " " + timeOfDay;
     
     
    $("#clock").html(currentTimeString);
   setInterval('updateClock()', 1000);
         
 }

function wol()
	{
		
		$.ajax({
 url: 'ajax.php?action=wol',
  type: 'post',
  success: function(data){
   // Perform operation on return value
   
   $("#wol").html(data);
  },
  complete:function(data){
   setTimeout(wol,3000); // check every 3 seconds 
  
  }
 });
}
function lastvisit ()
	{
		$.ajax({
 url: 'ajax.php?action=lastvisit',
  type: 'post',
  success: function(data){
   // Perform operation on return value
   
   $("#lastvisit").html(data);
   
  },
  complete:function(data){
   setTimeout(lastvisit,30000); // check every 30 seconds 
  
  }
 });
}

and save it to the jscripts folder

edit the headerinclude template then add the following line
<script type="text/javascript" src="{$mybb->asset_url}/jscripts/scripts.js"></script>

but make sure this is placed after jquery has been loaded.
last thing to do is to create a php file for the jquery code to interact with call it ajax.php and paste the following :-
<?php
define('IN_MYBB', 1);
require_once './global.php';
require_once MYBB_ROOT.'inc/functions_forumlist.php';
require_once MYBB_ROOT.'inc/class_parser.php';
$parser = new postParser;
$lang->load('index');

switch ($_GET['action']) {
	case 'wol':
		echo wol();
		break;
	case 'lastvisit':
		echo $lastvisit;
		break;
	}
function wol(){
	global $mybb,$db,$cache,$lang,$templates;
$whosonline = '';
if($mybb->settings['showwol'] != 0 && $mybb->usergroup['canviewonline'] != 0)
{
	// Get the online users.
	if($mybb->settings['wolorder'] == 'username')
	{
		$order_by = 'u.username ASC';
		$order_by2 = 's.time DESC';
	}
	else
	{
		$order_by = 's.time DESC';
		$order_by2 = 'u.username ASC';
	}

	$timesearch = TIME_NOW - (int)$mybb->settings['wolcutoff'];

	$membercount = $guestcount = $anoncount = $botcount = 0;
	$forum_viewers = $doneusers = $onlinemembers = $onlinebots = array();

	if($mybb->settings['showforumviewing'] != 0)
	{
		$query = $db->query("
			SELECT
				location1, COUNT(DISTINCT ip) AS guestcount
			FROM
				".TABLE_PREFIX."sessions
			WHERE uid = 0 AND location1 != 0 AND SUBSTR(sid,4,1) != '=' AND time > $timesearch
			GROUP BY location1
		");

		while($location = $db->fetch_array($query))
		{
			$forum_viewers[$location['location1']] += $location['guestcount'];
		}
	}

	$query = $db->simple_select("sessions", "COUNT(DISTINCT ip) AS guestcount", "uid = 0 AND SUBSTR(sid,4,1) != '=' AND time > $timesearch");
	$guestcount = $db->fetch_field($query, "guestcount");

	$query = $db->query("
		SELECT
			s.sid, s.ip, s.uid, s.time, s.location, s.location1, u.username, u.invisible, u.usergroup, u.displaygroup
		FROM
			".TABLE_PREFIX."sessions s
			LEFT JOIN ".TABLE_PREFIX."users u ON (s.uid=u.uid)
		WHERE (s.uid != 0 OR SUBSTR(s.sid,4,1) = '=') AND s.time > $timesearch
		ORDER BY {$order_by}, {$order_by2}
	");

	// Fetch spiders
	$spiders = $cache->read('spiders');

	// Loop through all users and spiders.
	while($user = $db->fetch_array($query))
	{
		// Create a key to test if this user is a search bot.
		$botkey = my_strtolower(str_replace('bot=', '', $user['sid']));

		// Decide what type of user we are dealing with.
		if($user['uid'] > 0)
		{
			// The user is registered.
			if(empty($doneusers[$user['uid']]) || $doneusers[$user['uid']] < $user['time'])
			{
				// If the user is logged in anonymously, update the count for that.
				if($user['invisible'] == 1)
				{
					++$anoncount;
				}
				++$membercount;
				if($user['invisible'] != 1 || $mybb->usergroup['canviewwolinvis'] == 1 || $user['uid'] == $mybb->user['uid'])
				{
					// If this usergroup can see anonymously logged-in users, mark them.
					if($user['invisible'] == 1)
					{
						$invisiblemark = '*';
					}
					else
					{
						$invisiblemark = '';
					}

					// Properly format the username and assign the template.
					$user['username'] = format_name(htmlspecialchars_uni($user['username']), $user['usergroup'], $user['displaygroup']);
					$user['profilelink'] = build_profile_link($user['username'], $user['uid']);
					eval('$onlinemembers[] = "'.$templates->get('index_whosonline_memberbit', 1, 0).'";');
				}
				// This user has been handled.
				$doneusers[$user['uid']] = $user['time'];
			}
		}
		elseif(my_strpos($user['sid'], 'bot=') !== false && $spiders[$botkey])
		{
			if($mybb->settings['wolorder'] == 'username')
			{
				$key = $spiders[$botkey]['name'];
			}
			else
			{
				$key = $user['time'];
			}

			// The user is a search bot.
			$onlinebots[$key] = format_name($spiders[$botkey]['name'], $spiders[$botkey]['usergroup']);
			++$botcount;
		}

		if($user['location1'])
		{
			++$forum_viewers[$user['location1']];
		}
	}

	if($mybb->settings['wolorder'] == 'activity')
	{
		// activity ordering is DESC, username is ASC
		krsort($onlinebots);
	}
	else
	{
		ksort($onlinebots);
	}

	$onlinemembers = array_merge($onlinebots, $onlinemembers);
	if(!empty($onlinemembers))
	{
		$comma = $lang->comma." ";
		$onlinemembers = implode($comma, $onlinemembers);
	}
	else
	{
		$onlinemembers = "";
	}

	// Build the who's online bit on the index page.
	$onlinecount = $membercount + $guestcount + $botcount;

	if($onlinecount != 1)
	{
		$onlinebit = $lang->online_online_plural;
	}
	else
	{
		$onlinebit = $lang->online_online_singular;
	}
	if($membercount != 1)
	{
		$memberbit = $lang->online_member_plural;
	}
	else
	{
		$memberbit = $lang->online_member_singular;
	}
	if($anoncount != 1)
	{
		$anonbit = $lang->online_anon_plural;
	}
	else
	{
		$anonbit = $lang->online_anon_singular;
	}
	if($guestcount != 1)
	{
		$guestbit = $lang->online_guest_plural;
	}
	else
	{
		$guestbit = $lang->online_guest_singular;
	}
	
	$lang->online_note = $lang->sprintf($lang->online_note, my_number_format($onlinecount), $onlinebit, $mybb->settings['wolcutoffmins'], my_number_format($membercount), $memberbit, my_number_format($anoncount), $anonbit, my_number_format($guestcount), $guestbit);
	
	return $lang->online_note.'<br>'.$onlinemembers;
}
}
?>

now save ajax.php in your forum root directory 
sorry there is so much PHP code but I couldn't find a function in mybb to return the data I needed.
Any questions just ask
Thanks for your contribution.

As a suggestion, I would remove the load of global.php and only load the necessary data, you could take a look at what the xmlhttp.php file loads. To remove even more work I would probably hook at xmlhttp to avoid a new file altogether (using something like the Hooks plugin).
This code is a snippet from a larger file that requires a lot of data from mybb, so that is why global.php is loaded. With this alteration I don't need a json encoded response so I don't think xmlhttp.php will give any advantage.
To be fair I don't use mybb as forum software so anything forum related gains little to no advantage in the use I am putting mybb to. just thought I would add this as people using mybb as forum software may want to use this bit of functionality.
The variable $lastvisit is defined in global.php at around line 489 is it defined else where ?
There does not appear to be a function to return wol data that I can find in the mybb source I would have thought there would have been something in inc/functions_online.php to do this, but the only code I can find is in index.php which I have turned into a function for my uses. but if there is a pre built function for this can you tell where it is located ?
Quote:I don't think xmlhttp.php will give any advantage

The advantage is that you won't be loading the full global.php script which might be desirable to save resources in any kind of setup.

You can change ajax.php to xmlhttp.php in your JavaScript.

Then add a new hook via a plugin or the Hooks plugin to xmlhttp.
	global $mybb, $db, $cache, $templates, $lang;

	switch($mybb->get_input('action'))
	{
		case 'lastvisit';
			if(isset($mybb->user['lastvisit']))
			{
				echo my_date('relative', $mybb->user['lastvisit'], '', 2);
			}
			else
			{
				echo $lang->lastvisit_never;
			}

			exit;

			break;
		case 'wol';
			$lang->load('index');

			if($mybb->settings['showwol'] != 0 && $mybb->usergroup['canviewonline'] != 0)
			{
				// Get the online users.
				if($mybb->settings['wolorder'] == 'username')
				{
					$order_by = 'u.username ASC';
					$order_by2 = 's.time DESC';
				}
				else
				{
					$order_by = 's.time DESC';
					$order_by2 = 'u.username ASC';
				}
			
				$timesearch = TIME_NOW - (int)$mybb->settings['wolcutoff'];
			
				$membercount = $guestcount = $anoncount = $botcount = 0;
				$forum_viewers = $doneusers = $onlinemembers = $onlinebots = array();
			
				if($mybb->settings['showforumviewing'] != 0)
				{
					$query = $db->query("
						SELECT
							location1, COUNT(DISTINCT ip) AS guestcount
						FROM
							".TABLE_PREFIX."sessions
						WHERE uid = 0 AND location1 != 0 AND SUBSTR(sid,4,1) != '=' AND time > $timesearch
						GROUP BY location1
					");
			
					while($location = $db->fetch_array($query))
					{
						$forum_viewers[$location['location1']] += $location['guestcount'];
					}
				}
			
				$query = $db->simple_select("sessions", "COUNT(DISTINCT ip) AS guestcount", "uid = 0 AND SUBSTR(sid,4,1) != '=' AND time > $timesearch");
				$guestcount = $db->fetch_field($query, "guestcount");
			
				$query = $db->query("
					SELECT
						s.sid, s.ip, s.uid, s.time, s.location, s.location1, u.username, u.invisible, u.usergroup, u.displaygroup
					FROM
						".TABLE_PREFIX."sessions s
						LEFT JOIN ".TABLE_PREFIX."users u ON (s.uid=u.uid)
					WHERE (s.uid != 0 OR SUBSTR(s.sid,4,1) = '=') AND s.time > $timesearch
					ORDER BY {$order_by}, {$order_by2}
				");
			
				// Fetch spiders
				$spiders = $cache->read('spiders');
			
				// Loop through all users and spiders.
				while($user = $db->fetch_array($query))
				{
					// Create a key to test if this user is a search bot.
					$botkey = my_strtolower(str_replace('bot=', '', $user['sid']));
			
					// Decide what type of user we are dealing with.
					if($user['uid'] > 0)
					{
						// The user is registered.
						if(empty($doneusers[$user['uid']]) || $doneusers[$user['uid']] < $user['time'])
						{
							// If the user is logged in anonymously, update the count for that.
							if($user['invisible'] == 1)
							{
								++$anoncount;
							}
							++$membercount;
							if($user['invisible'] != 1 || $mybb->usergroup['canviewwolinvis'] == 1 || $user['uid'] == $mybb->user['uid'])
							{
								// If this usergroup can see anonymously logged-in users, mark them.
								if($user['invisible'] == 1)
								{
									$invisiblemark = '*';
								}
								else
								{
									$invisiblemark = '';
								}
			
								// Properly format the username and assign the template.
								$user['username'] = format_name(htmlspecialchars_uni($user['username']), $user['usergroup'], $user['displaygroup']);
								$user['profilelink'] = build_profile_link($user['username'], $user['uid']);
								eval('$onlinemembers[] = "'.$templates->get('index_whosonline_memberbit', 1, 0).'";');
							}
							// This user has been handled.
							$doneusers[$user['uid']] = $user['time'];
						}
					}
					elseif(my_strpos($user['sid'], 'bot=') !== false && $spiders[$botkey])
					{
						if($mybb->settings['wolorder'] == 'username')
						{
							$key = $spiders[$botkey]['name'];
						}
						else
						{
							$key = $user['time'];
						}
			
						// The user is a search bot.
						$onlinebots[$key] = format_name($spiders[$botkey]['name'], $spiders[$botkey]['usergroup']);
						++$botcount;
					}
			
					if($user['location1'])
					{
						++$forum_viewers[$user['location1']];
					}
				}
			
				if($mybb->settings['wolorder'] == 'activity')
				{
					// activity ordering is DESC, username is ASC
					krsort($onlinebots);
				}
				else
				{
					ksort($onlinebots);
				}
			
				$onlinemembers = array_merge($onlinebots, $onlinemembers);
				if(!empty($onlinemembers))
				{
					$comma = $lang->comma." ";
					$onlinemembers = implode($comma, $onlinemembers);
				}
				else
				{
					$onlinemembers = "";
				}
			
				// Build the who's online bit on the index page.
				$onlinecount = $membercount + $guestcount + $botcount;
			
				if($onlinecount != 1)
				{
					$onlinebit = $lang->online_online_plural;
				}
				else
				{
					$onlinebit = $lang->online_online_singular;
				}
				if($membercount != 1)
				{
					$memberbit = $lang->online_member_plural;
				}
				else
				{
					$memberbit = $lang->online_member_singular;
				}
				if($anoncount != 1)
				{
					$anonbit = $lang->online_anon_plural;
				}
				else
				{
					$anonbit = $lang->online_anon_singular;
				}
				if($guestcount != 1)
				{
					$guestbit = $lang->online_guest_plural;
				}
				else
				{
					$guestbit = $lang->online_guest_singular;
				}
				$lang->online_note = $lang->sprintf($lang->online_note, my_number_format($onlinecount), $onlinebit, $mybb->settings['wolcutoffmins'], my_number_format($membercount), $memberbit, my_number_format($anoncount), $anonbit, my_number_format($guestcount), $guestbit);

				echo "<span class=\"smalltext\">{$lang->online_note}<br />{$onlinemembers}</span>";
			}

			exit;

			break;
	}

Which is pretty much the same code as yours.
Ok I have turned it into a sort of plugin and it works but the results are a bit different ...
  • ajax.php (original code always returns the user online, I guess this to be because global.php is writing the session data including the ajax call that my jquery is making.
  • xmlhttp.php does not write any session data so therefore after cutoff time the board returns 0 users online. On reflection this is correct as the board says 'active users' and not connected users.
  • I have never written a plugin before, all code I have done has been in add on php files and to be fair the documentation is a little sparse on the correct methods to use.
example being the returns from the is_installed

function myplugin_is_installed()
{
	global $mybb;
	$file = 'myplugin.txt';
	if (file_exists ( 'myplugin.txt') === true){
		
		return true;
			
	}
else {
	$file =  $mybb->asset_url.'/scripts.js';
	flash_message("file missing ".$file, '');
        return false;  

}

}

   does mybb take any action if false is returned ?