Issue Details (XML | Word | Printable)

Key: MDL-10234
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Minor Minor
Assignee: Howard Miller
Reporter: Enrique Castro
Votes: 0
Watchers: 0
Operations

Add/Edit UI Mockup to this issue
If you were logged in you would be able to see more operations.
Moodle

Fail to correctly import images in questions from XML exported file

Created: 24/Jun/07 02:01 AM   Updated: 28/Jun/07 11:16 PM
Return to search
Component/s: Questions
Affects Version/s: 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.7, 1.7.1, 1.7.2, 1.8, 1.8.1
Fix Version/s: 1.8.2, 1.9

Participants: Enrique Castro and Howard Miller
Security Level: None
Resolved date: 28/Jun/07
Affected Branches: MOODLE_16_STABLE, MOODLE_17_STABLE, MOODLE_18_STABLE
Fixed Branches: MOODLE_18_STABLE, MOODLE_19_STABLE


 Description  « Hide
Questions can be exported into XML text files that include images encoded as base64.
This is a very convenient way to move quiz questions around between courses. Better thsi is the ONLY way to excahnge quiz questions that include imege files added through the "Image to display" field in the question editing form.

However, importing such files created by export feature fails for any picture that is not in the course root dir. If the questions point to any image file located within any subdir of the course root, the questions are imported but not imagefiles. If I create previously the image directory then then image files are uploaded correctly, but the "Image to display" field is not pointing to it.

I have traced this to a minor bug in function importimagefile( $path, $base64 ) located in /question/format.php

When the XML files is procesed for importing by /question/format/xml/xml.php, in function import_headers( $question ) by line 132:

        $image = $this->getpath( $question, array('#','image',0,'#'), $qo->image );
        $image_base64 = $this->getpath( $question, array('#','image_base64','0','#'),'' );
        if (!empty($image_base64)) {
            $qo->image = $this->importimagefile( $image, stripslashes($image_base64) );
        }

 $qo->image will be the "Image to display" content, so it is essential that it contains the full path to the image file location, for instance "images/file.jpg".

However, importimagefile() function fails in two senses:

a) it returns the image filename WITHOUT the path, so the $qo->image/"Image to display" points to incorrect location (unless image is in root dir)
b) importimagefile fails to CREATE image dir if not exists previously. So, if the teacher is not aware of teh images locations and creates manually the appropriate subdirs BEFORE importing the procedure will fail.

I propose two modifications to importimagefile() to fix these issues:

    function importimagefile( $path, $base64 ) {
        global $CFG;

        // all this to get the destination directory
        // and filename!
        $fullpath = "{$CFG->dataroot}/{$this->course->id}/$path";
        $path_parts = pathinfo( $fullpath );
        $destination = $path_parts['dirname'];
        $file = clean_filename( $path_parts['basename'] );

        //check if path exists <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        check_dir_exists($destination, true, true); // ULPGC ecastro <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        // detect and fix any filename collision - get unique filename
        $newfiles = resolve_filename_collisions( $destination, array($file) );
        print_object("files:");
        print_object($newfiles);
        $newfile = $newfiles[0];

        // convert and save file contents
        if (!$content = base64_decode( $base64 )) {
            return '';
        }
        
        $newfullpath = "$destination/$newfile";
        if (!$fh = fopen( $newfullpath, 'w' )) {
            return '';
        }
        if (!fwrite( $fh, $content )) {
            return '';
        }
        fclose( $fh );

        // return the (possibly) new filename
        // include the path from course root. // ULPGC ecastro <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        $newfile = ereg_replace("{$CFG->dataroot}/{$this->course->id}/", '',$newfullpath); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        return $newfile;
    }


The code is the same for all versions from 1.6 to 1.9(HEAD)
Hope this can be fixed rapidly.

Cheers










 All   Comments   Change History   Version Control      Sort Order: Ascending order - Click to sort in descending order
Howard Miller made changes - 24/Jun/07 04:06 AM
Field Original Value New Value
Assignee Tim Hunt [ timhunt ] Howard Miller [ howardsmiller ]
thepurpleblob committed 1 file to 'Moodle CVS' on branch 'MOODLE_18_STABLE' - 28/Jun/07 11:13 PM
MDL-10234
Encoded images in subdirectories failed to load.
Thanks to Enrique Castro for fix.
MODIFY question/format.php   Rev. 1.17.2.7    (+5 -1 lines)
thepurpleblob committed 1 file to 'Moodle CVS' - 28/Jun/07 11:15 PM
MDL-10234
Encoded images in subdirectories failed to load.
Thanks to Enrique Castro for fix.
MODIFY question/format.php   Rev. 1.29    (+5 -1 lines)
Howard Miller added a comment - 28/Jun/07 11:16 PM
Fixed in CVS.

Thanks for patch.


Howard Miller made changes - 28/Jun/07 11:16 PM
Fix Version/s 1.8.2 [ 10220 ]
Status Open [ 1 ] Resolved [ 5 ]
Resolution Fixed [ 1 ]
Fix Version/s 1.9 [ 10190 ]