Advertisement
Plugins

Integrating Multiple Choice Quizzes in WordPress - Creating the Backend

by

Multiple choice questions are something that most of us have faced at least once in our life. We love them because we can provide correct answers by logically thinking about provided possibilities, even if we don't exactly know the correct answer. Also answering takes less time which makes it so popular.

Creating a multiple choice quiz in WordPress can be a very exciting and profitable task. You can use it in your personal blog to attract more visitors, or you can create a premium section with advanced quizzes, or you can create quizzes focusing on popular certification exams. There are numerous possibilities for making it profitable.

This plugin won't take you through to creating quizzes for building a business, but we have to start somewhere to get where we want to go. So this would be a good start for creating quizzes and making profits out of it.

So let's get started.


Functionality of the Plugin

First we need to gather the requirements of the plugin before going to design or implementation. Basically, we should be able to create multiple choice quizzes and allow users to take the quizzes and get results.

So let's take a look at the detailed requirements and components of our plugin:

  • The plugin should have a backend where we can insert questions and answers dynamically. Also it's ideal to have quiz categories to group quizzes into specific sections.
  • Site admin should be able to configure the quizzes through a settings page.
  • Users should have a frontend where they can take a quiz.
  • Once a quiz is completed users should be able to get the scores and results.

This tutorial is going to be constructed as a two part series, where we develop the backend of the plugin in the first part, followed by the plugin frontend in the second part.


Planning the Plugin Backend

In this part we are going to focus on developing the backend of the plugin where we develop the required data for quizzes.

Usually there is a list of quizzes, each of them containing a specific list of questions. With this plugin we are not going to create quizzes. We will be creating individual questions and assigning them dynamically to quizzes when requested.

Now we can take time to identify the components required for implementing the backend as listed in the following section.

  • Questions need to be created in the backend with the answers. A custom post type will be the best solution for implementing the questions. So we are going to use a custom post type called wptuts_quiz.
  • Each question should have multiple answers and one correct answer. Fields for answers will be created inside a meta box in the custom post creation screen.
  • Questions will be categorized into various sub-topics hence we need a custom taxonomy called quiz_categories for the wptuts_quiz post type.
  • Then we need to validate the question creation process. We will be using client side jQuery validations when necessary in question creation.
  • Finally we need a plugin settings page to store the number of questions per quiz and the duration for a quiz.

Having identified the necessary WordPress components, we can directly move into implementing the backend of the quiz plugin.


Creating Questions

The question creation process consists of four main sections: defining custom post type, defining custom taxonomy, assigning custom fields, and validations. Each of these sections will be discussed with detailed code in the upcoming sections.

1. Creating the Questions Custom Post Type

We need the most basic form of custom post type for questions without any advanced configurations. The only thing we need to consider is the selection of the right field for the question.

The default post creation screen contains two fields for title and content. You can choose any of those fields for the question. I am going to choose concatenation of both title and content fields considering advanced possibilities.

We will be creating an object-oriented plugin instead of a functional plugin, so all of the necessary actions, shortcodes and initializations will be done inside the constructor. The following contains the code for implementing the wptuts_quiz post type.

class WP_Quiz {

	public $plugin_url;

	public function __construct() {

		$this->plugin_url = plugin_dir_url( __FILE__ );

		add_action( 'init', array( $this, 'wpq_add_custom_post_type' ) );

	}

	public function wpq_add_custom_post_type() {

		$labels = array(
			'name' => _x( 'Questions', 'wptuts_quiz' ),
			'menu_name' => _x( 'WPTuts Quiz', 'wptuts_quiz' ),
			'add_new' => _x( 'Add New ', 'wptuts_quiz' ),
			'add_new_item' => _x( 'Add New Question', 'wptuts_quiz' ),
			'new_item' => _x( 'New Question', 'wptuts_quiz' ),
			'all_items' => _x( 'All Questions', 'wptuts_quiz' ),
			'edit_item' => _x( 'Edit Question', 'wptuts_quiz' ),
			'view_item' => _x( 'View Question', 'wptuts_quiz' ),
			'search_items' => _x( 'Search Questions', 'wptuts_quiz' ),
			'not_found' => _x( 'No Questions Found', 'wptuts_quiz' ),
		);

		$args = array(
			'labels' => $labels,
			'hierarchical' => true,
			'description' => 'WP Tuts Quiz',
			'supports' => array( 'title', 'editor' ),
			'public' => true,
			'show_ui' => true,
			'show_in_menu' => true,
			'show_in_nav_menus' => true,
			'publicly_queryable' => true,
			'exclude_from_search' => false,
			'has_archive' => true,
			'query_var' => true,
			'can_export' => true,
			'rewrite' => true,
			'capability_type' => 'post'
		);

		register_post_type( 'wptuts_quiz', $args );
	}
}

