Plan to Improve Flexibility of Question Category Sharing and Permissions

Jump to: navigation, search

Status of this Plan

This plan has been implemented and code is now in Moodle 1.9. See background here on how the plan evolved : forum discussion starting here with new heading 'Plan to Improve Flexibility of Question Category Sharing and Permissions'

More user friendly doc

You can find a more user friendly doc on the changes in the question engine for 1.9 here Question_Engine_Changes_in_Moodle_1.9



I plan along the way before making changes to the question bank code to add plenty of commenting in the approved Moodle style and in line with this info on Quiz_developer_docs#Code_documentation. Will add ??? where I'm not sure of something and generally add as many inline and phpdoc comments to the code as seem useful. I think Moodle guideline suggest that there are never to many comments in code, I'll try to keep the comments succinct. This I hope along the way will be a good way for me to learn about how the code works myself and cement the concepts in my own mind.

Rest of Tasks in Plan Are In The Order I Intend to Tackle Them

Commenting will be something I'll do throughout my work as I delve into the code and add new code. The rest of tasks in my plan below are in roughly the order in which I intend to tackle them.

Before Branch Changes to HEAD

I've made these changes before I branched the question bank code to work on a development branch.

Convert the Current edit categories table to a UL

Will convert the current edit categories table to an UL. This will be one step towards the new interface with several headings and lists of categories below each context heading. I won't add the context headings at this stage just change the current table to a UL.

Remove the Question Bank Reliance on SESSION

Will work on removing the use of SESSION to keep track of what category should be displayed and pass category and other params from page to page as url params or as hidden fields for buttons.

After Branching

Seperate Questions into Different Category Hierarchies in Different Context Levels

Remove 'publish' field from question_categories table 'course' field will become 'contextid' and will be of INT type pointing to the 'context' table.

Calculate equivalent context

Contents of the new context table will depend on the old contents of 'publish' and 'course' if publish is 1 then we make the context the site context. If it is 0 then we make the context the context for the course indicated in the 'course' field.

Change in How Categories Are Shared

Previously you could share a category anywhere in your Course's question bank category hierarchy at the site level. Now we have decided that we'll have seperate hierarchies for categories at each context level. So we need code on db upgrade to check that all parent categories referred to in the question_categories 'parent' field are in the same context. If they are not then this category becomes a new top level category.

So if a question category hierarchy in a course is as below :

  • Default
    • Science
      • Physics (shared)
        • Momentum and Dynamics

The Physics course will get moved to the site context since it is shared and the question category hierarchies will then be as follows :

Course Level

  • Default
    • Science
      • Momentum and Dynamics

Site Level

  • Physics

If a childs parent is gone then it get's put in the grandparent category, if no grandparent, then grand grand parent etc. We'll search up the category hierarchy till we reach a category that is still in the same context level or we reach the top level and use that as a parent.

When changing the tree, we'll preserve the existing ordering as defined by the sortorder fields.

Random Questions Issue

The problem here is that if there was a random question in category Science or Physics which had the 'Display questions from sub-categories too' turned on, then before or after the upgrade, it will behave differently. I don't know what the best solution to this is.Tim Hunt 07:49, 21 March 2007 (CDT)
See discussion of this issue starting here.
Proposed Solution

We'll write an admin report (the 'Is your question bank ready for Moodle 1.9?' report) and check that in to the 1.8 and 1.7 stable branches. That report performs the same logic on your site as the upgrade would, and lists all the categories that would cause a problem if you upgraded now. This report can include lots of explanatory text, and have links to go and edit those categories manually, so people can easily tweak things by hand before upgrading if they want to. We can then point people to that report in the release notes.

The first steps in the db upgrade should proceed as follows :

  1. Delete all random questions in the question bank that are not included in a quiz before upgrade. This should be safe. These questions have somehow become orphans and shouldn't be in the question bank anyway.
  2. Then we work through all the category trees in the site, starting at the top, and every time we find a category with random questions picking from subcategories, we set all child categories to have the same published status as that one. We log the changes we make so they can be reviewed later and print a warning during the upgrade process.

Edit Categories Page

Add Headings to Edit Categories Page for Each Context Level

  • Will add headings to edit categories page and below each heading there will be a list of categories in that context. Edit Categories page will then have the structure as shown here
  • The contexts available depend on where you are editing the categories from. Thus in one course you only see that course's context, any parent course categories contexts and the site context. When in the site context you only see the site context.
  • Order of listed contexts is most specific to least specific. Questions only for this module, for this course, for Course Categories, for Site.

Add Up / Down Action Buttons

These will work as discussed here - I like the first option and not the alternative I discuss.

Question Bank Page

  • New Question Category selection box with contexts as OPTGROUPS. Something like below. Only available categories are shown ie. only the parent contexts of the current context to which the user has usequestions capability.
  • Make sure indentation of category hierarchy works properly.
  • Add count of questions in brackets after each category.
  • Order of listed contexts is most specific to least specific. Questions only for this module, for this course, for Course Categories, for Site.

