Pages

Saturday, January 14, 2012

Online Users block (Part I) - How to be invisible on the Online Users block. A Moodle 1.9.x and 2.x solution

Learning Outcome: at the end of this post, you will know how to allow your Moodle 1.9.x and 2.x users to hide themselves on the Online Users block. This is Part I out of two parts. You can read Part II here.

Now I don't know about you, but I like, no, LOVE, the Online Users block by Andy J. Davis. It lends an air of Web 2.0 for Moodle. The feeling of a learning community that the block helps to foster is priceless. This block is useful for students and teachers to know who is online.





Figure 1: Online Users block.
A Moodle core block.



A teacher can gauge how many students are engaging themselves in night learning. Knowing who is online two hours before a quiz expires, can help students. They can contact and message each other or collaborate.



Two cases for invisibility. Why you should switch on the cloaking device.


All this is well and good, but there can be cases where having the entire class see your avatar is not cool. Some teachers may not want to be seen online. You might be grading assignments online and would not want to be interrupted by an instant message, chat window or by an email by your students. This is a real possibility if you are blessed to be an effective teacher, one who is well-loved by your students. So how to stay focussed on that rubric or grading of online submissions when you are peppered with requests from students?

If you are a teacher for whom 24 hours is never enough time, the only time you might be updating your course materials is after office hours. To be specific, at night. To be realistic, past the midnight hour, when the spouse and the kids are asleep. So, you might not be comfortable being seen on-line by your students at an unholy hour.  So as a teacher, how do you feel about accessing your Moodle site in the wee hours of the morning, and to find that your students are just as hard-working as you, online on the site? For me, there's always that funny feeling that the student might be on-line at the same time as I, and is wondering "Why is Mr. Frankie up late at night logged on to the Moodle site?".

Figure 2: Star Trek
Kligons in Alpha Sector, Captain!
Turn on the Cloaking Device, Spock!

Source: d-greg.deviantart.com, Creative Commons Attribute.

Of course you can also set the block (Site Administration | Modules | Blocks | Online Users | Remove after inactivity) to display users who have been online for 120 minutes. So if students see your avatar, it might have been because you logged on at 12 midnight and logged off a 12:30am and are now fast asleep. Only problem is, if you and your student are still logged on at 3:00am, then the game's up. You've been found out.

Some students may wish that they too were invisible in spite of that infernal online users block sitting pretty on the course page. A student may feel uncomfortable about revealing their presence to the world during the early hours of the morning.

So...?
So is there a way to make a user invisible to the Online Users block? I mean other than removing or hiding the block, is there a way to give a choice for the user to click a button and hey presto! Avatar disappears from the block. If Facebook allows you make yourself invisible on the Facebook chat window, why not apply the same concept to the Online Users block? We certainly can! To be exact, a user (teacher, student or administrator) can choose to allow his or her avatar and username to appear or be invisible on the Online Users block.

In this post, I present a practical and workable solution. I was the facilitator to this particular solution, and Mr. Matteo Scaramuccia of Genova Italy was the writer of the solution PHP code. Brilliant chap he is. So enough yacking around. Let's roll up our virtual sleeves and get to work!



HOW TO - MOODLE 1.9.15


Step 1: Access the Create a User Profile field link.


Figure 3: Click on the User profile fields link.



Step 2: Create a new profile field


Figure 4: Choose Checkbox from the dropdown box.



Step 3: Type in the settings values.



Figure 5: Lots of settings. Take your time.


The short name will later be referenced in PHP code. The Name is what appears on the User's edit profile page. Good to enter a brief and concise description. The "Display on signup page?" option should be set to "Yes". Click the "Save changes" button when finished.

Return to your homepage. Click on your username. In my case, I have the Login & Logout block installed.

Figure 6: Let's get to the user Profile page.


Scroll to the bottom of the page. See your custom, new user profile field description Stealth Mode? Great job so far! Tick the checkbox with your mouse and then click "Upate profile". You're halfway there!


Figure 7: Let's get to the user Profile page.



Step 4: Modify MoodleSite/blocks/online_users/block_online_users.php