We have enabled both title and editor fields in the custom post type to use for the question. Since the functions are located inside a class, we have to use $this in our WordPress actions, filters, and shortcodes to call the functions.

Apart from that all the parameters mentioned in the code are initialized with their default values.

2. Creating the Question Categories

In order to group questions into specific sections, we need something similar to default WordPress categories. Hence we will be using a custom taxonomy called quiz_categories. We need to call the custom taxonomy generation function on the init action as we did earlier. So the constructor of our plugin class needs to be updated with the following code.

add_action( 'init', array( $this,'wpq_create_taxonomies' ), 0 );

Then we can implement the wpq_create_taxonomies function on the wptuts_quiz post type as shown in the following code.

function wpq_create_taxonomies() {

	register_taxonomy(
		'quiz_categories',
		'wptuts_quiz',
		array(
			'labels' => array(
				'name' => 'Quiz Category',
				'add_new_item' => 'Add New Quiz Category',
				'new_item_name' => "New Quiz Category"
			),
			'show_ui' => true,
			'show_tagcloud' => false,
			'hierarchical' => true
		)
	);

}

I have used the default option parameters to create this custom taxonomy. Once the plugin is activated your custom post type and taxonomy will be displayed as shown in the following screen.

3. Creating the Question Answers

Next, we have to create multiple answers for each question. In this plugin the maximum number of answers per single question will be limited to five.

You can dynamically assign 1-5 answers for any question. Also we need to specify the correct answer from the provided list of answers. Since this data is associated with our questions, we can use a meta box with custom fields to generate the necessary fields.

As usual we need to update the constructor with the following code:

add_action( 'add_meta_boxes', array( $this,'wpq_quiz_meta_boxes' ) );

Consider the following code for the implementation of meta boxes with answers fields.

function wpq_quiz_meta_boxes() {
	add_meta_box( 'quiz-answers-info', 'Quiz Answers Info', array( $this, 'wpq_quiz_answers_info' ), 'wptuts_quiz', 'normal', 'high' );
}

function wpq_quiz_answers_info() {

	global $post;

	$question_answers = get_post_meta( $post->ID, '_question_answers', true );

	$question_answers = ( $question_answers == '' ) ? array( '', '', '', '', '' ) : json_decode( $question_answers );

	$question_correct_answer = trim( get_post_meta( $post->ID, '_question_correct_answer', true ) );

	$html = '<input type="hidden" name="question_box_nonce" value="' . wp_create_nonce( basename( __FILE__ ) ) . '" />';

	$html .= '<table class="form-table">';

	$html .= '<tr><th style=""><label for="Price">Correct Answer</label></th><td><select class="widefat" name="correct_answer" id="correct_answer" >';

	for ( $i = 1; $i <= 5; $i++ ) {

		if ( $question_correct_answer == $i ) {
			$html .= '<option value="' . $i . '" selected >Answer ' . $i . '</option>';
		}
		else {
			$html .= '<option value="' . $i . '">Answer ' . $i . '</option>';
		}

	}

	$html .= '</select></td></tr>';

	$index = 1;

	foreach ( $question_answers as $question_answer ) {

		$html .= '<tr><th style=""><label for="Price">Answer ' . $index . '</label></th>';
		$html .= '<td><textarea class="widefat" name="quiz_answer[]" id="quiz_answer' . $index . '" >' . esc_textarea( trim( $question_answer ) ) . '</textarea></td></tr>';

		$index++;

	}

	$html .= '</tr>';

	$html .= '</table>';

	echo $html;
}

4. Code Explanation

  • Answers of each question will be stored in a JSON encoded string in the post_meta table with the key _question_answers. So we access this field using the get_post_meta function to get the current values.
  • Then we get the correct answer of the question using a similar method. The correct answer will be stored as a string in the post_meta table with the key _question_correct_answer.
  • Finally, we create the HTML form, which contains the correct answer as a dropdown box and the possible answers as five text area fields.
  • All the existing values retrieved using the get_post_meta function will be assigned to the respective fields.

You should see something similar to the following screen, once you create the meta box.

quiz1

Now we have all the data required for our quiz generation plugin. Next step is to save the question data into the database.

But we need some validations prior to that. So let's move into validations.


Validating Question Creation

We don't have complex validation rules at this stage in the question creation process. Therefore we are going to use client side jQuery validations before submission.

Here we need the admin_enqueue_scripts action to be included into the constructor of our plugin.

So update the constructor with following code before we get started.

add_action( 'admin_enqueue_scripts', array( $this, 'wpq_admin_scripts' ) );

