/**
 * Imports an exercise in QTI format if the XML structure can be found in it
 * @param array $file
 * @return an array as a backlog of what was really imported, and error or debug messages to display
 */
function import_exercise($file)
{
    global $exercise_info;
    global $element_pile;
    global $non_HTML_tag_to_avoid;
    global $record_item_body;
    // used to specify the question directory where files could be found in relation in any question
    global $questionTempDir;
    $archive_path = api_get_path(SYS_ARCHIVE_PATH) . 'qti2';
    $baseWorkDir = $archive_path;
    if (!is_dir($baseWorkDir)) {
        mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true);
    }
    $uploadPath = '/';
    // set some default values for the new exercise
    $exercise_info = array();
    $exercise_info['name'] = preg_replace('/.zip$/i', '', $file);
    $exercise_info['question'] = array();
    $element_pile = array();
    // create parser and array to retrieve info from manifest
    $element_pile = array();
    //pile to known the depth in which we are
    //$module_info = array (); //array to store the info we need
    // if file is not a .zip, then we cancel all
    if (!preg_match('/.zip$/i', $file)) {
        return 'UplZipCorrupt';
    }
    // unzip the uploaded file in a tmp directory
    if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) {
        return 'UplZipCorrupt';
    }
    // find the different manifests for each question and parse them.
    $exerciseHandle = opendir($baseWorkDir);
    //$question_number = 0;
    $file_found = false;
    $operation = false;
    $result = false;
    $filePath = null;
    // parse every subdirectory to search xml question files
    while (false !== ($file = readdir($exerciseHandle))) {
        if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") {
            // Find each manifest for each question repository found
            $questionHandle = opendir($baseWorkDir . '/' . $file);
            while (false !== ($questionFile = readdir($questionHandle))) {
                if (preg_match('/.xml$/i', $questionFile)) {
                    $result = parse_file($baseWorkDir, $file, $questionFile);
                    $filePath = $baseWorkDir . $file;
                    $file_found = true;
                }
            }
        } elseif (preg_match('/.xml$/i', $file)) {
            // Else ignore file
            $result = parse_file($baseWorkDir, '', $file);
            $filePath = $baseWorkDir . '/' . $file;
            $file_found = true;
        }
    }
    if (!$file_found) {
        return 'NoXMLFileFoundInTheZip';
    }
    if ($result == false) {
        return false;
    }
    $doc = new DOMDocument();
    $doc->load($filePath);
    $encoding = $doc->encoding;
    // 1. Create exercise.
    $exercise = new Exercise();
    $exercise->exercise = $exercise_info['name'];
    $exercise->save();
    $last_exercise_id = $exercise->selectId();
    if (!empty($last_exercise_id)) {
        // For each question found...
        foreach ($exercise_info['question'] as $question_array) {
            //2. Create question
            $question = new Ims2Question();
            $question->type = $question_array['type'];
            $question->setAnswer();
            $question->updateTitle(formatText($question_array['title']));
            //$question->updateDescription($question_array['title']);
            $type = $question->selectType();
            $question->type = constant($type);
            $question->save($last_exercise_id);
            $last_question_id = $question->selectId();
            //3. Create answer
            $answer = new Answer($last_question_id);
            $answer->new_nbrAnswers = count($question_array['answer']);
            $totalCorrectWeight = 0;
            foreach ($question_array['answer'] as $key => $answers) {
                $split = explode('_', $key);
                $i = $split[1];
                // Answer
                $answer->new_answer[$i] = formatText($answers['value']);
                // Comment
                $answer->new_comment[$i] = isset($answers['feedback']) ? formatText($answers['feedback']) : null;
                // Position
                $answer->new_position[$i] = $i;
                // Correct answers
                if (in_array($key, $question_array['correct_answers'])) {
                    $answer->new_correct[$i] = 1;
                } else {
                    $answer->new_correct[$i] = 0;
                }
                $answer->new_weighting[$i] = $question_array['weighting'][$key];
                if ($answer->new_correct[$i]) {
                    $totalCorrectWeight = $answer->new_weighting[$i];
                }
            }
            $question->updateWeighting($totalCorrectWeight);
            $question->save($last_exercise_id);
            $answer->save();
        }
        // delete the temp dir where the exercise was unzipped
        my_delete($baseWorkDir . $uploadPath);
        return $last_exercise_id;
    }
    return false;
}
Example #2
0
/**
 * Main function to import an exercise.
 *
 * @param string $file path of the file
 * @param array $backlog_message
 *
 * @return the id of the created exercise or false if the operation failed
 */
