The Curious Case of the Disappearing Image

During our first live test of Rogo, we were somewhat alarmed when the students pointed out that one of the questions was missing an image. Although far from ideal, it was thankfully not disastrous, as it was noticed fairly early on and we were able to print out a copy of the image for all the students.

The question is, what happened to this image? The paper was checked thoroughly against the QuestionMark Perception version of the paper immediately after it was imported, so it would have been spotted at that point had it not come through in the import. However, I clearly did not check the paper thoroughly enough immediately before the exam, as the image was not there.

So the image was lost from the question between it being imported into Rogo and the paper being taken. To find out when and why, I reimported just this question. The image is there in the QTI XML export from Perception, and was there in the question immediately after import. However, after saving the question from the edit screen, without having made any changes to the question, the image had disappeared. The table cell that should contain the image was left just containing an  .

We presumed there was something in the imported HTML that was causing this to occur. Initially we thought it might be that there was no closing tag for the <IMG …> (nor a closing slash at the end of the tag), but adding this made no difference, and there were other questions that have the same lack of closing tag and there were no problems with these. On closer inspection of the html for the questions, we noticed that there was a span in the question intro in the faulty question that was not there in any others. This span contained some attributes that came from MS Word:

<SPAN style=”mso-bidi-font-family: Arial; mso-hansi-font-family: Arial” lang=EN-GB><STRONG>diaphragm <BR></STRONG></SPAN>

Removing the span altogether fixed the problem, so we drilled down in order to identify what aspect of the tags was causing it. We looked into the following:

  • The <br> inside span the span? Moving it outside made no difference
  • No quotation marks around EN-GB? Adding them made no difference
  • The lang attribute? Removing it made no difference
  • Non-standard CSS properties in style attribute? Removing the styles fixed the problem

Although it is nice to have found the specific cause, there is no reason for this span to exist at all, so we have removed it completely from the imported version. Hopefully questions containing spans such as this will be few and far between, but since many questions are copied in from Word, care needs to be taken, as it seems that the Rogo text editor, not unusually, does not like them.

For future imports, a quick find/replace through the QTI XML exports when we transfer questions en masse from Perception to Rogo should enable us to remove problematic spans. We will have to do some modification of the XML anyway (e.g. changing the path to images), so it will not be much more work to sort this out as well. I have also blogged about other issues relating to importing questions.

Importing Questions into Rogo

