General developer forum

Not getting response data from question engine

 
Picture of Richard Jones
Not getting response data from question engine
 

Hello

Trying to complete a simple filter that will insert a question into Moodle text.  Eventually planning to implement this in an iframe as discussed here:  https://moodle.org/mod/forum/discuss.php?d=332254.

However, while I am able to show the question, I'm not able to recover the result using code like this:

// Get and decrypt question id (note, encrypted to text).
$enid = required_param('id', PARAM_TEXT); 
$id = (int) filter_simplequestion_decrypt($enid, $key);
// Get our context and course module id
$courseid = required_param('courseid', PARAM_INT);
require_login($courseid);
$context = context_course::instance($courseid);
$preview_url = get_preview_url($enid, $courseid);
$PAGE->set_context($context);
$PAGE->set_url($preview_url); 
// Load the question
$question = question_bank::load_question($id);
question_require_capability_on($question, 'view');  
// Question display options 
$maxvariant = min($question->get_num_variants(), QUESTION_PREVIEW_MAX_VARIANTS);
$options = get_display_options($maxvariant);
$quba = question_engine::make_questions_usage_by_activity('filter_simplequestion', $context);
$qubaid = $quba->get_id();
if (data_submitted() && confirm_sesskey()) {
  // Process the response
  $timenow = time();
  $transaction = $DB->start_delegated_transaction();
  question_engine::load_questions_usage_by_activity($qubaid);
  $quba->process_all_actions($timenow);
  question_engine::save_questions_usage_by_activity($quba);
  $transaction->allow_commit();
} else {
  // Setup the question to be displayed                     
  $quba->set_preferred_behaviour('immediatefeedback');
  $slot = $quba->add_question($question, 0);
  $quba->start_question($slot);
  
  $transaction = $DB->start_delegated_transaction();
  question_engine::save_questions_usage_by_activity($quba);
  $transaction->allow_commit();
}

(full filter code is here: https://github.com/richardjonesnz/moodle_filter_simplequestion).

The error is in reading from the database:

  • line 486 of /lib/dml/moodle_database.php: dml_read_exception thrown
  • line 242 of /lib/dml/pgsql_native_moodle_database.php: call to moodle_database->query_end()
  • line 738 of /lib/dml/pgsql_native_moodle_database.php: call to pgsql_native_moodle_database->query_end()
  • line 463 of /question/engine/datalib.php: call to pgsql_native_moodle_database->get_recordset_sql()
  • line 84 of /question/engine/lib.php: call to question_engine_data_mapper->load_questions_usage_by_activity()
  • line 75 of /filter/simplequestion/showquestion.php: call to question_engine::load_questions_usage_by_activity()

Tail end of sql error:

FROM mdl_question_usages quba
LEFT JOIN mdl_question_attempts qa ON qa.questionusageid = quba.id
LEFT JOIN mdl_question_attempt_steps qas ON qas.questionattemptid = qa.id
LEFT JOIN mdl_question_attempt_step_data qasd ON qasd.attemptstepid = qas.id
WHERE
quba.id = $1
ORDER BY
qa.slot,
qas.sequencenumber
[array (
0 => 'j5nTmQceGk',
)]
Error code: dmlreadexception

I think I'm missing a question attempt somewhere in here but I'm not finding that clear from the question engine documentation. 

I've been trying to nut this out for a week with little success, any hints on where to look next or help appreciated.

Thanks.


 
Average of ratings: -
Tim at Lone Pine Koala Sanctuary
Re: Not getting response data from question engine
Core developersDocumentation writersParticularly helpful MoodlersPlugin developers

The mistake you are making is that you are not tracking the $qubaid correctly. You create a new quba, and hence a new id, both when someone goes to start the question, and then again after they have submitted the answers. Obviously, when you are processing the answers, you need to re-load the same quba that you created before.

If you want to see some working code that does basically the same as what you are trying to do, look at question/preview.php. The key bits are probably:

And, of course, https://docs.moodle.org/dev/Using_the_question_engine_from_module is the page of developer docs that explains what is going on.

 
Average of ratings: Useful (1)
Picture of Richard Jones
Re: Not getting response data from question engine
 

Thanks Tim

Yes, I started with preview.php as the base but over-simplified it.  Forcing immediatefeedback dispenses with any need for the control form (save, fill, submit etc).

Now that's working fine for admins and students except for the pluginfile issue as discussed in the previous thread. The pluginfile src url is present on inspection of the page but does not display the image for students. 


 
Average of ratings: -
Tim at Lone Pine Koala Sanctuary
Re: Not getting response data from question engine
Core developersDocumentation writersParticularly helpful MoodlersPlugin developers

I'm sorry, I can't find the previous thread you refer to.

The most likely thing that would be wrong would be missing is the function filter_simplequestion_question_pluginfile defined in a lib.php file in your plugin. There are two examples in Moodle core: in the quiz https://github.com/moodle/moodle/blob/master/mod/quiz/lib.php#L1921 and in question preview: https://github.com/moodle/moodle/blob/master/question/previewlib.php#L235

 
Average of ratings: -
Picture of Richard Jones
Re: Not getting response data from question engine
 

Hi Tim

It was this one: https://moodle.org/mod/forum/discuss.php?d=332254.

The same issue is referred to but unfortunately Peter never came back with the code (and his github projects are private sadly) so I'll give it a go. 

The key code in preview.php is here:

//$quba = question_engine::make_questions_usage_by_activity(
//        'filter_simplequestion', $context);
$quba = question_engine::make_questions_usage_by_activity(
            'core_question_preview', context_user::instance($USER->id)); 

I can get the questions within the context of the plugin but the existing pluginfile code for the preview expects the user context.  My knowledge in this area is a work in progress.

Thanks for the links.

Richard

 
Average of ratings: -
Tim at Lone Pine Koala Sanctuary
Re: Not getting response data from question engine
Core developersDocumentation writersParticularly helpful MoodlersPlugin developers

I can't really  remember what the context of the question usage is used for. My guess is not very much, so it does not matter too much. (To remember, I would have to read the code, and I am not minded to do that right now.)

I expect that, when a particular context is deleted, we probably delete all the related attempts.

I think that, for your plugin, using the user context is probably an OK choice.

Note that, for question preview, there is a scheduled task to clean up old attempts that are no longer needed. Eventually, you will probably want to do the same.

 
Average of ratings: -
Picture of Richard Jones
Re: Not getting response data from question engine
 

That's OK Tim, the code is well commented, probably by you.

Using the user context is actually why the plugin files are showing for admins and not students as the preview library pluginfile function expects someone with the 'use' capability to be using it.  On my reading anyway.

Yes, I saw that and checked the table, it has a lot of entries in it from my testing.

Thanks again for your help.  I have a couple of actually paid things to do but will certainly re-visit this soon.


 
Average of ratings: -
Picture of Richard Jones
Re: Not getting response data from question engine
 

So, thanks for your help Tim, there is a working beta version at github.  Some improvements are still possible though, as noted in the readme.

I have a tracker for this. https://tracker.moodle.org/browse/CONTRIB-7081.

Suggestions for improvements always welcome.


 
Average of ratings: -