/**
  * @todo : add session id when used for session
  */
 public function restore_test_category($session_id, $respect_base_content, $destination_course_code)
 {
     $course_id = api_get_course_int_id();
     // Let's restore the categories
     $tab_test_category_id_old_new = array();
     // used to build the quiz_question_rel_category table
     if ($this->course->has_resources(RESOURCE_TEST_CATEGORY)) {
         $resources = $this->course->resources;
         foreach ($resources[RESOURCE_TEST_CATEGORY] as $id => $CourseCopyTestcategory) {
             $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
             // check if this test_category already exist in the destination BDD
             // do not Database::escape_string $title and $description, it will be done later
             $title = $CourseCopyTestcategory->title;
             $description = $CourseCopyTestcategory->description;
             if (Testcategory::category_exists_with_title($title)) {
                 switch ($this->file_option) {
                     case FILE_SKIP:
                         //Do nothing
                         break;
                     case FILE_RENAME:
                         $new_title = $title . "_";
                         while (Testcategory::category_exists_with_title($new_title)) {
                             $new_title .= "_";
                         }
                         $test_category = new Testcategory(0, $new_title, $description);
                         $new_id = $test_category->addCategoryInBDD();
                         $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
                         break;
                     case FILE_OVERWRITE:
                         $id = Testcategory::get_category_id_for_title($title);
                         $my_cat = new Testcategory($id);
                         $my_cat->name = $title;
                         $my_cat->modifyCategory();
                         $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
                         break;
                 }
             } else {
                 // create a new test_category
                 $test_category = new Testcategory(0, $title, $description);
                 $new_id = $test_category->addCategoryInBDD();
                 $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
             }
             $this->course->resources[RESOURCE_TEST_CATEGORY][$id]->destination_id = $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id];
         }
     }
     // lets check if quizzes-question are restored too, to redo the link between test_category and quizzes question for questions restored
     // we can use the source_id field
     // question source_id => category source_id
     if ($this->course->has_resources(RESOURCE_QUIZQUESTION)) {
         // check the category number of each question restored
         if (!empty($resources[RESOURCE_QUIZQUESTION])) {
             foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $CourseCopyQuestion) {
                 $new_quiz_question_id = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
                 $question_category = $CourseCopyQuestion->question_category;
                 if ($question_category > 0) {
                     Testcategory::add_category_for_question_id($tab_test_category_id_old_new[$question_category], $new_quiz_question_id, $course_id);
                 }
             }
         }
     }
 }
Esempio n. 2
0
/**
 * Handles a given Excel spreadsheets as in the template provided
 */