Go to line 108 of the file named block_online_users.php. 
Comment off lines 108 to 114.

Figure 8: The original file. Backup it up first!


Copy the below code by Matteo Scaramuccia (where did this code come from?):

   if ($users = get_records_sql($SQL, 0, 50)) {   
       // We'll just take the most recent 50 maximum 
       foreach ($users as $user) { 
          require_once("$CFG->dirroot/user/profile/lib.php"); 
          $user->profile = (array)profile_user_record($user->id); 
          if (isset($user->profile) && !empty($user->profile['stealth'])) { 
             unset($users[$user->id]); 
             // i.e., don't display the avatar data, just loop back up 
          } else { 
              $users[$user->id]->fullname = fullname($user); 
          } 
       } 
   } else {         
             $users = array(); 
          }


By the way, click here for some information on the PHP craftsman, Matteo.


Paste the code right after the commented code inside block_online_users.php. See below.


Figure 9: The modified file contents


Save the modified file. Make sure you upload (FTP) it back to the MoodleSite/blocks/online_users/ folder.
Next, we test the block to make sure that it works.

Step 5: Test out the block!


Before ticking the checkbox, eveyone's listed on the Online Users block. No hiding. That's because the USS Enterprise's cloaking device hasn't been activated.


Figure 10: Now you see me....


Now observe the Online Users block after ticking the checkbox. See below.


Figure 11: ...now you don't!


Poof! I've been made invisible. Not because I'm the Administrator, but because I ticked my user profile's stealth field. If you managed to duplicate this on your Moodle production site, then CONGRATULATIONS! Now all that's left to do is to inform your users of the stealth feature and how to activate it. 

You probably know this. Your users are never really invisible since you can always turn live logs on (Site Administration | Reports | Live logs) to see student activity on your site. So you can run, but you can't hide from the Moodle Administrator. But at least other students can't see you if you don't want them to. 

What happens if it didn't work for you?

If the hack didn't work on your site, don't despair. Restore the original block_online_users.php file. You did back it up in the beginning right?? What!? If you didn't, then just undo the changes (Control-Z on your editor). Go to "Site Administration | Server | Debugging". Turn the Debugging mode on and choose "All: Show all reasonable PHP debug messages". Redo the changes and see if any warning or error messages appear on your screen.




With the debugging mode turned on, the resultant error messages will give you an idea how went wrong. In the worst case, give me a tinkle at boonsengkam@gmail.com.




[Important Update: Sunday 15/1/2012, 3pm]

I've added an option for the username to display a text message which can be selected by the user from the Edit User Profile screen. The text message will reflect the user's mood or current status. For example a 'busy' status would send a message to others that the user is not to be disturbed.

I've added a busy user profile field to my system.


  Figure 12: Yet another user profile field - busy.


  Figure 13: The busy user profile field in a user profile.



Then, I've modified block_online_users.php so that it checks if this busy field has been ticked. If yes, then the text "(busy)" is appended to the username on the Online Users block. 


Here what my latest Moodle 1.9.15
block_online_users.php section looks like now:

   ....

   if ($users = get_records_sql($SQL, 0, 50)) {  

      // We'll just take the most recent 50 maximum
      foreach ($users as $user) {
         require_once("$CFG->dirroot/user/profile/lib.php");
         $user->profile = (array)profile_user_record($user->id);
         if (isset($user->profile) && !empty($user->profile['stealth']))
         {  
           //Invisible status
           unset($users[$user->id]);  
           // i.e., don't display the avatar data, just loop back up

         } else if (isset($user->profile) && !empty($user->profile['busy']))
                {  
                   //Append the word "(busy)" to the username
                   $users[$user->id]->fullname = fullname($user)." (busy)";
                }
                else {  
                        //Normal visible status
                        $users[$user->id]->fullname = fullname($user);
                     }
      } //foreach
   } else {         
            $users = array();
          }
  ...


Here's the effect of the 'busy' status on the block:



Figure 14: Mr Frankie is a very busy teacher.
So why is he showing his students that he is online, but is 'busy'?

