Quiz support in the Mobile app
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}}} |
Introduction
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.
mod_quiz_get_quizzes_by_courses:
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.
mod_quiz_get_user_attempts
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
mod_quiz_get_acess_information
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.
mod_quiz_start_attempt
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.
mod_quiz_get_attempt_data
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).
mod_quiz_save_attempt
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).
mod_quiz_process_attempt
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).
core_question_update_flag
For updating the flag status of a question
Other Web Services for displaying user data, or for getting required data
mod_quiz_get_user_best_grade
Get the best user grade on a finished quiz. This is the best grade in the quiz, not the one in the gradebook.
mod_quiz_get_combined_review_options
Combines the review options from a number of different quiz attempts.
mod_quiz_get_attempt_review
Return the review information for the given closed attempt (like review.php).
mod_quiz_get_attempt_summary
Return the in progress attempt summary information (like summary.php).
mod_quiz_view_quiz
To trigger the quiz course module viewed event and completion.
mod_quiz_view_attempt
To trigger the attempt viewed event and to set the current page in the attempt.
mod_quiz_view_attempt_summary
To trigger the attempt summary viewed event.
mod_quiz_view_attempt_review
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
Pros
- 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
Cons
- The questions includes markup, with classes etc… They can collide with the app styles
- Javascript may be included in the response.
- We must add a new metadata method to qtypes.Like: https://github.com/moodle/moodle/blob/master/question/type/questiontypebase.php#L104
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)
Pros
- Clean data, without formatting
Cons
- 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.
Synchronization
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).