function lp_upload_quiz_action_handling()
{
    global $debug;
    $_course = api_get_course_info();
    $courseId = $_course['real_id'];
    if (!isset($_POST['submit_upload_quiz'])) {
        return;
    }
    // Get the extension of the document.
    $path_info = pathinfo($_FILES['user_upload_quiz']['name']);
    // Check if the document is an Excel document
    if ($path_info['extension'] != 'xls') {
        return;
    }
    // Read the Excel document
    $data = new Spreadsheet_Excel_Reader();
    // Set output Encoding.
    $data->setOutputEncoding(api_get_system_encoding());
    // Reading the xls document.
    $data->read($_FILES['user_upload_quiz']['tmp_name']);
    $correctScore = isset($_POST['correct_score']) ? $_POST['correct_score'] : null;
    $incorrectScore = isset($_POST['incorrect_score']) ? $_POST['incorrect_score'] : null;
    $useCustomScore = isset($_POST['user_custom_score']) ? true : false;
    $propagateNegative = 0;
    if ($useCustomScore && !empty($incorrectScore)) {
        if ($incorrectScore < 0) {
            $propagateNegative = 1;
        }
    }
    // Variables
    $quiz_index = 0;
    $question_title_index = array();
    $question_name_index_init = array();
    $question_name_index_end = array();
    $score_index = array();
    $feedback_true_index = array();
    $feedback_false_index = array();
    $number_questions = 0;
    $question_description_index = array();
    $noNegativeScoreIndex = array();
    $questionTypeList = array();
    $questionTypeIndex = array();
    $categoryList = array();
    // Reading all the first column items sequentially to create breakpoints
    for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
        if ($data->sheets[0]['cells'][$i][1] == 'Quiz' && $i == 1) {
            $quiz_index = $i;
            // Quiz title position, only occurs once
        } elseif ($data->sheets[0]['cells'][$i][1] == 'Question') {
            $question_title_index[] = $i;
            // Question title position line
            $question_name_index_init[] = $i + 1;
            // Questions name 1st position line
            $number_questions++;
        } elseif ($data->sheets[0]['cells'][$i][1] == 'Score') {
            $question_name_index_end[] = $i - 1;
            // Question name position
            $score_index[] = $i;
            // Question score position
        } elseif ($data->sheets[0]['cells'][$i][1] == 'FeedbackTrue') {
            $feedback_true_index[] = $i;
            // FeedbackTrue position (line)
        } elseif ($data->sheets[0]['cells'][$i][1] == 'FeedbackFalse') {
            $feedback_false_index[] = $i;
            // FeedbackFalse position (line)
        } elseif ($data->sheets[0]['cells'][$i][1] == 'EnrichQuestion') {
            $question_description_index[] = $i;
        } elseif ($data->sheets[0]['cells'][$i][1] == 'NoNegativeScore') {
            $noNegativeScoreIndex[] = $i;
        } elseif ($data->sheets[0]['cells'][$i][1] == 'QuestionType') {
            $questionTypeIndex[] = $i;
        }
    }
    // Variables
    $quiz = array();
    $question = array();
    $new_answer = array();
    $score_list = array();
    $feedback_true_list = array();
    $feedback_false_list = array();
    $question_description = array();
    $noNegativeScoreList = array();
    // Getting questions.
    $k = $z = $q = $l = $m = $n = 0;
    for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
        if (is_array($data->sheets[0]['cells'][$i])) {
            $column_data = $data->sheets[0]['cells'][$i];
            // Fill all column with data to have a full array
            for ($x = 1; $x <= $data->sheets[0]['numCols']; $x++) {
                if (empty($column_data[$x])) {
                    $data->sheets[0]['cells'][$i][$x] = '';
                }
            }
            // Array filled with data
            $column_data = $data->sheets[0]['cells'][$i];
        } else {
            $column_data = '';
        }
        // Fill quiz data
        if ($quiz_index == $i) {
            // The title always in the first position
            $quiz = $column_data;
        } elseif (in_array($i, $question_title_index)) {
            //a complete line where 1st column is 'Question'
            $question[$k] = $column_data;
            for ($counter = 0; $counter < 12; $counter++) {
                $myData = isset($data->sheets[0]['cells'][$i + $counter]) ? $data->sheets[0]['cells'][$i + $counter] : null;
                if (isset($myData[1]) && $myData[1] == 'QuestionType') {
                    $questionTypeList[$k] = $myData[3];
                }
                if (isset($myData[1]) && $myData[1] == 'Category') {
                    $categoryList[$k] = $myData[2];
                }
            }
            if (!isset($questionTypeList[$k])) {
                $questionTypeList[$k] = null;
            }
            $k++;
        } elseif (in_array($i, $score_index)) {
            //a complete line where 1st column is 'Score'
            $score_list[$z] = $column_data;
            $z++;
        } elseif (in_array($i, $feedback_true_index)) {
            //a complete line where 1st column is 'FeedbackTrue'
            $feedback_true_list[$q] = $column_data;
            $q++;
        } elseif (in_array($i, $feedback_false_index)) {
            //a complete line where 1st column is 'FeedbackFalse' for wrong answers
            $feedback_false_list[$l] = $column_data;
            $l++;
        } elseif (in_array($i, $question_description_index)) {
            //a complete line where 1st column is 'EnrichQuestion'
            $question_description[$m] = $column_data;
            $m++;
        } elseif (in_array($i, $noNegativeScoreIndex)) {
            //a complete line where 1st column is 'NoNegativeScore'
            $noNegativeScoreList[$z - 1] = $column_data;
        }
    }
    // Get answers
    for ($i = 0; $i < count($question_name_index_init); $i++) {
        for ($j = $question_name_index_init[$i]; $j <= $question_name_index_end[$i]; $j++) {
            if (is_array($data->sheets[0]['cells'][$j])) {
                $column_data = $data->sheets[0]['cells'][$j];
                // Fill all column with data
                for ($x = 1; $x <= $data->sheets[0]['numCols']; $x++) {
                    if (empty($column_data[$x])) {
                        $data->sheets[0]['cells'][$j][$x] = '';
                    }
                }
                $column_data = $data->sheets[0]['cells'][$j];
                // Array filled of data
                if (is_array($column_data) && count($column_data) > 0) {
                    $new_answer[$i][$j] = $column_data;
                }
            }
        }
    }
    // Quiz title.
    $quiz_title = $quiz[2];
    if ($quiz_title != '') {
        // Variables
        $type = 2;
        $random = $active = $results = $max_attempt = $expired_time = 0;
        // Make sure feedback is enabled (3 to disable), otherwise the fields
        // added to the XLS are not shown, which is confusing
        $feedback = 0;
        // Quiz object
        $exercise = new Exercise();
        //
        $quiz_id = $exercise->createExercise($quiz_title, $expired_time, $type, $random, $active, $results, $max_attempt, $feedback, $propagateNegative);
        if ($quiz_id) {
            // insert into the item_property table
            api_item_property_update($_course, TOOL_QUIZ, $quiz_id, 'QuizAdded', api_get_user_id());
            // Import questions.
            for ($i = 0; $i < $number_questions; $i++) {
                // Question name
                $question_title = $question[$i][2];
                $description = isset($question_description[$i][2]) ? $question_description[$i][2] : '';
                $categoryId = null;
                if (isset($categoryList[$i]) && !empty($categoryList[$i])) {
                    $categoryName = $categoryList[$i];
                    $categoryId = Testcategory::get_category_id_for_title($categoryName, $courseId);
                    if (empty($categoryId)) {
                        $category = new TestCategory(null, $categoryName, '');
                        $categoryId = $category->addCategoryInBDD();
                    }
                }
                $question_description_text = "<p></p>";
                if (!empty($description)) {
                    // Question description.
                    $question_description_text = "<p>" . $description . "</p>";
                }
                // Unique answers are the only question types available for now
                // through xls-format import
                $answerList = isset($new_answer[$i]) ? $new_answer[$i] : '';
                $question_id = null;
                if (isset($questionTypeList[$i])) {
                    $detectQuestionType = intval($questionTypeList[$i]);
                } else {
                    $detectQuestionType = detectQuestionType($answerList, $score_list);
                }
                /** @var Question $answer */
                switch ($detectQuestionType) {
                    case FREE_ANSWER:
                        $answer = new FreeAnswer();
                        break;
                    case GLOBAL_MULTIPLE_ANSWER:
                        $answer = new GlobalMultipleAnswer();
                        break;
                    case MULTIPLE_ANSWER:
                        $answer = new MultipleAnswer();
                        break;
                    case FILL_IN_BLANKS:
                        $answer = new FillBlanks();
                        $question_description_text = '';
                        break;
                    case MATCHING:
                        $answer = new Matching();
                        break;
                    case UNIQUE_ANSWER:
                    default:
                        $answer = new UniqueAnswer();
                        break;
                }
                if ($question_title != '') {
                    $question_id = $answer->create_question($quiz_id, $question_title, $question_description_text, 0, $answer->type);
                    if (!empty($categoryId)) {
                        TestCategory::add_category_for_question_id($categoryId, $question_id, $courseId);
                    }
                }
                switch ($detectQuestionType) {
                    case GLOBAL_MULTIPLE_ANSWER:
                    case MULTIPLE_ANSWER:
                    case UNIQUE_ANSWER:
                        $total = 0;
                        if (is_array($answerList) && !empty($question_id)) {
                            $id = 1;
                            $globalScore = null;
                            $objAnswer = new Answer($question_id, $courseId);
                            $globalScore = $score_list[$i][3];
                            // Calculate the number of correct answers to divide the
                            // score between them when importing from CSV
                            $numberRightAnswers = 0;
                            foreach ($answerList as $answer_data) {
                                if (strtolower($answer_data[3]) == 'x') {
                                    $numberRightAnswers++;
                                }
                            }
                            foreach ($answerList as $answer_data) {
                                $answerValue = $answer_data[2];
                                $correct = 0;
                                $score = 0;
                                if (strtolower($answer_data[3]) == 'x') {
                                    $correct = 1;
                                    $score = $score_list[$i][3];
                                    $comment = $feedback_true_list[$i][2];
                                } else {
                                    $comment = $feedback_false_list[$i][2];
                                    $floatVal = (double) $answer_data[3];
                                    if (is_numeric($floatVal)) {
                                        $score = $answer_data[3];
                                    }
                                }
                                if ($useCustomScore) {
                                    if ($correct) {
                                        $score = $correctScore;
                                    } else {
                                        $score = $incorrectScore;
                                    }
                                }
                                // Fixing scores:
                                switch ($detectQuestionType) {
                                    case GLOBAL_MULTIPLE_ANSWER:
                                        if (isset($noNegativeScoreList[$i][3])) {
                                            if (!(strtolower($noNegativeScoreList[$i][3]) == 'x') && !$correct) {
                                                $score = $score_list[$i][3] * -1;
                                            }
                                        } else {
                                            $score = $score_list[$i][3] * -1;
                                        }
                                        $score /= $numberRightAnswers;
                                        break;
                                    case UNIQUE_ANSWER:
                                        break;
                                    case MULTIPLE_ANSWER:
                                        if (!$correct) {
                                            //$total = $total - $score;
                                        }
                                        break;
                                }
                                $objAnswer->createAnswer($answerValue, $correct, $comment, $score, $id);
                                $total += $score;
                                $id++;
                            }
                            $objAnswer->save();
                            $questionObj = Question::read($question_id, $courseId);
                            switch ($detectQuestionType) {
                                case GLOBAL_MULTIPLE_ANSWER:
                                    $questionObj->updateWeighting($globalScore);
                                    break;
                                case UNIQUE_ANSWER:
                                case MULTIPLE_ANSWER:
                                default:
                                    $questionObj->updateWeighting($total);
                                    break;
                            }
                            $questionObj->save();
                        }
                        break;
                    case FREE_ANSWER:
                        $questionObj = Question::read($question_id, $courseId);
                        $globalScore = $score_list[$i][3];
                        $questionObj->updateWeighting($globalScore);
                        $questionObj->save();
                        break;
                    case FILL_IN_BLANKS:
                        $scoreList = array();
                        $size = array();
                        $globalScore = 0;
                        foreach ($answerList as $data) {
                            $score = isset($data[3]) ? $data[3] : 0;
                            $globalScore += $score;
                            $scoreList[] = $score;
                            $size[] = 200;
                        }
                        $scoreToString = implode(',', $scoreList);
                        $sizeToString = implode(',', $size);
                        //<p>Texte long avec les [mots] à [remplir] mis entre [crochets]</p>::10,10,10:200.36363999999998,200,200:0@'
                        $answerValue = $description . '::' . $scoreToString . ':' . $sizeToString . ':0@';
                        $objAnswer = new Answer($question_id, $courseId);
                        $objAnswer->createAnswer($answerValue, '', '', $globalScore, 1);
                        $objAnswer->save();
                        $questionObj = Question::read($question_id, $courseId);
                        $questionObj->updateWeighting($globalScore);
                        $questionObj->save();
                        break;
                    case MATCHING:
                        $globalScore = $score_list[$i][3];
                        $position = 1;
                        $objAnswer = new Answer($question_id, $courseId);
                        foreach ($answerList as $data) {
                            $option = isset($data[3]) ? $data[3] : '';
                            $objAnswer->createAnswer($option, 0, '', 0, $position);
                            $position++;
                        }
                        $counter = 1;
                        foreach ($answerList as $data) {
                            $value = isset($data[2]) ? $data[2] : '';
                            $position++;
                            $objAnswer->createAnswer($value, $counter, ' ', $globalScore, $position);
                            $counter++;
                        }
                        $objAnswer->save();
                        $questionObj = Question::read($question_id, $courseId);
                        $questionObj->updateWeighting($globalScore);
                        $questionObj->save();
                        break;
                }
            }
        }
        $lpFromSession = Session::read('lpobject');
        if (isset($lpFromSession)) {
            if ($debug > 0) {
                error_log('New LP - SESSION[lpobject] is defined', 0);
            }
            $oLP = unserialize($lpFromSession);
            if (is_object($oLP)) {
                if ($debug > 0) {
                    error_log('New LP - oLP is object', 0);
                }
                if (empty($oLP->cc) or $oLP->cc != api_get_course_id()) {
                    if ($debug > 0) {
                        error_log('New LP - Course has changed, discard lp object', 0);
                    }
                    $oLP = null;
                    Session::erase('oLP');
                    Session::erase('lpobject');
                } else {
                    Session::write('oLP', $oLP);
                }
            }
        }
        /** @var learnpath $lpFromSession */
        $lpFromSession = Session::read('oLP');
        if (isset($lpFromSession) && isset($_GET['lp_id'])) {
            $previous = $lpFromSession->select_previous_item_id();
            $parent = 0;
            // Add a Quiz as Lp Item
            $lpFromSession->add_item($parent, $previous, TOOL_QUIZ, $quiz_id, $quiz_title, '');
            // Redirect to home page for add more content
            header('location: ../newscorm/lp_controller.php?' . api_get_cidreq() . '&action=add_item&type=step&lp_id=' . intval($_GET['lp_id']));
            exit;
        } else {
            echo '<script>window.location.href = "' . api_get_path(WEB_CODE_PATH) . 'exercice/admin.php?' . api_get_cidReq() . '&exerciseId=' . $quiz_id . '&session_id=' . api_get_session_id() . '"</script>';
        }
    }
}