In preparation for our first running our first live test of Rogo, we needed to get an exam paper that had been created in Questionmark Perception into Rogo. This seemed simple enough, simply by exporting the QTI XML from Perception and importing it into Rogo. This generally worked reasonably well, but there were a few issues that had to be dealt with:

  • Not unsurprisingly, images needed special attention. The links to the images in Perception (e.g. “%SERVER.GRAPHICS%topicresources/1065007843”, where the number at the end is the topic id) were replaced (using a blanket find/replace) with “/media(/subdirectorypath)”, and the images copied into the appropriate subdirectory.
  • There were some issues with tables where an image was shown side by side with the answer options, which required a hack in Perception. For some questions there were problems in the HTML in Perception (left over from the dark ages), so fixing the HTML in Perception fixed the import problems relating to this.
  • EMQ feedback – the general question feedback from Perception is given as the feedback for all stems in Rogo, which does not have general feedback for EMQs. This can be fixed by removing the feedback from all except the last question, so that it just appears at the end of the responses. Alternatively, the feedback can be split up to give each stem its own feedback. Either of these options would be laborious for large numbers of questions, so the best long-term alternative may be to alter the import code to deal with this.
  • MCQ feedback – when importing MCQs (including those created in Rogo, exported and imported back in without any modification), in which only general feedback is provided, the general feedback is put in the answer feedback for each answer and general feedback is left empty. This has been added to the Rogo Trac system (#683,  https://suivarro.nottingham.ac.uk/trac/rogo/ticket/683)
  • Correct answers for EMQs – after importing all the correct answers are set to A. This is also the case if a question is created in Rogo, exported from Rogo and imported back in. This issue was added to Trac (#682, https://suivarro.nottingham.ac.uk/trac/rogo/ticket/682) and has now been fixed by the Rogo team, presumably for a future release. For this assessment, fixing this was simply, but annoyingly, a case of going through all the questions and changing the correct answers.
  • Rogo does not have a multiple MCQ question type, i.e. several MCQs that share the same stimulus and so are combined into a single question, so that it looks like an EMQ, but there are different answer options for each stem. Such questions are recognised as Matrix questions by Rogo when they are imported, but this format is not appropriate. There is no way of modifying an EMQ in Rogo so that subsets of the answer options are only available for certain stems. We have a large number of questions of this format, and currently the only option is to separate them out into MCQs, which is not a sustainable solution. Therefore, we may need to create a multiple MCQ question type, which hopefully would not be too difficult using the EMQ question type as the basis.

Having fixed all these problems, it seemed as though we had an exact copy of the assessment, with everything working as it should. The only difference between the questions as far as the students were concerned was that the multiple MCQ question (there was only one of this type in this paper) was split into 5 separate MCQs.

However, while running the assessment, we were to come across the Curious Case of the Disappearing Image, which, it turned out, was caused by a problem related to importing.

Importing Multiple Users in Rogo

Rogo enables the import of multiple users from a CSV file.

The are a number of required fields, although the order of the fields is flexible. The import does not worry about the case of the field headings, and can accept alternatives for each, as shown below:

  • Student ID: student_id, id
  • Forename(s): first names, forenames
  • Surname: surname, family name
  • Title: title
  • Course Code: course code, course
  • Year of Study: year of study, year of course (1, 2, 3 etc, not actual year, which is held in session)
  • Email Address: email, local email

It is also possible to specify a username for each student. If no username is given, the system will take everything before the @ in the email as the student’s username. A Module and Session (e.g. 2011/12) can also be specified – both are needed for this to be added. Module needs to be the module ID, e.g. OrgBod.

The Student ID does not refer to the student’s username or their database ID (an incremental digit), but a student ID held in a separate table in the database, which does not have to be unique.

Importing a user with the same username as a user that is already in the database will result in that user being overwritten.

There is no way of specifying a password for a user. All passwords are generated randomly and then hashed. This means there is also no way of finding out a user’s password. The only way to define a password for a user is to click “Reset” from the User File, which sends the user an email that they can then click on to set their password. This makes sense from a security point of view, but it is important for us to be able to see user’s passwords (something that is possible in Perception), so that we can log them in if they have forgotten their password, and can test multiple users with defined passwords.

In order to enable defining of passwords in user import, the following was added to import_users.inc:

Line 117:

    //JHM 2012-04-13: Enable passwords to be imported by csv
if (isset($header['password']) && $fields[$header['password']] != "") {	//Check that we have a password header, and the password is not blank for this user
    $password = $fields[$header['password']];
} else {
    $password = PasswordUtils::gen_password();	//No password was provided, so generate a random one
}

Line 137, comment out:

//$password = PasswordUtils::gen_password();	//JHM 2012-04-13: Password now obtained from csv or generated above (line 118)

From looking in the database, this was changing the value of the password for a user, but still did not allow the user to login using the given password. It emerged that this was because the passwords were being doubly encrypted, first in import_users.inc and then in UserUtils::createUser (userutils.class.php line 50). Therefore, I changed lines 137-139 of import_users.inc to:

//$password = PasswordUtils::gen_password();	//JHM 2012-04-13: Password now obtained from csv or generated above (line 118)
//$encpw_password = PasswordUtils::encpw($username, $password);	//JHM 2012-04-13: Password encrypted in createUser below
$encpw_password = $password;	//JHM 2012-04-13: Password encrypted in createUser below, so use plain password

This then worked fine for new user imports, but not for importing users over the top of old users. This required changes to lines 153 onwards in import_users.inc:

$encpw_password = PasswordUtils::encpw($username, $password);	//JHM 2012-04-13: Encrypt password for updating

//JHM 2012-04-13: Added password - 'ssssss' refers to var types, so add extra s to get it to work
$result = $mysqli->prepare("UPDATE users SET yearofstudy=?, title=?, first_names=?, surname=?, grade=?, password=? WHERE username=?");
$result->bind_param('sssssss', $year, $title, $forname, $surname, $course, $encpw_password, $username);

This now seems to work. This issue has been submitted to the Trac system – ticket #701, https://suivarro.nottingham.ac.uk/trac/rogo/ticket/701

We have also made a request for the import to flag up potential problems with header names, and/or enabling users to tell Rogo which headers it should expect, so it can report back if it failed to find any of these. Trac ticket #700 – https://suivarro.nottingham.ac.uk/trac/rogo/ticket/700