Question Adding / Editing Forms

  • New Question Category selection box with contexts as OPTGROUPS. Same as in Question bank page above.
  • The category dropdown menus here, and on all other pages, are all produced by the question_category_options function in questionlib.php, so we just have to edit that function.

Add code to cope with detecting and moving associated files

Need code to check for files in the current course / at the site level that need to be moved when a question is moved. Questions can be moved either :

  • when a whole category and it's child categories are moved between contexts on the Edit Category page either :
    • using the arrows on the main category listing page
    • or in the update category form.
  • or when an individual question is moved in the edit question form by using the select box there.

The default question type object will have a new method to deal with things that need doing when a question is removed default_questiontype::move_to_category() this can be overriden by child classes for extra specific stuff to be done for special question types.

We will check for linked course files and site files in question text and other text using a regular expression. List associated files for user and allow user the choice to move files to the same context as the question. So if a question is shared at the :

  • course level or module level associated files will be stored in the course files area.
  • course category or site level associated files will be stored in the site files area.

Add fields to question table - created, modified, createdby and modifiedby

Add fields to the question table to track who created and modified a question and when. Old questions will all have createdby / modifiedby set to 0 initially which will mean the creator / modifier is unknown. If a question has an unknown owner then only capabilities all and not mine will apply.

Add code to import and add/edit question forms to insert / update created, modified, createdby and modifiedby fields.

Add Permissions to Roles and Permissions System

Will extend the capabilities of the permissions system to differentiate between a question that is owned by the editor and a question not owned by the editor.

These capability would be tested at the module / course / course category / system level depending on what context the category / questions the user is attempting to perform actions on.


I propose capabilities as below but there is some debate as to how granular these permissions should be. In the plans mentioned in the linked discussion forum I mention differentiating also between a question created by someone in the same group as you compared to someone not, this won't be dealt with yet at this stage.


Allows the management of category hierarchies ie. creating, editing and moving categories. (The Categories editing page would be shown if the user has permission to edit the hierarchy in the current context or any parent context.)


Controls :

  • the adding of questions to a category.
  • the import of questions. I propose getting rid of the seperate import capability. I think the capabilities should be about what you can do with questions and import is just one way to add a question/questions to a question bank.

This capability would be tested at the module / course / course category / system level depending on the where the user is attempting to create a question.

mine / all

All other capabilities are split into two types mine or all. So the permissions for what you can do with a question depend on whether the question was created by you or someone else.

  • 'all' means the capability allows you to act on all questions, your own questions included (so 'mine' is not tested if you have 'all').
  • 'mine' means only questions created by you.
moodle/question:editmine / editall

Controls whether a user can :

  • edit their own / someone else's question.
  • delete their own / someone else's question.
moodle/question:viewmine / viewall

Controls whether a user can see all of their own / someone else's question. This is different to 'use' which only allows you to preview a question. If you can 'view' that means you can see all the questions answers and it means you can :

  • save as new question
  • export questions in the category
moodle/question:usemine / useall

Controls whether a user can :

  • include their own / someone else's question in an activity (currently only the quiz activity).
  • preview a question

moodle/question:movemine / moveall

Controls moving of questions to another category. You must have permission to do this both in the context you are moving the question from and you must have the 'add' capability in the context you are moving the question to.


Need a database upgrade script that gives appropriate new-style capabilities to roles based on the old role definition.

Roles that previously had the manage capability will have :

  • moodle/question:add
  • moodle/question:editmine / editall
  • moodle/question:viewmine / viewall
  • moodle/question:usemine / useall
  • moodle/question:movemine / moveall

This will give them the same permissions as they had previously.

Modify Restore and Backup

  • Make restore and backup deal with new createdby, created etc fields and contextid in categories.
  • We should support newer type questions db backup restoration as well as supporting restore of older backups.
  • Restoring questions will continue to be controlled by moodle/site:backup and moodle/site:restore and capabilities.

Restoring older category hierarchies

Older question banks will be restored as owner unknown (createdby field set to 0).

The calculations to make changes in the structure of the db detailed here, will also apply when restoring older backups.

Which Questions Get Backed Up and Restored

This was discussed in thread 'want to have a way for students to be able to create and edit their own questions but not be able to access questions in the same course'.

  • Backup all questions in the course and module context levels.
  • Backup only questions and question categories in system and course category levels that are used by activities (currently only quiz) in the course.
  • Check backed up stamps to see if question already exists in any parent context. Question might exist in contexts site / course category and restored activities can use this question this is not dependent on user's permissions.
  • If the question doesn't already exist in module context or in a parent context (course, system etc). Restore will be to site / course category depending on add capability as well as restore capability in those contexts. If the user doesn't have capability to add questions to the system / course category level then questions are restored to the course (we won't test capabilities in course / module context since the user has course restore capability).

Admin Report Will be Backported to 1.7 and 1.8

An admin report to report recommended changes to rare cases of sharing questions which might cause problems in 1.9 will be added to 1.7 and 1.8 - backported from existing code that will have been developed on HEAD.