HD Quiz

Need to send invoices?
Check out my new WordPress plugin HDInvoice
Limited time launch sale

hi, i’m checking the new v1.8. There are a lot of new fea…

Published: May 16, 2020
Support status: closed

hi, i’m checking the new v1.8. There are a lot of new features and the plugin is super!!!

I’m testing (with previous version) the possibility for a user to create a question from the front end. This is possible (with limitations) because the question’s data (answers, correct answer number etc) is saved into Custom Fields. At the new version all question’s data stored as a string…..

I want to ask: is it possible for a user, visitor, registered to create a question (or a quiz) from the front end (for example using a form or php template).

thanks for the great plugin and support.

This thread has been imported from harmonicdesign.ca/hd-quiz/

thread author: maki

Hi Maki,
this is certainly possible, but I caution against it. Allowing anyone to modify your site or submit data is a security risk.

If you are comfortable with this, then I suggest taking a look at the browser console when you save a new question or save quiz settings. When doing so, you will see the javascript object that is being serialized and saved. This way you will know the meta name, type, options, and value for each meta field.

From there, take a look at the function hdq_sanitize_fields located in ./includes/functions/php. You can run your object through this to auto sanitize it. The function that saves data is called hdq_save_question, but you’ll want to write your own function to account for the lack of security nonce and user permissions.

16 May 2020 — 06:22 support admin - Dylan

Thanks for your answer.
Sorry, but I don’t understand the way you describe it. I don’t know much about php encoding and functions.

If you can give me the code and how to work, maybe it’s worth a try.

I know that allowing anyone to submit data is a security risk, but I think the administrator should approve that data before it appears.

16 May 2020 — 06:36 thread author - maki

Systems like HD Quiz were designed to run securely in the backend of WordPress. Converting that to safely run on the front end is NOT a small change. Doing this right would take even a seasoned developer several hours to do. Because of this, all I can (and am willing) to do is help point you in the correct direction.

So there are two types of things you will need to be able to create and save meta (options or settings) for. The first is a quiz. Quizzes are custom taxonomies called quiz. Think of a quiz as a special category used to store questions – like a blog and normal categories. Before you can edit quiz settings, you will need to create the quiz. Once again, take a look at ./includes/functions.php to see how I am doing this in HD Quiz. The function is called hdq_add_quiz and uses WordPress’ wp_insert_term to save.

The second thing you will need is a question. Questions are a custom post type called post_type_questionna (reaaaallly wish I named this something better when I first created HD Quiz). When creating this CPT, you will need to attach it to a quiz. Just like when you add a category to a post for a blog. For this, take a look at the function hdq_save_question to see how I am saving question data.

So the above is just basic WordPress dev stuff – nothing special. So now let’s talk about HD Quiz specific things.

Instead of saving each “field” as a separate entry, we save all fields as one serialized object. This significantly speeds up the database (we only need to ping the database once instead of for each field), allows meta to be “pluggable” (so other devs and even you can easily add custom fields without needing to edit HD Quiz), and allows for automatic sanitization (which will save you a ton of worry and time). But how do you construct this new “mega field”?

As I previously suggested, I suggest opening your browser console (this can be done in most browsers by pressing F12). With the console open, try creating a new question. You should see a full JavaScript object show up. This object is what you will need to recreate on your front end when one of your users submits their data. Here is the order that things happen. You can also take a look at ./includes/meta.php and a function called hdq_get_question_meta. This function includes a JSON string that represents the field data as well.

  1. User submits a new question. Using javascript, you grab their details and create the javascript object.
  2. You send that object via ajax to a function called hdq_sanitize_fields. As long as your object is properly formatted, this function will automatically parse and sanitize the fields for you. This is SUPER important for security.
  3. Now that you have your clean data, it’s time to save it. Now you will send the data to a new function that is based off of the function hdq_save_question (you’ll want to keep most of the same code, except remove the NONCE and hdq_user_permission calls).


IMPORTANT NOTES: In your new function that actually saves question data, you’ll want to change 'post_status' => 'publish' to 'post_status' => 'draft' so that you can “approve” submitted questions.

I hope this writeup helps!

16 May 2020 — 07:02 support admin - Dylan

Thanks for the effort you put into writing this whole text. At first reading I didn’t understand exactly how I could create a quiz or a question from the front end. I will try again but I am not very optimistic. With the old version I was making a form, putting it on a page or a post and entering the fields ….. now the whole process is very difficult for me.
Thank you again for the amazing work and the willingness to help.

16 May 2020 — 07:29 thread author - maki

That’s essentially what you’re still doing! There are really only two differences. The first is that you no longer have to worry about cleaning and sanitizing the data yourself – the hdq_sanitize_fields function will do this for you. The second is that before you send the data off from the form, you should use Javascript to combine the field values into an object array. You can also do this in the backend with PHP, but it’s far quicker and easier to do it with JavaScript.

16 May 2020 — 07:34 support admin - Dylan

