This is the second article of a series of articles explaining how I created the Q-List WordPress plugin. First article explained the administration section and this one will explain the user interface. This article consists of the following steps:

  • Using tags in your posts like [qlist]
  • Handling cookies for your plugin
  • Handling forms




Note: I am going to assume you read the first article and know the steps that are explained on creating the plugin.


First we are going to hook out function that handles showing the questions to the “content”. This will allow us to use te [qlist] tag to show the results and the poll.

add_filter('the_content', 'add_qlist_to_content');



Now we need to create out add_qlist_to_content function. This is a really simple function, it will get the $content variable only and depending on if the user has “posted” answers it will post answers to the database and also will show the questions and the results.

function add_qlist_to_content($content){
	if($_POST['qlistanswers']){
		post_answers();
	}
	if(preg_match_all("[qlist]",$content,$matches)){
                // Here I check if the [qlist] tag exists in the content of your post. $content is a variable that WordPress sends into your function.
		$content= str_replace("[qlist]",show_questions(),$content);
                // And if it exists I replace [qlist] with the return value from show_questions() and at the end of our function we return the $content
	}
	return $content;
}


If you don’t return the $content variable at the end of your function, you won’t see anything in your posts.


Now its time to show our questions. I kept this function seperate for those who wants to use it independently in their theme instead of using the [qlist] tag.


This function, like you probably have guessed, shows the questions and the results of your poll. The $listclass variable is also used in the function declaration, so that if anyone wants to use a different class name in the html, they can do so when calling the function. It is an optional variable.

function show_questions($listclass=''){
	global $wpdb;
	$user_id=$_SESSION['user_id']; // We get the current users session id for the cookies, which also will be used in the database.
	if($listclass==''){$listclass="qlist";} // I set the list class to qlist if the variable isn't set
	if(!isset($user_id)){$formclick = 'onclick="alert(\'You need to have cookies enabled to vote in your browser!\')"';}
        //Above is a check to see if the user has enabled cookies in their computer, othewise the plugin won't allow them to vote.
	$db_questions = $wpdb->get_results("SELECT * from ".$wpdb->prefix."qlists order by q_order,question");// Getting all the questions from our qlists table

	if(empty($db_questions)){return "";}// Check to see if there are no results return empty
	$qlist = '
Switch View';//This is to call jquery function that switches the view $qlist .= '
'; $qlist .= ''; foreach ($db_questions as $db_question) {$i++; if($wpdb->get_var("Select count(a_id) from ".$wpdb->prefix."qlists_answers where u_id='$user_id' and q_id='".$db_question->q_id."' and answer='1'")){$isyes = ' checked="checked"';$uncheckedclass='';}else{$isyes='';$uncheckedclass='unchecked_qlist';} $qlist.='
'; $qlist.=$db_question->question; $qlist .=''.$res.'
'; $res = get_qlist_result($db_question->q_id); $qlist .= '
'; $ids .= "$db_question->q_id,"; } $qlist .= '
'; $qlist .= '
'; return $qlist; }



There is one main loop in the function that loops through the resultset that the query returns from the table to prinout the questions and results.

if($wpdb->get_var("Select count(a_id) from ".$wpdb->prefix."qlists_answers where u_id='$user_id' and q_id='".$db_question->q_id."' and answer='1'")){$isyes = ' checked="checked"';$uncheckedclass='';}else{$isyes='';$uncheckedclass='unchecked_qlist';}



This checks if the user has answered yes to any of the questions and if they did, the checkbox is checked.


And the rest of the loop is basic php where we show the appropriate questions and answers. To show the percentages from the database for the results, I use a function that calculates it. Following line calls the function every time a question is printing out to the page and saves the result into the $res variable

$res = get_qlist_result($db_question->q_id);


function get_qlist_result($id){
	global $wpdb;
	$res = $wpdb->get_results("Select answer from ".$wpdb->prefix."qlists_answers where q_id='$id'");
	$a=$b=0;
	foreach ($res as $r) {
		if($r->answer=="1"){$a++;}
		$b++;
	}
	return number_format((($a/$b)*100),2)."%";
}



This function gets the question id from our “main” loop and looks in our answers table for all the answers that has the question id as the id that we’ve sent in. And then I loop through the result set and everytime the answer was true to the question i increment the counter “$a”, and also the number of results are saved into the counter “$b”. At the end I calculated the percentage by dividing a by b and then multiplying it by 100, hence getting percentage.


number_format is a function that only returns so many decimals after the comma so you won’t have ugly numbers like 14,333333333. Also I return the percentage sign at the end of our string so that can be used in showing the answer percentage.


Also a hidden input with all the ids from the questions are set in the “main” loop so that, they can be used in posting the answers to the database.


In our add_qlist_to_content function we had an if statement that checks if anything was posted. This function calls our post_answers() function.


This function gets the users current session id and also the results from the form that was posted and updates the answers table if the user is only changing his answers, or creates new records if this is users first time.

function post_answers(){
	global $wpdb;
	$user_id=$_SESSION['user_id'];
	if($user_id){
	$vars = $_POST;
	$i=0;
		while (list($key, $value) = each($vars)){
			if(preg_match("/box(\d+)/",$key)){
				$answers_checked[$i] = str_replace("box","",$key);
				$i++;
			}
		}
		$all_q = explode(",",$_POST['qlistanswers']);

		for($a=0;$a<(count($all_q)-1);$a++){
			if(in_array($all_q[$a],$answers_checked)){
				$answers[$a]["q_id"]=$all_q[$a];
				$answers[$a]["answer"] = "1";
			}else{
				$answers[$a]["q_id"]=$all_q[$a];
				$answers[$a]["answer"] = "0";
			}
		}

		for($a=0;$aget_var("Select count(a_id) from ".$wpdb->prefix."qlists_answers where u_id='$user_id' and q_id='".$answers[$a]['q_id']."'")){
				$wpdb->insert($wpdb->prefix."qlists_answers",array('answer'=>$answers[$a]["answer"],'q_id'=>$answers[$a]["q_id"],'u_id'=>$user_id),array( '%d', '%d', '%s' ));
			}else{
				$wpdb->update($wpdb->prefix."qlists_answers",array('answer'=>$answers[$a]["answer"]),array( 'q_id' => $answers[$a]['q_id'],'u_id'=>$user_id ),array( '%d' ),array( '%d', '%s' ));
			}
		}
	}
}



