Quiz support in the Mobile app

From MoodleDocs
Quiz support in the Mobile app
Project state In Progress
Tracker issue https://tracker.moodle.org/browse/MOBILE-921
Discussion https://moodle.org/mod/forum/view.php?id=7798
Assignee {{{assignee}}}


The quiz module and the question bank are two of the most sophisticated and complex features in Moodle (quizzes are not supported neither in BBLearn app and Canvas LMS app due to their complexity). They are also the most commonly used features in courses.

Quiz support in the Mobile app is one of the most requested features by users; in this document I’m going to do a brief analysis about the implications of adding basic support to quizzes in the app.

The main purpose of this document is to estimate the effort in man-hour for developing such feature.

Basically, the quiz module allows the teacher to build question tests. A quiz is a set of questions that a user has to answer. The quiz module has advanced features like multiple attempts, time limits, submission grace periods, question shuffling, question paging, possible answers shuffling, question behaviors (like adaptive mode, manual grading, interactive), delays between attempts, force browse security, etc…

Moodle comes with 10 different question types, (description, essay, multi choice, match, truefalse, shortanswer, numerical, calculated, calculatedsimple, calculatedmultiple, close) (Note that for Moodle 3.0 new question types had been added), and it allows additional types via plugins.

Simple question types use standard HTML and complex ones may use Javascript, Java Applets or HTML 5 elements (like canvas, etc..)

It will be very complex implement support for all the features of this module, so the initial approach should be to implement most-cases support for quizzes. This means that the app will check if a quiz is compatible or not based on the quiz settings and the questions used.

Options to be supported:

  • Open and close quiz dates
  • Multiple attempts and grading methods
  • Pagination
  • Require password
  • Require network address
  • Time limit
  • Submission grace period
  • Navigation method
  • Shuffle questions
  • Shuffle within questions
  • Each attempt builds on the last
  • Question behaviors: Adaptive mode and Adaptive mode (no penalties), manual grading, interactive mode, immediate feedback, Deferred feedback or Immediate feedback with Certainty-based marking (CBM)

Attempts restrictions:

  • Delays between attempts

Options initially not supported:

  • Browser security

Only quizzes with the options listed in the first section will be supported. The question types included in the quiz will be checked too, only quizzes including the following Moodle question types will be initially supported:

  • calculated
  • calculatedsimple
  • calculatedmulti
  • description
  • essay
  • gapselect
  • match
  • multichoice
  • numerical
  • shortanswer
  • truefalse
  • ddimageortext
  • ddmarker
  • ddwtos

Only Moodle core quiz access rules and question behaviors will be supported, quiz with non-core questions or questions behaviors won't be supported

Moodle Web Services

The app needs to retrieve all the quiz related information from the Moodle site, this means that we will need new Web Services for the quiz module.


This Web Service will return all the quizzes a student can see in a course, including basic information like the number of attempts allowed, the grading method, quiz availability dates, if the quiz requires password, etc..

The information is user-specific, quiz overrides applies to the user doing the Web Service call.

All the information returned by the WS will be data that the user can see in the web interface.


Returns the list of attempts for the user and their status (finished, inprogress, overdue, abandoned) See: https://github.com/moodle/moodle/blob/master/mod/quiz/attemptlib.php#L437


Return capabilities information and the quiz_access_manager::prevent_access / prevent_new_attempt / get_preflight_check_for information.

It also returns information about the different question types (or potential question types for random quizzes) used.


Starts a new attempt, this WS will return the attempt id and additional information if required. If password is required (or another preflighdata) it should be passed as parameter to this function. (like startattempt.php)

In Moodle this is done by startattempt.php.


After starting or resuming an attempt, this WS will return a question page information including the questions (see questions rendering and interchange data format section for information about the questions format). It also returns attempt layout, next page number, basic information about each quiz question, etc.. (like attempt.php).


This is very similar to what the current autosave.ajax.php does, it will save the current quiz status and question answers. This will be called periodically (based on Moodle site global quiz settings).


This will process an attempt page (like processattempt.php), it will be used on page change and for finishing the attempt. It will be automatically called by the quiz timer (if enabled).


For updating the flag status of a question

Other Web Services for displaying user data, or for getting required data


Get the best user grade on a finished quiz. This is the best grade in the quiz, not the one in the gradebook.


Combines the review options from a number of different quiz attempts.


Return the review information for the given closed attempt (like review.php).


Return the in progress attempt summary information (like summary.php).


To trigger the quiz course module viewed event and completion.


To trigger the attempt viewed event and to set the current page in the attempt.


To trigger the attempt summary viewed event.


To trigger the attempt reviewed event.

Moodle API changes required

Avoid code duplication

In order to avoid code duplication, some parts of the code from startattempt.php, attempt.php, proccessattempt.php will be moved to functions in local mobile.

Event triggering

The mobile app needs to trigger events when the user view/open specific pages, this will require to create new specific web services for triggering events that will require to move the lines that triggers an event to functions (to avoid code duplication again).

External data formatting

Some quiz API functions like quiz_feedback_for_grade returns text formatted using format_text, external functions cannot use this methods (they must use the external_format_text and external_format_string implementations) because of this, we'll need to modify some core functions, in this specific case, we create a new function quiz_feedback_record_for_grade that will return the plain record (this function will be used by quiz_feedback_for_grade)

Prefligh data checking

We need a new function in mod/quiz/accessmanager.php to run a set of preflight checks for the given data (like run_preflight_checks). This was actually done inside every access rule (usually in the form validation)

Additional helper methods

