Tag Archives: watupro

[WatuPRO] How to Open The Export Files (Tab Delimited CSV Files)

In WatuPRO all export files are TAB (tabulator) delimited CSV files. The reason we use this format is because comma delimited files are more error prone when the data contains rich text, HTML, commas, quotes etc. Tabulator is a lot more reliable as delimiter when importing and exporting data.

If you use Microsoft Excel here are a couple of links that will help you:

The official Microsoft guides

A pictorial by Excel Easy

Here at Kiboko Labs we prefer to use Libre Office Calc. It’s free and has versions for Mac, Windows, and Linux. When you double-click a .csv named file it automatically suggests the proper delimiter. Just select UTF-8 (Unicode) as encoding, if this is not already selected and open the file. Much easier.

[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
}