function import_exercise($file, &$backlog)
{
    global $exercise_info;
    global $element_pile;
    global $non_HTML_tag_to_avoid;
    global $record_item_body;
    // used to specify the question directory where files could be found in relation in any question
    global $questionTempDir;
    // get required table names
    $tbl_cdb_names = get_module_course_tbl(array('qwz_exercise', 'qwz_question'), claro_get_current_course_id());
    $tbl_quiz_exercise = $tbl_cdb_names['qwz_exercise'];
    $tbl_quiz_question = $tbl_cdb_names['qwz_question'];
    // paths
    $baseWorkDir = get_path('rootSys') . get_conf('tmpPathSys') . 'upload/';
    // create temp dir for upload
    if (!file_exists($baseWorkDir)) {
        claro_mkdir($baseWorkDir, CLARO_FILE_PERMISSIONS);
    }
    $uploadDir = claro_mkdir_tmp($baseWorkDir);
    // this function should return the dir name and not the full path ...
    $uploadPath = str_replace($baseWorkDir, '', $uploadDir);
    // set some default values for the new exercise
    $exercise_info = array();
    $exercise_info['name'] = preg_replace('/.zip$/i', '', $file);
    $exercise_info['description'] = '';
    $exercise_info['question'] = array();
    // create parser and array to retrieve info from manifest
    $element_pile = array();
    //pile to known the depth in which we are
    $module_info = array();
    //array to store the info we need
    // if file is not a .zip, then we cancel all
    if (!preg_match('/.zip$/i', $_FILES['uploadedExercise']['name'])) {
        $backlog->failure(get_lang('You must upload a zip file'));
        return false;
    }
    //unzip the uploaded file in a tmp directory
    if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) {
        $backlog->failure(get_lang('Upload failed'));
        return false;
    }
    // find the different manifests for each question and parse them.
    $exerciseHandle = opendir($uploadDir);
    $question_number = 0;
    $file_found = false;
    // parse every subdirectory to search xml question files
    while (false !== ($file = readdir($exerciseHandle))) {
        if (is_dir($uploadDir . '/' . $file) && $file != "." && $file != "..") {
            //find each manifest for each question repository found
            $questionHandle = opendir($uploadDir . '/' . $file);
            while (false !== ($questionFile = readdir($questionHandle))) {
                if (preg_match('/.xml$/i', $questionFile)) {
                    list($parsingBacklog, $success) = parse_file($uploadDir, $file, $questionFile);
                    $backlog->append($parsingBacklog);
                    $file_found = true;
                }
            }
        } elseif (preg_match('/.xml$/i', $file)) {
            list($parsingBacklog, $success) = parse_file($uploadDir, '', $file);
            $backlog->append($parsingBacklog);
            $file_found = true;
        }
        // else ignore file
    }
    if (!$file_found) {
        $backlog->failure(get_lang('No XML file found in the zip'));
        return false;
    }
    //---------------------
    //add exercise in tool
    //---------------------
    //1.create exercise
    $exercise = new Exercise();
    $exercise->setTitle($exercise_info['name']);
    $exercise->setDescription($exercise_info['description']);
    if ($exercise->validate()) {
        $exercise_id = $exercise->save();
    } else {
        $backlog->failure(get_lang('There is an error in exercise data of imported file.'));
        return false;
    }
    ksort($exercise_info['question'], SORT_NUMERIC);
    //For each question found...
    foreach ($exercise_info['question'] as $key => $question_array) {
        //2.create question
        $question = new Qti2Question();
        $question->import($question_array);
        if ($question->validate()) {
            // I need to save the question after the answer because I need question id in answers
            $question_id = $question->save();
            //3.create answers
            $question->setAnswer();
            $question->answer->import($question_array);
            if ($question->answer->validate()) {
                $question->setGrade($question->answer->getGrade());
                $question->save();
                // save computed grade
                $question->answer->save();
                $exercise->addQuestion($question_id);
            } else {
                $backlog->failure(get_lang('Invalid answer') . ' : ' . $key);
            }
        } else {
            $backlog->failure(get_lang('Invalid question') . ' : ' . $key);
        }
    }
    // delete the temp dir where the exercise was unzipped
    claro_delete_file($uploadDir);
    return $exercise_id;
}
/**
 * Main function to import the Aiken exercise
 * @return mixed True on success, error message on failure
 */