My first problem is that I can’t find the way to use the code to enter the values ​​(eg query, answers) needed for a query. If you have any other suggestions or suggestions using php I would love to hear it.

16 May 2020 — 07:54 thread author - maki

If you mean getting creating the JavaScript object from your form, this should help.

Let’s assume that you only have 6 fields on your form. All fields are simple text inputs, with exception to the last.

The first field has an ID question_name and is the question name/title. Fields 2 – 5 have IDs answer_1, answer_2answer_4. The sixth field is a number input called correct_answer – your users will enter the number that corresponds to the correct answer (example: if answer_2 is the correct answer, then the user would enter 2 in this field).

Now for the javascript.

In javascript, you can get the value of any of these fields by doing this:

document.getElementById("input ID goes here").value;

so if you wanted to get the question title…

let question_name = document.getElementById("question_name").value;

So once you have all of your field values, you need to create a new variable and format it like the previous examples I gave.

example of simple version (you will need to extend this to include all of the fields – once again, use the console to see the full version when you save a question in the backend)

let question = {
    title: {
        type: "title",
        value: question_title
    selected: {
        type: "correct",
        value: [correct_answer]
    answers: {
        type: "answers",
        value: [
              answer: answer_1,
              image: ""
              answer: answer_2,
              image: ""
              answer: answer_3,
              image: ""
              answer: answer_4,
              image: ""

Once you’ve done something like above, the rest is easy. You can send that data to a custom PHP function via ajax to wp-ajax.php (as always take a look at HD Quiz itself to see how to best do this), and use that function to send the data to be sanitized. Once sanitized, you can then safly save the data.

I wish I could help more, but as I said, this is not some quick and easy thing to do – at least not to do in a way that wouldn’t get your site hacked in about 5 minutes haha. Other than the JavaScript above which I can see being difficult if you don’t know javascript, this version of HD Quiz actually makes something like this much easier than before, since all of the heavy liftings can be automated by HD Quiz itself now.

If you still need help after taking the time to read through all of this, then the only suggestions I can make are ones you may not like. You can hire a developer to code this for you (any WP dev should have no problems doing this – especially if you show them this thread) or even get me to do it if you have the budget! You can also use this as an excuse to expand your own coding/development skills as well (always a great thing!)

All the best and good luck!

16 May 2020 — 08:13 support admin - Dylan

I would appreciate it if you could suggest me a solution without using javascript (for which I don’t know programming). Maybe if it’s only done with php code, you can help me create the input form for the query and save it.

16 May 2020 — 11:01 thread author - maki

For PHP, you basically just do the same thing – but in PHP syntax. So for example, once you submit the form data

$data = array(); $data["title"]["type"] = "title"; $data["title"]["value"] = $_POST["question_title"];

$data["question_type"]["type"] = "select"; $data["question_type"]["value"] = "multiple_choice_text";

$data["selected"]["type"] = "correct"; $data["selected"]["value"] = array($_POST["correct"]);

$answers = array(); array_push($answers, array("answer" => $_POST["answer_1"], "image" => "")); array_push($answers, array("answer" => $_POST["answer_2"], "image" => "")); array_push($answers, array("answer" => $_POST["answer_3"], "image" => "")); array_push($answers, array("answer" => $_POST["answer_4"], "image" => ""));

$data["answers"]["type"] = "answers"; $data["answers"]["value"] = $answers;

// ... continue to build out the entire array // the above is assuming that the values are submitted from the form // but you will still want to set other options as well take a look at ./tools/data_upgrade.php for list of fields

// send all of the data to the HD Quiz sanitize function // this cleans the data to make sure it is safe to save $data = hdq_sanitize_fields($data);

// if the data sanitizes and validates without issue, we can now create the question

$total = wp_count_posts('post_type_questionna'); $total = $total->publish;

$post_information = array( 'post_title' => $data["title"]["value"], 'post_content' => '', // post_content is required, so we leave blank 'post_type' => 'post_type_questionna', 'post_status' => 'draft', // set to draft so that you can manually approve 'menu_order' => $total // always set as the last question of the quiz ); $data["question_id"]["type"] = "integer"; $data["question_id"]["value"] = wp_insert_post($post_information);

// now that the question has been created, we can save our custom fields // save the data to the question $hdq_id is the ID of the question update_post_meta($hdq_id, "question_data", $data);

16 May 2020 — 12:10 support admin - Dylan

hello i’m back
After days of trying to create what we discussed in previous posts, I admit that I was not able to do it. The only solution is if you can give me each file ready and how I need to handle it so that I can achieve what I asked for. In any case, thank you once again for your support and help.

23 May 2020 — 13:00 thread author - maki

If you are enjoying HD Quiz please leave a review here on the official WordPress.org page. HD Quiz is developed by me, just some dude, and is supported and available for free. It may seem dumb, but truly nothing makes me happier than knowing that people are using and loving HD Quiz and my hard work.

This thread has either been marked as complete or has been automatically closed due to inactivity.