qbank_ type plugin: adding fields to question edit form

qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Number of replies: 9
Picture of Core developers
Hi: We are trying to add some custom fields (for University) to the question bank. We have used the customfields qbank plugin and it works.  We are using Moodle 4.1 and later.
But we are considering to refactor it into an isolated qbank_myfield plugin, to take advantage of some new possibilities in question bank management (for instance, bulk actions).  But going this route we can edit the value of the new field in the question bank page, but the new field do not appear in the question edit form, while proper customfields do appear there.

As far as I can see, in question/type/edit_question_form.php there is
        if (!\core\plugininfo\qbank::is_plugin_enabled('qbank_customfields')) {
            $this->customfieldpluginenabled = false;
        }
¿Are there any other hooks or callbacks in plugins of type qbank_xxxx to insert new editable fields in the question edit form, like customfields?
Average of ratings: -
In reply to Enrique Castro

Re: qbank_ type plugin: adding fields to question edit form

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
There is sort-of a hook for this, but the way it is done at the moment is really not great (sorry).

Near the top of the form there is this old-style callback https://github.com/moodle/moodle/blob/master/question/type/edit_question_form.php#L214-L226, but only if you are editing an existing question, and since it is right at the top, you cannot control where your new fields go in relation to the other fields.

Really, this callback should be customfields code is. Then the customfields (and probably the tags) bits of code should be moved into their respective plugins using that hook. The current callback should be deprecated.

I don't have time to do that right now, but would happily review a patch. At the very least, please could you make a tracker issue for this?
In reply to Tim Hunt

Re: qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Picture of Core developers
Hi Tim, If I understand you correctly, you are suggesting adding new general functionality to qbank_ type plugins, adding capacity to define and edit new fields in the question edit form ¿Is that correct?

I'ts have been a long time since I adeed something to core, and I'm not experienced with new coding style, but I can try. We could add a new abstract class available to be extended by qbank_ plugins. Something like 'question_edit_handler' .  This handler would have methods for:
  • instance_form_definition()
  • instance_form_before_set_data()
  • instance_form_definition_after_data()
  • instance_form_save()

And many of those currently defined in question/bank/customfields/classes/customfield/question_handler.php

Then, where code now calls for customfieldhandler, calling any handler for any qbank_ plugin having it. 

For instance, in question/type/edit_question_form.php calling

$plugins = \core_component::get_plugin_list_with_class('qbank', 'question_edit_handler', 'question_edit_handler.php');
foreach ($plugins as $componentname => $classname) {
    $handlerclass =  str_replace('_', '\', $componentname) . '\' . $classname;
    $this->qbankedithandlers[$componentname] = new $handlerclass();
    $this->qbankedithandlers[$componentname]->set_parent_context($this->categorycontext); // For question handler only.
    $this->qbankedithandlers[$componentname]->instance_form_definition($mform, empty($this->question->id) ? 0 : $this->question->id);
}

In question/bank/editquestion/question.php, adding something like

$plugins = \core_component::get_plugin_list_with_class('qbank', 'question_edit_handler', 'question_edit_handler.php');
foreach ($plugins as $componentname => $classname) {
    $handlerclass =  str_replace('_', '\', $componentname) . '\' . $classname;
    $qbankedithandlers[$componentname] = new $handlerclass();
    $qbankedithandlers[$componentname]->instance_form_before_set_data($toform);
}

And afterwards,

$qbankedithandlers[$componentname]->instance_form_save($fromform);

I can get some time to actually implement code along these lines, taking care of  loading/saving, editing form, backup/restore, export/import etc; if you really see such approach useful and deserves the time invested, with any hope to see it in core in 4.5 or so.

The main point is if we want qbank plugins to add new properties to questions themselves, individually, or remain as something that act on the bank, on questions listings.  Please, let me now if you think an effort in this direction would we useful and is in line with the ideas of the group promoting new qbank developments.  

In reply to Enrique Castro

Re: qbank_ type plugin: adding fields to question edit form

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
That is the approximately the design of what is required, but I dno't think tis is quite right.

Question bank plugins should not use get_plugin_list_with_class. The way it is supposed to work is that anything the plugin wants to do is declared in the plugin_features class, which is a subclass of plugin_features_base. So, we should probably add a get_question_edit_handler method there, which by default returns null, but which can return an instance of a subclass of question_edit_handler_base.

As you say, as well as the direct interactions with the form, you need to handle saving/loading, backup/restore, import/export etc. Backup/restore is already supported. Import/export was completely missed initally (oops!) and is being handled in MDL-78520 - but work there has stalled. Still, the propsed data_mapper there might be the best approach for handling the data, and being consistent with the proposed implementation there would probably be good.

Anyway, this is definitely something we need it Moodle, so any progress you can make towards it would be beneficial. And, I might be able to help, but only once I have finished developing my current priority.
In reply to Tim Hunt

Re: qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Picture of Core developers
Hi Tim, OK I will proceed in this direction.  I already wrote a draft class question_edit_handler_base this weekend.
I actually thought of adding a fourth feature to plugin_features class, but that was changing more files. But if we are talking about core, the concern is future use, simple, understandable and maintainable, not changes in current files.
I'll read  MDL-78520  to see what to do with export/import.   
In reply to Tim Hunt

Re: qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Picture of Core developers
Hi, so, I created an issue in moodle tracker MDL-80964 to address this. Thanks Tim for making clearer the ultimate purpose: a new way to manage question edit form from bank plugins.  I have created a patch along the lines indicated above. I've added the patch to MDL-80964 and is here too. 

In a separate issuse, MDL-78520, you propose having a general way for other code to inspect what features qbank plugins support or expose. So, I have added a helper get_all_qbank_plugin_features() working like init_plugins() method in the view class. 
I really hope you could review this ad help to push it into new releases. Please let me now any correction or improvement that you see appropriate. 
In reply to Tim Hunt

Re: qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Picture of Core developers

Hi, Hooks API has landed in moodle 4.4 Dev  . In comments for MDL-80964 Tim suggest that would be sensible to implement this in the same manner.  So, I've tried and is actually posiible and even cleaner (less modification of current core code). You may see an implementation of hooks for question_edit_form in issue  MDL-81170

Actually, this pathway allows any plugin type to extend the question edit form, adding new datafields, or managing the existing ones (freezing some, fort instance). The mechanism via plugin_features was exclusive for qbank type plugins, so less generic.

Please, have a look at   MDL-81170  and vote for integration.


In reply to Tim Hunt

Re: qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Picture of Core developers
Hi again,  course hooks have been modified in last weekly update to use new features in PHP8.1.
So, I've updated the patch here to have question edit form hooks written and used in the same style as course form hooks.  Please, see MDL-81170  for the newer version
In reply to Tim Hunt

Re: qbank_ type plugin: adding fields to question edit form

by Enrique Castro -
Picture of Core developers

Hi, time for new 4.5 release is coming. Please, may I ask to review  MDL-81170?.  I've added a demo repository with two brances, main (follogin moodle main) and edit-question-hook  contaning the proposed changes. Following Tim Hunt's recommendation, this proposal eliminates the especial entry points for question custom fields and are replaced by thesw new regular hooks.

If you whant to try, I'm including a patch file as attachment.