function aiken_import_exercise($file)
{
    global $exercise_info;
    global $element_pile;
    global $non_HTML_tag_to_avoid;
    global $record_item_body;
    // used to specify the question directory where files could be found in relation in any question
    global $questionTempDir;
    $archive_path = api_get_path(SYS_ARCHIVE_PATH) . 'aiken';
    $baseWorkDir = $archive_path;
    if (!is_dir($baseWorkDir)) {
        mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true);
    }
    $uploadPath = '/';
    // set some default values for the new exercise
    $exercise_info = array();
    $exercise_info['name'] = preg_replace('/.(zip|txt)$/i', '', $file);
    $exercise_info['question'] = array();
    $element_pile = array();
    // create parser and array to retrieve info from manifest
    $element_pile = array();
    //pile to known the depth in which we are
    // if file is not a .zip, then we cancel all
    if (!preg_match('/.(zip|txt)$/i', $file)) {
        //Display :: display_error_message(get_lang('YouMustUploadAZipOrTxtFile'));
        return 'YouMustUploadAZipOrTxtFile';
    }
    // unzip the uploaded file in a tmp directory
    if (preg_match('/.(zip|txt)$/i', $file)) {
        if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) {
            return 'ThereWasAProblemWithYourFile';
        }
    }
    // find the different manifests for each question and parse them
    $exerciseHandle = opendir($baseWorkDir);
    $file_found = false;
    $operation = false;
    $result = false;
    // Parse every subdirectory to search txt question files
    while (false !== ($file = readdir($exerciseHandle))) {
        if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") {
            //find each manifest for each question repository found
            $questionHandle = opendir($baseWorkDir . '/' . $file);
            while (false !== ($questionFile = readdir($questionHandle))) {
                if (preg_match('/.txt$/i', $questionFile)) {
                    $result = aiken_parse_file($exercise_info, $baseWorkDir, $file, $questionFile);
                    $file_found = true;
                }
            }
        } elseif (preg_match('/.txt$/i', $file)) {
            $result = aiken_parse_file($exercise_info, $baseWorkDir, '', $file);
            $file_found = true;
        }
        // else ignore file
    }
    if (!$file_found) {
        $result = 'NoTxtFileFoundInTheZip';
    }
    if ($result !== true) {
        return $result;
    }
    // Add exercise in tool
    // 1.create exercise
    $exercise = new Exercise();
    $exercise->exercise = $exercise_info['name'];
    $exercise->save();
    $last_exercise_id = $exercise->selectId();
    if (!empty($last_exercise_id)) {
        // For each question found...
        foreach ($exercise_info['question'] as $key => $question_array) {
            //2.create question
            $question = new Aiken2Question();
            $question->type = $question_array['type'];
            $question->setAnswer();
            $question->updateTitle($question_array['title']);
            $question->updateDescription($question_array['description']);
            $type = $question->selectType();
            $question->type = constant($type);
            $question->save($last_exercise_id);
            $last_question_id = $question->selectId();
            //3.create answer
            $answer = new Answer($last_question_id);
            $answer->new_nbrAnswers = count($question_array['answer']);
            $max_score = 0;
            foreach ($question_array['answer'] as $key => $answers) {
                $key++;
                $answer->new_answer[$key] = $answers['value'];
                $answer->new_position[$key] = $key;
                // Correct answers ...
                if (in_array($key, $question_array['correct_answers'])) {
                    $answer->new_correct[$key] = 1;
                    $answer->new_comment[$key] = $question_array['feedback'];
                } else {
                    $answer->new_correct[$key] = 0;
                }
                $answer->new_weighting[$key] = $question_array['weighting'][$key - 1];
                $max_score += $question_array['weighting'][$key - 1];
            }
            $answer->save();
            // Now that we know the question score, set it!
            $question->updateWeighting($max_score);
            $question->save();
        }
        // delete the temp dir where the exercise was unzipped
        my_delete($baseWorkDir . $uploadPath);
        $operation = $last_exercise_id;
    }
    return $operation;
}
/**
 * main function to import an exercise,
 *
 * @return an array as a backlog of what was really imported, and error or debug messages to display
 */
