Backup 2.0 for developers
Template:Development:Backup 2.0Moodle 2.0
This page tries to explain, from a development perspective, how to implement the backup feature for various Moodle 2.x plugins, mainly, modules and blocks.
Note that, at the time of writing this, the backup & restore subsystem itself is under development, so still there are some missing bits, specially about the way to handle subplugins (question types, data fields...) under the new backup infrastructure, so any module using such artifacts, like data, assignment, quiz, workshop, aren't good candidates right now. This will be addressed (and this Docs updated) once we have determined how each subplugin is expected to work (from a DB / backup perspective).
Everything in backup is about tasks and steps (see Backup 2.0 general architecture for more information), all them conforming one backup plan. Each module instance and each block instance will be backup by one backup task instance that is, basically, one collection of backup steps. How steps are organized within the task will dictate to the backup system what to do and in which order.
Another important point is that Moodle backup 2.0, supports multiple backup formats ("moodle2", "imscc"...) each one having its own tasks/steps, completely unrelated between them. In any case, for now, we are focusing all the explanations below in the "moodle2" format, that is the one required in order to keep any module/block transportable between Moodle instances without any loss of data. Surely, for the rest of formats, we'll end with other documents describing them, as far as each one can have its own particularities.
Talking about backup steps we must differentiate two type of steps:
- Execution steps: That, simply, execute arbitrary PHP code. They are useful to prepare different structures, create directories, whatever have to be done not involving the generation of XML files. Normally you won't need them.
- Structure steps: That, using one PHP API (detailed below) define completely the XML structure to be exported and its contents. Hopefully, "normal" modules only will have to use one step of this type in order to have the backup functionality 100% implemented.
Said that, in the next steps we are going through all the steps necessary to create the backup of one simple module and one block, in order to get all the possibilities covered.
How to backup one module
For this section, we have selected one simple module (choice) that requires practically all the backup "machinery" to be used, so it will get explained as we progress in the development. The only point not covered here are the "subplugin" facilities, covered later in a separate section.
In order to achieve the backup implementation for the module, some prerequisites should be fulfilled. They are just recommendations but, specially while getting used to backup, it's good to follow them. Let's see:
- Learn about the module. If you aren't the creator of the module, spend some time playing with the module, creating and using it, exploring each one of its functionalities. By doing this you will end with some "real" data in the module instances that will be really useful when testing / debugging how the module backup is being generated.
- Draw one schema of the module DB structures. While you are playing with the module, look continuously to the DB, how records are saved and which are the relations between the module's tables. As far a backup is, basically, one "selective dump" of those tables, knowing the maximum about them is highly recommended. At the end, you must end with one tree structure will be the basis for the generated XML file.
- Annotate which tables contain user-related info and which ones don't. One of the core functionalities that must be present on each module is the ability to include user related information or skipping it, so you will need that information later.
Tip: If the module already existed before Moodle 2.0, it can be a good idea to take a look to its 1.9 backuplib.php file, as far as the structure is already defined there and can help to understand the organization better and, at the same time, keeping the XML structure as similar as possible, that will, definitively, make things easier when converting 1.9 backup files to the new backup 2.0 format.
Note: It's important to highlight that the structure schema, once decided, should be as stable as possible along the time, because any change in the structure makes restore really way-more-more complex to be implemented. There isn't problems adding / deleting fields, nor adding new elements to the structure. But the structure (tree) itself must persist as stable as possible, so please, be careful when deciding it.
So, applying these pre-requisites to our candidate module (choice), here it's the corresponding schema. We'll use it along the whole process.
In the schema, you must try to put as much information as possible, so that will produce the coding process later to be quicker and easier while keeping the final results free from errors and missing bits. So, once more, don't start coding immediately, instead spend some time with the requisites above, understanding how the module works and designing the final structure that represents it better.
The tree on the left shows the ER/DB structure of the choice module, where one choice have one or more options and each option is answered by users one or more times (note: ignore cardinality accuracy in the previous phrase). And that's the best schema representing the structure of the module, with each element properly nested so, we won't have any problem with restore as far as the order required by restore (1, 2, 3) are naturally given. Cool, but follow reading… it will surprise you!
Instead we are going to use the (complete this time) diagram below. See the rationale about that after the image.