So now my students know that I'm online, but I'm busy with something and shouldn't be disturbed (hopefully).
This makes me think. Hmm...besides the stealth (invisible) and busy statuses, what other statuses can we put into the system? "Away for now", "Doing quiz", "Sleepy", "Awake", "Frustrated", "Happy", "Sad" and "Peaceful" are some that come to my mind. What do you think? Food for thought eh?

Future work
What is needed is to allow the user to set his or her status directly from the Online Users block. That would be more user-friendly and more Web2.0ish for this block.

Conclusion
With that, we have come to the close of this post. I hope that you found this post useful. A hearty THANK YOU goes out to the talented and brilliant Matteo Scaramuccia, without whom this post would not have been possible. Viva la Italia! Until the next time, here's to the la bella vita (the good life) that Moodle gives to us educators. Use Moodle to the max, but remember that you still need to read that book chapter inside out before you start your class lecture.

Addio (Goodbye),
Frankie Kam
Melaka, Malaysia 


APPENDIX

Moodle 2.0 equivalent code with the Stealth Mode, curtesy of Matteo, is shown below:


         if ($users = $DB->get_records_sql($sql, $params, 0, 50)) {   
             // We'll just take the most recent 50 maximum
             foreach ($users as $user) {
                require_once("$CFG->dirroot/user/profile/lib.php");
                profile_load_custom_fields($user);
                if (isset($user->profile) && !empty($user->profile['stealth'])) {
                    unset($users[$user->id]); // i.e., don't display the avatar data, just loop back up
                } else {
                    $users[$user->id]->fullname = fullname($user);
                }
             }
         } else {
             $users = array();


Moodle 2.0 equivalent code with the Stealth Mode AND Busy Mode, curtesy of Matteo, is shown below:


         if ($users = $DB->get_records_sql($sql, $params, 0, 50)) {   
             // We'll just take the most recent 50 maximum
             foreach ($users as $user) {
                require_once("$CFG->dirroot/user/profile/lib.php");
                profile_load_custom_fields($user);
                if (isset($user->profile) && !empty($user->profile['stealth'])) {
                    unset($users[$user->id]); // i.e., don't display the avatar data, just loop back up
                } else if (isset($user->profile) && !empty($user->profile['busy'])) {
                                 $users[$user->id]->fullname = fullname($user).'(busy)';
                         } else
                                  {
                                      $users[$user->id]->fullname = fullname($user);
                                   }
             }
         } else {
             $users = array();


If all you cared about was to hide the administrator and to show all other users, then you could use this code below which you would insert at line 139 of the original bloc_online_users.php file:


$admins = get_admins();  
$isadmin = false; 
foreach ($admins as $admin) { 
  if ($user->id == $admin->id) { 
    $isadmin = true; 
    break; 
 }

if($isadmin == true) 
   continue;  //loop back up!


As in the image below:


Figure 14: Make the Administrator invisible. Not everyone else.


Although this quick and dirty solution (hack) works, is not as flexible as compared to the main solution in this post. Still, it might be useful.


RELATED QUESTIONS AND ANSWERS

Question1: How do I hide a block from students?

Answer1 (a): 
Just insert a condition just before the return in the online users block:
return $this->content;
is (!isadmin()) { $this->content = ""; }
return $this->content;
Credit due: Ger Tielemans
Source: http://moodle.org/mod/forum/discuss.php?d=68164

Answer1 (b): 
This works in Moodle 1.9.4 and no code changes have to be made to the Moodle core:

    Turn editing on on the Front Page.
    Click the Assign Roles icon on the Online Users block.
    Click the Override Permissions tab.
    Click the Student role.
    Click the Prevent radio button next to 'View list of online users' and 'View block'.
    Click Save Changes.

After this change is applied your students will no longer see the Online Users block whereas non-student users will still see it. To disable it for any other role simply repeat the above for each role you want to modify.

Credit due: Luis de Vasconcelos

That's all folks!
You can also read Part II of this topic on this blog.

If you like this post or site
a small donation would be nice but would last only a day,
otherwise leaving a comment (or a compliment) below will last me a month!

Ratings and Recommendations by outbrain