function import_exercise($file)
{
    global $exercise_info;
    global $element_pile;
    global $non_HTML_tag_to_avoid;
    global $record_item_body;
    // used to specify the question directory where files could be found in relation in any question
    global $questionTempDir;
    $archive_path = api_get_path(SYS_ARCHIVE_PATH) . 'qti2';
    $baseWorkDir = $archive_path;
    if (!is_dir($baseWorkDir)) {
        mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true);
    }
    $uploadPath = '/';
    // set some default values for the new exercise
    $exercise_info = array();
    $exercise_info['name'] = preg_replace('/.zip$/i', '', $file);
    $exercise_info['question'] = array();
    $element_pile = array();
    // create parser and array to retrieve info from manifest
    $element_pile = array();
    //pile to known the depth in which we are
    //$module_info = array (); //array to store the info we need
    // if file is not a .zip, then we cancel all
    if (!preg_match('/.zip$/i', $file)) {
        Display::display_error_message(get_lang('You must upload a zip file'));
        return false;
    }
    // unzip the uploaded file in a tmp directory
    if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) {
        Display::display_error_message(get_lang('You must upload a zip file'));
        return false;
    }
    // find the different manifests for each question and parse them.
    $exerciseHandle = opendir($baseWorkDir);
    //$question_number = 0;
    $file_found = false;
    $operation = false;
    $result = false;
    // parse every subdirectory to search xml question files
    while (false !== ($file = readdir($exerciseHandle))) {
        if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") {
            //find each manifest for each question repository found
            $questionHandle = opendir($baseWorkDir . '/' . $file);
            while (false !== ($questionFile = readdir($questionHandle))) {
                if (preg_match('/.xml$/i', $questionFile)) {
                    $result = parse_file($baseWorkDir, $file, $questionFile);
                    $file_found = true;
                }
            }
        } elseif (preg_match('/.xml$/i', $file)) {
            $result = parse_file($baseWorkDir, '', $file);
            $file_found = true;
        }
        // else ignore file
    }
    if (!$file_found) {
        Display::display_error_message(get_lang('No XML file found in the zip'));
        return false;
    }
    if ($result == false) {
        return false;
    }
    //add exercise in tool
    //1.create exercise
    $exercise = new Exercise();
    $exercise->exercise = $exercise_info['name'];
    $exercise->save();
    $last_exercise_id = $exercise->selectId();
    if (!empty($last_exercise_id)) {
        //For each question found...
        foreach ($exercise_info['question'] as $key => $question_array) {
            //2.create question
            $question = new Ims2Question();
            $question->type = $question_array['type'];
            $question->setAnswer();
            $question->updateTitle($question_array['title']);
            // question ...
            $type = $question->selectType();
            $question->type = constant($type);
            // type ...
            $question->save($last_exercise_id);
            // save computed grade
            $last_question_id = $question->selectId();
            //3.create answer
            $answer = new Answer($last_question_id);
            $answer->new_nbrAnswers = count($question_array['answer']);
            foreach ($question_array['answer'] as $key => $answers) {
                $split = explode('_', $key);
                $i = $split[1];
                $answer->new_answer[$i] = $answers['value'];
                // answer ...
                $answer->new_comment[$i] = $answers['feedback'];
                // comment ...
                $answer->new_position[$i] = $i;
                // position ...
                // correct answers ...
                if (in_array($key, $question_array['correct_answers'])) {
                    $answer->new_correct[$i] = 1;
                } else {
                    $answer->new_correct[$i] = 0;
                }
                $answer->new_weighting[$i] = $question_array['weighting'][$key];
            }
            $answer->save();
        }
        // delete the temp dir where the exercise was unzipped
        FileManager::my_delete($baseWorkDir . $uploadPath);
        $operation = true;
    }
    return $operation;
}