Some additional helper methods in classes will be necessary, like a new get_question_type_class_name in the attempt class. or question_get_qtypes_in_categories in the questionlib, to get all the different types of questions present in a given category (this will use in quizzes using random questions, we need to know in advance the potential question types to check if they are supported)

Rendering and interchange data format.

One of the critical aspects of this development is to decide how the questions information will be exported via Web Services, there are two main alternatives:

Export the HTML as it’s generated by the questions renderers


  • We just need to style the HTML, no need to generate it in the app.
  • Questions includes the corrects ids and form elements needed by the save_attempt logic (that relies in _POST data)
  • All the inmediate feedback, and behaviour hooks is supported.
  • Questions review code is supported.
  • Images and attachments can be handled nicely
  • Potentially, any question type that does not rely in Javascript would be compatible
  • It will support custom rendering via the theme


The method should return if the question uses plain HTML (standard html form elements), javascript, java applets, flash... "is_plain_HTML"

Export the question using a question export format (GIFT or Moodle XML)


  • Clean data, without formatting


  • Limited types of question supported, contributes questions types are not going to be supported never
  • It misses questions files attachments
  • We'd need to duplicate a lot of logic that is already done in Moodle for creating the input fields with correct identifiers
  • We'd need to handle manually all the behaviour plugins (will need web services for each one, and new API functions..)
  • We'd need to create new API functionss for exporting additional data, like the javascript structures passed to complex questions like the D&D ones

Question types supported by Moodle XML format (export):

description, essay, multi choice, match, truefalse, shortanswer, numerical, calculated, calculatedsimple, calculatedmulti

Question types supported by GIFT format (export):

description, essay, multi choice, match, truefalse, shortanswer, numerical

Final decision

So basically we opted for the option of retrieving all the data rendered, this seems to best choice right now.

Common use case

  • As a student I open the app, log in to a site.
  • Browse to a course.
  • Select display the course contents.
  • Open a quiz activity.
  • The app checks if the quiz is compatible via the mod_quiz_get_course_quizzes and the information from mod_quiz_get_access_information (for example, if the app detects that a non-supported contrib question type is used, it will notify the user to do the quiz in the web version).
  • If the quiz is compatible and is open in time (and the rest of quiz restrictions are ok), the app downloads the users attempts via mod_quiz_start_get_attempts.
  • If there is an incomplete attempt, the app continues the attempt.
  • If there aren’t incomplete attempts and the user can do additional attempts, then the app starts a new attempt.
  • The app then downloads the current page questions via the function mod_quiz_get_attempt_data.
  • The app periodically saves the attempts data via the mod_quiz_save_attempt function (that will do the same that the current autosave.ajax.php).
  • When the user switch between pages, data is saved by mod_quiz_process_attempt. The new page questions are retrieved using mod_quiz_get_attempt_data.
  • When the user finishes the attempt, the mod_quiz_finish_attempt function is called using the finish special parameter.
  • During all the user quiz interactions, all the events are recorded in Moodle via the mod_quiz_view_* functions

Offline support

We'll allow users to download a quiz for offline usage. If the quiz is suitable for offline usage (see quiz restrictions) the user will see the cloud - download option (same that for SCORM or any resource) to attempt it while offline.

Usage considerations

  • By default quiz won't be able to be played offline. It's a new setting in a new access rule.
  • If the user wants to download a quiz for offline usage, we must create an initial empty attempt because we need an attemptid for retrieving the list of questions and ordering. This means that clicking the download button will create a new attempt if the user doesn't have any or the last attempt is finished.
  • You cannot start a new offline attempt if a previous offline attempt is not synchronized (because the previous offline attempt will be in in-progress status).
  • If the quiz has an start date, the quiz can only be downloaded for offline after the start date.
  • If the quiz has a finish date it must be submitted (synchronized) before the finish date.
  • If the user is doing an offline attempt and he submit the responses (when he is not connected to Internet) we’ll display a message like “Your responses couldn’t be sent to the Moodle site. We’ll try to send them again once you are connected to Internet again...”. In this case, in the user attempts list we’ll display the attempt as Finished but not submitted to the site. The user won’t be able to edit his responses or start new attempts.
  • If via Moodle we detect that the user started or continued a new attempt using the app, everytime he continues that attempt in Moodle it will be noticed asking him to be sure to don't have unsaved work in his mobile devices.

Quiz restrictions

A quiz will be available for offline usage only if:

  • It doesn’t require a network address.
  • The question behavior is deferred feedback with or without CBM.
  • It doesn’t require a time limit.


We'll try to synchronize every time the user goes from offline to online (even if the user is not attempting the quiz). It will be done on a question-by-question basis.

Conflict resolution

This should be done on a question-by-question basis, each question will be synchronized depending on the sequencechecknumber and last action time.

Required changes

Moodle core: Issue MDL-53870, changes required:

  • Create a new access rule offlineattempts, this access rule will come with a new setting (new allowofflineattempts field in the quiz table).
  • Create a new field in the quiz_attempts table (timemodifiedoffline) that will be updated exclusively by external systems like the mobile app.
  • Return new question attempts data via Web Services: sequencecheck, lastactiontime and hasautosavedstep.
  • Return the quiz password hashed using SHA1 to allow quiz protected passwords.

Mobile app: Issues MOBILE-1529, MOBILE-1540, MOBILE-1543

  • Support quiz prefetch (all the question data and attached images).
  • Allow question answers storage in the app.
  • Implement the synchronization process.
  • Changes in the UI (to display the synchronization status for the user).

See also