Now look at the following code for including necessary script files for validation.

function wpq_admin_scripts() {

	wp_register_script( 'quiz-admin', plugins_url( 'js/quiz.js', __FILE__ ), array( 'jquery' ) );

	wp_enqueue_script( 'quiz-admin' );

}

Using wp_register_script and wp_enqueue_script, we have a plugin-specific JS file called quiz.js for handling validations. Validation will be done using the jQuery library and hence we have set the built-in jQuery library as a dependency for our plugin-specific JavaScript.

Having included the scripts, let's implement the actual validations in the quiz.js file as shown in the following code.

jQuery(document).ready(function($) {

	$("#post-body-content").prepend('<div id="quiz_error" class="error" style="display:none" ></div>');

	$('#post').submit(function() {

		if ( $("#post_type").val() =='wptuts_quiz' ) {

			return wpq_validate_quizes();

		}

	});

});

First, we assign an empty div element to the post creation screen to display any errors. Then we can call a custom JS function on the post publish action by checking the correct post type using the #post_type hidden field value.

The following code contains the implementation of the wpq_validate_quizes function.

var wpq_validate_quizes = function() {

	var err = 0;

	$("#quiz_error").html("");

	$("#quiz_error").hide();

	if ( $("#title").val() == '' ) {

		$("#quiz_error").append("<p>Please enter Question Title.</p>");

		err++;

	}

	var correct_answer = $("#correct_answer").val();

	if ( $("#quiz_answer"+correct_answer).val() == "" ) {

		$("#quiz_error").append("<p>Correct answer cannot be empty.</p>");

		err++;

	}

	if ( err > 0 ) {

		$("#publish").removeClass("button-primary-disabled");

		$(".spinner").hide();

		$("#quiz_error").show();

		return false;

	}
	else {

		return true;

	}
};

Code Explanation

  • First we have to hide the error container and set its current error message to empty.
  • Then we check whether the title exists, as title is mandatory for questions.
  • Next we get the selected correct answer and check whether the answer field related to the correct answer is empty.
  • When validation errors are generated we display the errors in the specified error container and prevents the submission of the post.

The following image shows the post creation screen with custom validation messages.

wpquiz2

Once the form is successfully validated without errors, we can move onto saving the question details to the database.


Saving Question Details

WordPress provides an action called save_post, which will be executed just after the post creation. We can define a custom function on the save_post action to save the custom field details into the database.

As usual update the constructor with the save_post action code.

add_action( 'save_post', array( $this, 'wpq_save_quizes' ) );

Implementation of the wpq_save_quizes function is given in the following code.

function wpq_save_quizes( $post_id ) {

	if ( ! wp_verify_nonce( $_POST['question_box_nonce'], basename( __FILE__ ) ) ) {

		return $post_id;

	}

	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {

		return $post_id;

	}

	if ( 'wptuts_quiz' == $_POST['post_type'] && current_user_can( 'edit_post', $post_id ) ) {

		$question_answers = isset( $_POST['quiz_answer'] ) ? ( $_POST['quiz_answer'] ) : array();

		$filtered_answers = array();

		foreach ( $question_answers as $answer ) {

			array_push( $filtered_answers, sanitize_text_field( trim( $answer ) ) );

		}

		$question_answers = json_encode( $filtered_answers );

		$correct_answer = isset( $_POST['correct_answer'] ) ? sanitize_text_field( $_POST['correct_answer'] ) : "";

		update_post_meta( $post_id, "_question_answers", $question_answers );

		update_post_meta( $post_id, "_question_correct_answer", $correct_answer );

	}
	else {

		return $post_id;

	}
}

The post ID is passed automatically to this function. Initially we execute validations for nonce value and autosave. The most important thing before saving is the validation of post type.

If you omit the post type check, this code will be executed for all the post types in your WordPress installation including normal posts, which can result in inconsistent data.

Finally we get the values of our answers fields and correct answer field to be saved to the database using the update_post_meta function. All the custom fields details will be saved to the post_meta table.

Now we have completed the question creation process. Since we are using randomly generated quizzes, you might need lots of questions to see this plugin in action. So get ready by adding additional questions before we implement the quiz in the next part.


Quiz Settings Page

Even though it's not mandatory, it's ideal to have a settings page for our plugin so that the admin can customize according to their preferences.

So let's implement a simple settings page to contain the quiz duration and number of questions per quiz. We need to implement the admin_menu action in the constructor.

add_action( 'admin_menu', array( $this, 'wpq_plugin_settings' ) );
function wpq_plugin_settings() {

	//create new top-level menu

	add_menu_page( 'WPTuts Quiz Settings', 'WPTuts Quiz Settings', 'administrator', 'quiz_settings', array( $this, 'wpq_display_settings' ) );

}