The “while” loop in our function gets the checked true questions into our array “answers_checked”. Then we loop throught the full question list that we’ve sent, in our hidden field to create a new array that has all the questions and also the answers called $answers. This is a multi-dimensional array.


Our final loop just loops through the answers array and updates or creates records depending on the user id. Our check in this line shows if the user has answered the question or not. Rest is update and insert statements that I explained in the first article that WordPress uses.

if(!$wpdb->get_var("Select count(a_id) from ".$wpdb->prefix."qlists_answers where u_id='$user_id' and q_id='".$answers[$a]['q_id']."'")){



Now we also need to handle the users sessions so that we won’t lose them next time they come to the site. WordPress has a hook init that runs when the page is starting to load. This is run even before our plugin is run. We call a function set_userID_qlist() here.


This function first sets the expiration time for the cookie to be a year. Also we check if the sessions are already declared in our website if not we start the sessions. Then we check for the cookie user_id and if it is set, we save it into the session user_id. If it isn’t set then we create a unique id that starts with the string qid- and has random characters rest. uniqid is a php function which you can find information on php.net easily. Then we set the cookie user_id and also the session user_id

add_action('init', 'set_userID_qlist');

function set_userID_qlist(){
	$expire=time()+60*60*24*30*12;
	if(!session_id()){session_start();}
	if(isset($_COOKIE['user_id'])){
		$user_id=$_COOKIE['user_id'];
		$_SESSION['user_id']=$user_id;
	}else{
		$user_id = uniqid("qid-");
		setcookie("user_id", $user_id, $expire);
		$_SESSION['user_id']=$user_id;
	}
}



At this point your plugin will work fine but you styling won’t since we didn’t hook our stylesheet file to our plugin. To do so you need to use the wp_head action to call the function that registers and then prints the stylesheet. This function is self explanatory and there isn’t really much going on in it.

add_action('wp_head', 'add_qlist_styles');

function add_qlist_styles(){
	wp_register_style('qlist_create', WP_PLUGIN_URL.'/q-list-list-creator/q-list.css');
	wp_enqueue_style('qlist_create');
	wp_print_styles();
}



Also one last thing is to get our Switch View link to work. On click we made our link to call a javascript function named show_checked_qlist(). We need to create this function and hook it into our footer so that it printsout in the footer. This is a better practice to put javascript to the footer.

add_filter('wp_footer','add_qlist_js');

function add_qlist_js(){
	echo '';
}



You want to use jQuery selectors instead of using onclick events in the html. That is a whole article itself to be explained and is not in the scope of this one.


This concludes our plugin. Hope you liked it. Please let me know how you would have done this plugin or about your thoughts in the comments section.





Related Posts

Leave a Reply