Tag Archives: watupro

[WatuPRO] How To Make It Reload The Page on Each Question

This is a request we got few times. WatuPRO is designed to load pages in paginated quizzes nicely via ajax. This is the contemporary way of doing things and the desired behaviour for 99.9% of the customers. So “feature” to reload page on each refresh will probably never be added.

However this post will explain you how to customize the plugin yourself and achieve this in the rare case you need it (for example to get more ad impressions).

This is too complicated to be done as external plugin so it involves customizing WatuPRO directly. Here is it, step by step:

0. For all of this to work you must select “Automatically store user progress as they go from page to page” in the quiz settings.

1. Open lib/main.js and add:

WatuPRO.doReload = false;

under the other WatuPRO properties on top.

2. In method WatuPRO.nextQuestion in the same file add the following changes (in red) to the following piece of code:

       if(!this.doReload) {		
		jQuery("#question-" + WatuPRO.current_question).show();		
		
		this.hilitePage(WatuPRO.current_question, this.answered);			
		
		// show/hide next/submit button
		if(WatuPRO.total_questions <= WatuPRO.current_question) {		 			jQuery("#next-question").hide();		 			jQuery('#action-button').show(); 			if(jQuery('#WTPReCaptcha').length) jQuery('#WTPReCaptcha').show();  		} 		else { 			jQuery("#next-question").show();		 			if(jQuery('#WTPReCaptcha').length) jQuery('#WTPReCaptcha').hide(); 		} 		 		// show/hide previous button 		if(WatuPRO.current_question>1) jQuery('#prev-question').show();
		else jQuery('#prev-question').hide();
		
		// show/hide liveResult toggle if any
		if(jQuery('#questionWrap-'+WatuPRO.current_question).is(':hidden')) {
			jQuery('#liveResultBtn').hide();
		} else {
			if(jQuery('#liveResultBtn').length)  jQuery('#liveResultBtn').show();
		}
	}	
	else jQuery('.watupro-buttons').hide();

3. At the bottom of the same method add:

jQuery.post(WatuPRO.siteURL, data, function(msg){
		if(WatuPRO.doReload) location.reload();
	})	

This will make it reload when WatuPRO.doReload is true.
Now we have to make it true when clicking on buttons:

4. In the method initWatu in the same file REMOVE the red from the following code:

// different behavior if we have preloaded page
	if(!WatuPRO.pagePreLoaded) {
		jQuery("#question-1").show();
	} else WatuPRO.goto(null, WatuPRO.current_question);

so the goto gets executed always.

5. Open views/show_exam.php and find the calls to WatuPRO.nextQuestion(event, ‘previous’); and WatuPRO.nextQuestion(event). Make doReload to be true like this:

onclick=”WatuPRO.doReload=true;WatuPRO.nextQuestion(event, ‘previous’);”

6. If you use the paginator, do it for the paginator too. Models/exam.php static function paginator:

onclick=’WatuPRO.doReload=true;WatuPRO.goto(event, “.$j.”);’

7. Now if you want this to work for non-logged in users you need to make several PHP changes. By default WatuPRO never stores progress for non-logged in users to save server resources. But you can change this. In show_exam.php (not the view/ but the main file) add the following code (in red):

