Every quiz system works differently and Drupal Quiz will never support the full union of features from every other system. Consequently, sometimes when a user imports a quiz, some of it will be lost.

To avoid this, we can store the source data for the import. This will have two benefits:

1) When the quiz module functionality or importer improves, the original is on file to be reimported. It also knows which questions were generated in the db from the earlier import and can update them.

2) In situations where the Quiz module is used as a question bank, users can download the original without the round-trip conversion in and out of the Drupal Quiz model.

I think the best way to implement this is a set of "importation" records. Each record would store information about the importation (such as time and user) along with the source data. The source data could go into a file or a blob. A blob would probably be easier to manage. Then each question item could have a "source" field which could be a user in the system or an importation record.

I don't know whether the importation record should be a proper node or just a db table. I would leave that up to the more experienced Drupalers to weigh in on.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mbutcher’s picture

If we are using QueryPath already, the QPCache module might provide what is needed to store imported records.

turadg’s picture

That's an interesting idea. Which importers use QueryPath now? The QTI importer?

Many of the question interchange formats aren't DOMs. GIFT has a highly esoteric syntax. Many of the importers are made using Moodle code (and maybe soon ATutor code) which my wouldn't work with QP I think.

Maybe we can adapt QPCache to a sort of QICache (Quiz import cache)?

mbutcher’s picture

We can certainly do whatever is most fitting for the project. The QPCache layer is pretty generic, so it should suite our purposes.

Matt

turadg’s picture

in IRC Sivaji pointed out the file_save_upload function. It puts uploads into a "files" table and they can be made permanent with file_set_status().

This table also records the user id of the uploader and a timestamp. This covers all the things I could think to store on the importation record, so we can just use this files table as is.

I'm going to try adding a "from_file_import" attribute to the base question type and set up the importer to store the file uploads and associate each question with its file.

mbutcher’s picture

Yes, sivaji is right about this. If we are already uploading the file onto the file system, we might as well save it there, and then save a reference to the file.

turadg’s picture

So I've got the upload persisting now, but adding the "from_file" property to each question is turning out to be harder than I thought.

I'm trying to associate the record from the files table (fid) with the question node. I thought I could tack it onto the schema quiz_node_question_properties, thinking that that was common across all questions, but I've learned that it's used only by multichoice. multichoice uses that table by legacy, but each other type, using OO, has its own table.

The OO question type system has an interface for question type, but no superclass. There's no table that stores data in common among them. It would be nice to have a standard base table as long as it could be done in a non-confusing way. So I may write a superclass with properties stored in one table, and subclasses that store added properties in another. Not sure yet, just making note of the idea.

Sivaji_Ganesh_Jojodae’s picture

I appreciate your interest in porting powerful import/export feature to quiz module. Quiz is an official google summer of code 2009 project. I have already proposed to implement a simple import/export feature (which has to be completed on or before the GSoC time scale) .i have already started working on it. Make sure your improvements/feature doesn't breaks and/or creates a major changes to the things i have already done. I am sorry if you feel that i am interrupting you.

turadg’s picture

Sivaji, of course I want you and your GSoC project to succeed. I am taking pains not to impede you. Quiz is also critical to my PhD research. We can both achieve our goals without breaking each other's code.

Something very helpful in that aim is unit testing. This summer I'm working with an undergraduate here, Drew Besse, and one thing he will be doing is writing unit tests for the quiz module. He's already written tests for the import/export code and will be uploading a patch today. He's even already found a bug using the tests.

Another way to avoid breaks is by abstraction of code so changes in implementation of one part don't impact other parts. The refactorings I describe in this issue are towards that goal.

turadg’s picture

Status: Active » Needs review

This was implemented by a patch on #515238.

It could still use error logging.

dbesse’s picture

FileSize
6.61 KB

Adds a reimport feature as requested by turadg. Uses table changes made earlier to create a new revision of every question previously added by the import.

turadg’s picture

dbesse, it looks fine but it's hard to see your changes with this full new file. It can be useful to copy and edit while developing, but for patching in we need something cleaner.

Since you copied the original file, right now loading this file and the other file in the same page request will throw a fatal error because they're defining the same function names. You made questions_reimport_form() which is safe, but you didn't similarly rename questions_import_submit_moodle_format(). Because this function is exactly the same as in, questions_import.admin.inc, it should simply be included. At that point you'd encounter your name collisions with other functions that you do want to redefine, in which case you can change their names appropriately.

Once you've got the reimport file including the regular import file and calling its functions, then you can copy and rename where you want. That'll at least be a safe patch.

Once it's all working together, then we can refactor the code so that more is shared between them and it's all easier to follow. The key is to isolate concerns so the same change doesn't have to be made in multiple places (for example, when the next programmer comes around and thinks he's fixed something but there are other places the same change must be made).

dbesse’s picture

FileSize
4.83 KB

makes sense. I've renamed the changed functions and removed the non-changed ones. There is still a lot of duplicated code. I'll go through and work on eliminating the duplicated code, but in the mean time this patch doesn't break anything.

dbesse’s picture

FileSize
8.09 KB

I think I might have messed something up with the above patch. Regardless, this one should work. It moves most of the work back to questions_import.admin, splitting all the submit functions into main functions and functions that just edits nodes. The questions_reimport uses these new node edit functions to save most of the duplicated work.

dbesse’s picture

FileSize
6.36 KB

scratch that -- I was confused on how I made the second patch. turns out I forgot to add the updated reimport file to the good one. This one *should* work properly. (As should the patch in #12, but not #13)

turadg’s picture

Assigned: Unassigned » turadg
turadg’s picture

dbesse, #14 is a great improvement. Here are some feedback items:

- there were some bugs with missing arguments
- $node->format is for the input format of the node, like "HTML Filter" which is 1. (not the *import* format)
- I like how you factored out common functionality. I did that a little more, abstracting db calls to the import records table
- "RIGHT JOIN" in the filename query brought up files that weren't imports. a simple "JOIN" is correct.

I fixed all the above, but there are a few remaining items before we can close this out.

The main one is, there's an if-statement on "$item_id", but that's never set. It seems that it's expected to be set when the question node already existed. That would be good, so please make that work. Also, several functions use that exact same logic, so factor that out.

Things like the input format or the taxonomic categories are specified in the import form. They're not saved for the reimportation, and they shouldn't be since an error in those may be why they're reimporting. Instead, add the Advanced fields from the normal input form into the reimport one. You might make a function in questions_import.admin.inc that returns the Advanced form field set.

Almost there.

turadg’s picture

Status: Needs review » Needs work
turadg’s picture

Issue tags: +blocks40a3

Needs completed for alpha 3.

falcon’s picture

Bump

falcon’s picture

Version: 6.x-4.x-dev » 6.x-5.x-dev
Status: Needs work » Postponed
turadg’s picture

Issue tags: -blocks40a3

removed blocker tag since this is postponed.

djdevin’s picture

Component: Code - Quiz module » Code - Quiz core
Issue summary: View changes
Status: Postponed » Closed (outdated)

This issue is being closed because it was filed against a version that is no longer supported. If the issue still persists in the latest version of Quiz, please open a new issue.