function wpq_display_settings() {

	$html = '<div class="wrap">
		<form method="post" name="options" action="options.php">
			<h2>Select Your Settings</h2>' . wp_nonce_field( 'update-options' ) . '

			<table width="100%" cellpadding="10" class="form-table">
				<tr>
					<td align="left" scope="row">
						<label>Number of Questions</label><input type="text" name="wpq_num_questions" value="' . get_option( 'wpq_num_questions' ) . '" />
					</td>
				</tr>
				<tr>
					<td align="left" scope="row">
						<label>Duration (Mins)</label><input type="text" name="wpq_duration" value="' . get_option( 'wpq_duration' ) . '" />
					</td>
				</tr>
			</table>

			<p class="submit">
				<input type="hidden" name="action" value="update" />
				<input type="hidden" name="page_options" value="wpq_num_questions,wpq_duration" />
				<input type="submit" name="Submit" value="Update" />
			</p>

		</form>
	</div>';

	echo $html;
}

We can use the add_menu_page function to add a settings page to the admin area. The wpq_display_settings function is used to implement the display elements of the settings page.

We have used two text fields for duration and questions per quiz. Form submission and data saving can be handled manually using custom code, but WordPress provides us a simplified method for updating options.

In this method you have to set the form action to the options.php file. Then you have to create a hidden field called action to contain the value of 'update'. Finally we need to have another hidden field called page_options to contain the names of the two text fields to be updated.

Make sure to use these built-in options update techniques in scenarios where the requirements for saving the fields are not complex.

Once the submit button is clicked, form details will be updated automatically without any custom code.


What's Next

We have completed the backend of our quiz plugin. Now you can create questions and get ready for the next part where we will use these questions to dynamically generate quizzes.

Until then let me know the best possible way to implement a dynamic quiz on the frontend. Keep in mind that only one question will be displayed at a time. When the user requests a question, he can move to the next question.

Looking forward to your suggestions.

Related Posts
  • Web Design
    UX
    Impress Your Visitors With a Web 2.0 Hit CounterCounter thumb
    If there's one way to show off how successful your site is, it's by letting your visitors know how many others have been there before them. Let's furnish a web page with a hit counter!Read More…
  • Code
    Theme Development
    Custom Controls in the Theme CustomizerTheme customizer custom control 400
    In the last article, we explored the advanced controls available in the Theme Customizer, and how to implement them. We’re going to look at how to create our own custom control, allowing you to choose which Category of Posts are displayed on the home page. To get started, download version 0.6.0 of our Theme Customizer Example.Read More…
  • Code
    PHP
    Validation and Exception Handling: From the UI to the BackendProcedural to oop php retina preview
    Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached a point when we had to take architectural actions to accommodate all the exceptional cases our quite large software project needed to handle. Below is a list of practices we came to value and apply when it comes to validation and exception handling.Read More…
  • Code
    Plugins
    Integrating Multiple Choice Quizzes in WordPress – Creating the FrontendIntegrating multiple choice quizzes in wordpress
    This is the second part of the series on developing a multiple choice quiz plugin for WordPress. In the first part we created the backend of our plugin to capture the necessary data to store in the database. In this final part, we will be creating the frontend of the plugin where the users can take quizzes and evaluate their knowledge.Read More…
  • Code
    Creative Coding
    Using Backbone Within the WordPress Admin: The Back EndThumbnai02l
    The rumours are true! The WordPress Admin Panel is now using Underscore and Backbone! This means that with minimal effort, we can begin to utilise these fantastic JavaScript libraries in our own plugins. This tutorial will show you exactly how you can do that. We'll create the Admin part of a Quiz plugin. We'll use a simple Custom Post Type to save Questions, and then within each question we'll add a meta box that will allow us to enter up to 4 answers and select which is the correct one. We'll be going through how to use templates, how to hook into click and key-up events, how to save data back to the WordPress database and most importantly, how to 'get your truth out of the Dom', as the creator Jeremy Ashkenas likes to put it.Read More…
  • Code
    Plugins
    Creating Responsive Pricing Table Plugin for WordPressPricing table plugin
    Pricing tables are a key component of your business that promotes your products and helps users choose between different services you have. Most modern commercial WordPress themes provide built in Pricing Tables. There are also plenty of free and commercial pricing table plugins for WordPress. This tutorial is intended to provide knowledge to WordPress developers on creating a plugin from scratch which enables customization in different projects. Every web design is trying to accomplish responsive features which enable better look and feel on any kind of device. The pricing tables created with this plugin will work on all kinds of devices such as mobiles and tablets as well. So let's get started.Read More…