if(!empty($_SESSION['watupro_taking_id'])) {
	$in_progress = $wpdb->get_row($wpdb->prepare("SELECT * FROM ".WATUPRO_TAKEN_EXAMS." 
		WHERE ID=%d AND exam_id=%d AND in_progress=1 ORDER BY ID DESC LIMIT 1", $_SESSION['watupro_taking_id'], $exam_id));
}
if(!empty($advanced_settings['dont_load_inprogress'])) $in_progress = null;

so we can get taking ID from session (Sessions MUST be enabled on your server)

8. In order to store tkaing ID in session you need to do several changes in lib/watupro.php. The first is to remove/comment the following from watupro_store_details() and watupro_store_all():

if(!is_user_logged_in()) exit;

9. Then in function add_taking() just before return $taking_id; add:

$_SESSION['watupro_taking_id'] = $taking_id;

10. In the same function just above if(empty($taking_id)) { add:

if(!empty($_SESSION['watupro_taking_id'])) $taking_id = $_SESSION['watupro_taking_id'];

That’s it. Shouldn’t take you more than 1-2 hours. If you can’t handle it yourself, we can provide the service for charge.

This is a customization and we cannot provide free support for it. If the change does not work you have to debug it yourself. Make sure sessions are enabled on your server.

[WatuPRO] How To Display Different Content Depending on Last / Not Last Quiz Attempt

WatuPRO has a setting to limit the number of quiz attempts by IP addres (or by username if your quiz requires user login). Sometimes you may want to display different message to the user depending on whether this is their last quiz attempt or not. For example you may want to conditionally display text like “Try again!” and “Sorry, you have no more attempts!”.

WatuPRO doesn’t yet have such configuration but it’s easy to build a custom filter using our barebone customization plugin.

If you are not interested in the code, read only the following section which also gives download link for the custom plugin. The third section of this article will show and explain the code.

Customized Filter Download and Usage

In order to use the new filter you need to download and install this plugin:

watupro-custom1.1

How to use it? Simply include your conditional content between “tags”:

{last} This content will be shown only after the last user’s attempt on the quiz. {/last}

{notlast} This content will be shown only if the user has more attempts. {/notlast}

You can include these tags in the “Final page / quiz output” tab or in the grade descriptions in case you are showing grade descriptions in your quiz output.

Here’s an example:


 

You completed quiz %%QUIZ-NAME%%.

You got %%PERCENTAGE%%% correct answers.

{last}You have no more attempts.

Here are your answers: %%ANSWERS%%{/last}

{notlast}You can try again{/notlast}


Programming Code

If you are interested in the code, here’s how we did it. In the watuprocustom_init() function we added a filter for the “watupro_content” filer:

add_filter(‘watupro_content’, array(‘WatuPROCustomFilters’, ‘last_attempt’));

And below is the filter function. It works only by IP but it’s easy to change it to work with quizzes restricted by “user_id” as well.

class WatuPROCustomFilters {
	// replace contents of  &  pseudo-tags
	//   & 
	// currently used for %%ANSWERS%% variable
   static function last_attempt($content) {
   	global $wpdb;
		if(empty($_POST['watupro_current_taking_id'])) return $content;   
		
		// now get the contents between last-attempts and not-last-attempts tags
		// in case tags are not there return content
		if(!strstr($content, '{last}') and !strstr($content, '{notlast}')) return $content; 	
   	
   	// select taking
		$taking = $wpdb->get_row($wpdb->prepare("SELECT exam_id, ip, user_id 
			FROM ".WATUPRO_TAKEN_EXAMS." WHERE ID=%d", $_POST['watupro_current_taking_id']));
			
		// select quiz allowed num takings	
		$quiz = $wpdb->get_row($wpdb->prepare("SELECT takings_by_ip FROM ".WATUPRO_EXAMS." 
			WHERE ID=%d", $taking->exam_id));
			
		$is_last_attempt = false;
			
		if($quiz->takings_by_ip) {
		
			// select num takings
			$num_takings = $wpdb->get_var($wpdb->prepare("SELECT COUNT(ID) FROM ".WATUPRO_TAKEN_EXAMS."
			WHERE exam_id=%d AND ip=%s", $taking->exam_id, $_SERVER['REMOTE_ADDR']));
			
			if($num_takings >= $quiz->takings_by_ip) $is_last_attempt = true;
		}		
		
		// now replace properly
		if($is_last_attempt) {
			// the content between  and  should be shown. The other should be removed
			$content = str_replace(array('{last}','{/last}'), '', $content);
			$content = preg_replace('#\{notlast\}(.+?)\{\/notlast\}#s', '', $content);
		}
		else {
			echo 'werehere';
			$content = str_replace(array('{notlast}','{/notlast}'), '', $content);
			$content = preg_replace('#\{last\}(.+?)\{\/last\}#s', '', $content);
		}
		
		return $content;		
			 
   }	// end last_attempt filter
}

How Does The Timer Work in WatuPRO?

WatuPRO, the premium version of our WordPress quiz plugin has a timer feature. It’s enabled by a setting in the  Add / Edit Quiz page:

Set time limit of minutes (Leave it blank or enter 0 to not set any time limit.)

When you set anything different than zero, everyone who starts the quiz will see “Start Quiz” button. When started the timer starts running.  Here are several frequently asked questions about the timer and their answers:

Q: What happens when the timer runs out?

A: The user results are automatically submitted. So the questions they already answered will be recorded properly, the other will be marked as unanswered.

Q: What happens if the user refreshes the page from their browser?

A: The timer continues from where they were. No time is lost or added except the few seconds taken for refreshing the page.

Q: What happens if the user closes the browser, their internet connection get lost, power goes down etc?

A: The timer keeps running behind the scene so the time when the user was not online is lost. This is done to prevent cheating of users who can take screenshot of the questions and answer “at home”.

When the user comes back, the timer continues. If all the time ran out, their results are submitted automatically. Such a situation requires that the user have stored their progress via the optional Save button or their progress is automatically stored using the appropriate option (for paginated quizzes). If no progress is stored for a given user and they come back after timer ran out, they will never be able to submit the quiz!

Q: I see some users took hours to complete a quiz that has just 30 minutes time limit! Are they cheating the timer?

No, they are not cheating the timer. As explained above when the user closes the browser and come back later after the time has passed their results are automatically submitted (but only the answers they gave before returning). In such event there was more time from start to end of the test than allowed, but the user did not use that time. The quiz is just showing you this to let you know which users abandoned the tests and then came back later (and how much later) to have it immediately auto-submitted. This information can be useful to help you design the quiz better.

Q: How does it work for non logged in users?

A: The same way as of logged in users except that closing the browser may clear the session and restart the timer. Refreshing the page does not restart the timer – it keeps running from where it was refreshed.

Q: Can users with disabled JavaScript on their browsers cheat the timer?

A: No, they can’t. The start time of their quiz attempt is recorded in the database so even without any javascript they can’t cheat the timer. Results of users who try to cheat the timer this way and exhaust their time will not be accepted. They will remain as “unfinished quiz attempts”.

Q: Is there a place where I can see unfinished quiz attempts?

A: Yes. If there are any quiz attempts that are currently in progress, you will see the following link in your “View results” page (this is the page you get when you click on the “Taken X times” link under “View Results” column on your Quizzes page) :

There are 1 unfinished attempt(s).

You can click on that link to see these attempts and clean them if you wish (be careful, some of these might be of an user currently taking a quiz).

Q: Do search engines index the contents of quizzes with timer?

A: The questions of timed quizzes are hidden before the timer is started. This is to avoid tech-savvy users viewing the questions by using “view source”. For this reason search engines can’t index these questions.

Q: Can I set different timers per each question?

No, the timer is available only per quiz basis. Creating per-question timer is extremely complicated and unlikely to ever happen so please don’t contact us asking about it.

Q: I had a quiz taker complain that their results were submitted blank. How come?

There is a protection against smart savvy users who switch off JavaScript on their browsers to earn more time than allowed. Pity for them, they can’t cheat the timer: time is tracked both on the front-end and the back-end. Users who cheat will have their answers completely wiped.

If you are convinced than honest users may somehow have their answers lost, we recommend setting some pagination (for example one question per page or 10 questions per page etc), and selecting the following option:

Answers that are stored in the system will not be wiped out. This will ensure that even if some odd computer problem occurs (we could never reproduce such case!) a genuine quiz taker will not lose the answers given before the timer ran out. This will work for logged in users.

Q. I changed the timezone settings on my site and someone who was taking a timed quiz got their time increased or decreased

The time when user starts the quiz is recorded accordingly to your server time zone settings to prevent all forms of cheating. So if you change the timezone settings in the middle of a quiz, this will of course affect everyone who has already started it but has not completed it. This is normal and cannot be avoided so simply don’t change the timezone while people are doing timed quizzes. Any quiz attempts that start after the change will be timed correctly.