diff --git a/main/exercice/exercice.php b/main/exercice/exercice.php index 5ad6b09b33..114b248fdb 100755 --- a/main/exercice/exercice.php +++ b/main/exercice/exercice.php @@ -427,10 +427,10 @@ if ($show != 'result') { require_once (api_get_path(LIBRARY_PATH) . 'statsUtils.lib.inc.php'); if ($is_allowedToEdit && !empty ($choice) && $choice == 'exportqti2') { - require_once ('export/qti2/qti2_export.php'); + require_once 'export/qti2/qti2_export.php'; $export = export_exercise($exerciseId, true); - require_once (api_get_path(LIBRARY_PATH) . 'pclzip/pclzip.lib.php'); + require_once api_get_path(LIBRARY_PATH) . 'pclzip/pclzip.lib.php'; $archive_path = api_get_path(SYS_ARCHIVE_PATH); $temp_dir_short = uniqid(); $temp_zip_dir = $archive_path . "/" . $temp_dir_short; @@ -786,6 +786,8 @@ if (($is_allowedToEdit) and ($origin != 'learnpath')) { echo '' . Display :: return_icon('new_test.gif', get_lang('NewEx')) . get_lang('NewEx') . ''; echo '' . Display :: return_icon('question_add.gif', get_lang('AddQuestionToExercise')) . get_lang('AddQuestionToExercise') . ''; echo '' . Display :: return_icon('jqz.gif', get_lang('ImportHotPotatoesQuiz')) . get_lang('ImportHotPotatoesQuiz') . ''; + // link to import qti2 ... + echo '' . Display :: return_icon('jqz.gif', get_lang('ImportQtiQuiz')) . get_lang('ImportQtiQuiz') . ''; echo '' . Display :: return_icon('show_test_results.gif', get_lang('Results')) . get_lang('Results') . ''; } @@ -869,9 +871,9 @@ if ($show == 'test') { $myorigin = (empty ($origin) ? '' : '&origin=' . $origin); $mylpid = (empty ($learnpath_id) ? '' : '&learnpath_id=' . $learnpath_id); $mylpitemid = (empty ($learnpath_item_id) ? '' : '&learnpath_item_id=' . $learnpath_item_id); - - $token = Security::get_token(); - + + $token = Security::get_token(); + while ($row = Database :: fetch_array($result)) { //validacion when belongs to a session $session_img = api_get_session_image($row['session_id'], $_user['status']); @@ -907,15 +909,13 @@ if ($show == 'test') { } else { echo $rowi . ' ' . api_strtolower(get_lang(($rowi > 1 ? 'Questions' : 'Question'))) . ''; } - - //echo ''; ?> - <?php echo api_htmlentities(get_lang('Edit'),ENT_QUOTES,$charset); ?> - - ')) return false;"><?php echo api_htmlentities(get_lang('CopyExercise'),ENT_QUOTES,$charset); ?> + <?php echo api_htmlentities(get_lang('Edit'),ENT_QUOTES,$charset); ?> + + ')) return false;"><?php echo api_htmlentities(get_lang('CopyExercise'),ENT_QUOTES,$charset); ?> ')) return false;" ><?php echo api_htmlentities(get_lang('CleanStudentResults'),ENT_QUOTES,$charset); ?> - + <?php echo api_htmlentities(get_lang('Activate'),ENT_QUOTES,$charset); ?> + '; + echo ""; echo "\n"; } else { // student only @@ -1365,7 +1370,7 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { } $parameters=array('cidReq'=>Security::remove_XSS($_GET['cidReq']),'show'=>Security::remove_XSS($_GET['show']),'filter' => Security::remove_XSS($_GET['filter']),'gradebook' =>Security::remove_XSS($_GET['gradebook'])); - + $table = new SortableTableFromArrayConfig($list_info, 1,20,'quiz_table'); $table->set_additional_parameters($parameters); if ($is_allowedToEdit || $is_tutor) { diff --git a/main/exercice/export/exercise_import.inc.php b/main/exercice/export/exercise_import.inc.php index 3ecd9e329b..27122b6b17 100644 --- a/main/exercice/export/exercise_import.inc.php +++ b/main/exercice/export/exercise_import.inc.php @@ -1,5 +1,7 @@ -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 + my_delete($baseWorkDir . $uploadPath); + $operation = true; + } + return $operation; +} - //find each question repository in the uploaded exercise folder +function parse_file($exercisePath, $file, $questionFile) { + global $exercise_info; + global $element_pile; + global $non_HTML_tag_to_avoid; + global $record_item_body; + global $questionTempDir; + + $questionTempDir = $exercisePath . '/' . $file . '/'; + $questionFilePath = $questionTempDir . $questionFile; + + if (!($fp = @ fopen($questionFilePath, 'r'))) { + Display :: display_error_message(get_lang('Error opening question\'s XML file')); + return false; + } else { + $data = fread($fp, filesize($questionFilePath)); + } + + //parse XML question file + + //used global variable start values declaration : + + $record_item_body = false; + $non_HTML_tag_to_avoid = array ( + "SIMPLECHOICE", + "CHOICEINTERACTION", + "INLINECHOICEINTERACTION", + "INLINECHOICE", + "SIMPLEMATCHSET", + "SIMPLEASSOCIABLECHOICE", + "TEXTENTRYINTERACTION", + "FEEDBACKINLINE", + "MATCHINTERACTION", + "ITEMBODY", + "BR", + "IMG" + ); + + //this array to detect tag not supported by claroline import in the xml file to warn the user. + + $non_supported_content_in_question = array ( + "GAPMATCHINTERACTION", + "EXTENDEDTEXTINTERACTION", + "HOTTEXTINTERACTION", + "HOTSPOTINTERACTION", + "SELECTPOINTINTERACTION", + "GRAPHICORDERINTERACTION", + "GRAPHICASSOCIATIONINTERACTION", + "GRAPHICGAPMATCHINTERACTION", + "POSITIONOBJECTINTERACTION", + "SLIDERINTERACTION", + "DRAWINGINTERACTION", + "UPLOADINTERACTION", + "RESPONSECONDITION", + "RESPONSEIF" + ); + $question_format_supported = true; + + $xml_parser = xml_parser_create(); + xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, false); + xml_set_element_handler($xml_parser, 'startElement', 'endElement'); + xml_set_character_data_handler($xml_parser, 'elementData'); + + if (!xml_parse($xml_parser, $data, feof($fp))) { + // if reading of the xml file in not successfull : + // set errorFound, set error msg, break while statement + Display :: display_error_message(get_lang('Error reading XML file')); + return false; + } + + //close file + fclose($fp); + if (!$question_format_supported) { + Display :: display_error_message(get_lang('Unknown question format in file %file', array ( + '%file' => $questionFile + ))); + return false; + } + return true; +} - array_push ($backlog_message, get_lang('XML question files found : ')); +/** + * Function used by the SAX xml parser when the parser meets a opening tag + * + * @param unknown_type $parser xml parser created with "xml_parser_create()" + * @param unknown_type $name name of the element + * @param unknown_type $attributes + */ - $question_number = 0; +function startElement($parser, $name, $attributes) { + global $element_pile; + global $exercise_info; + global $current_question_ident; + global $current_answer_id; + global $current_match_set; + global $currentAssociableChoice; + global $current_question_item_body; + global $record_item_body; + global $non_HTML_tag_to_avoid; + global $current_inlinechoice_id; + global $cardinality; + global $questionTempDir; + + array_push($element_pile, $name); + $current_element = end($element_pile); + if (sizeof($element_pile) >= 2) + $parent_element = $element_pile[sizeof($element_pile) - 2]; + else + $parent_element = ""; + if (sizeof($element_pile) >= 3) + $grant_parent_element = $element_pile[sizeof($element_pile) - 3]; + else + $grant_parent_element = ""; + + if ($record_item_body) { + + if ((!in_array($current_element, $non_HTML_tag_to_avoid))) { + $current_question_item_body .= "<" . $name; + + foreach ($attributes as $attribute_name => $attribute_value) { + $current_question_item_body .= " " . $attribute_name . "=\"" . $attribute_value . "\""; + } + $current_question_item_body .= ">"; + } else { + //in case of FIB question, we replace the IMS-QTI tag b y the correct answer between "[" "]", + //we first save with claroline tags ,then when the answer will be parsed, the claroline tags will be replaced - //used to specify the question directory where files could be found in relation in any question + if ($current_element == 'INLINECHOICEINTERACTION') { - global $questionTempDir; + $current_question_item_body .= "**claroline_start**" . $attributes['RESPONSEIDENTIFIER'] . "**claroline_end**"; + } + if ($current_element == 'TEXTENTRYINTERACTION') { + $correct_answer_value = $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id]; + $current_question_item_body .= "[" . $correct_answer_value . "]"; + } + if ($current_element == 'BR') { + $current_question_item_body .= "
"; + } + } - //1- parse the parent directory + } - $questionHandle = opendir($exercisePath); + switch ($current_element) { + case 'ASSESSMENTITEM' : + { + //retrieve current question + + $current_question_ident = $attributes['IDENTIFIER']; + $exercise_info['question'][$current_question_ident] = array (); + $exercise_info['question'][$current_question_ident]['answer'] = array (); + $exercise_info['question'][$current_question_ident]['correct_answers'] = array (); + $exercise_info['question'][$current_question_ident]['title'] = $attributes['TITLE']; + $exercise_info['question'][$current_question_ident]['tempdir'] = $questionTempDir; + } + break; - while (false !== ($questionFile = readdir($questionHandle))) - { - if (preg_match('/.xml$/i' ,$questionFile)) - { - array_push ($backlog_message, get_lang("XML question file found : ".$questionFile)); - parse_file($exercisePath, '', $questionFile); - }//end if xml question file found - }//end while question rep + case 'SECTION' : + { + //retrieve exercise name + $exercise_info['name'] = $attributes['TITLE']; - //2- parse every subdirectory to search xml question files + } + break; - while (false !== ($file = readdir($exerciseHandle))) - { + case 'RESPONSEDECLARATION' : + { + //retrieve question type - if (is_dir($exercisePath.$file) && $file != "." && $file != "..") - { - //find each manifest for each question repository found + if ("multiple" == $attributes['CARDINALITY']) { + $exercise_info['question'][$current_question_ident]['type'] = 'MCMA'; + $cardinality = 'multiple'; + } + if ("single" == $attributes['CARDINALITY']) { + $exercise_info['question'][$current_question_ident]['type'] = 'MCUA'; + $cardinality = 'single'; + } - $questionHandle = opendir($exercisePath.$file); + //needed for FIB - while (false !== ($questionFile = readdir($questionHandle))) - { - if (preg_match('/.xml$/i' ,$questionFile)) - { - parse_file($exercisePath, $file, $questionFile); - }//end if xml question file found - }//end while question rep - } //if is_dir - }//end while loop to find each question data's + $current_answer_id = $attributes['IDENTIFIER']; + } + break; - //Display data found + case 'INLINECHOICEINTERACTION' : + { + $exercise_info['question'][$current_question_ident]['type'] = 'FIB'; + $exercise_info['question'][$current_question_ident]['subtype'] = 'LISTBOX_FILL'; + $current_answer_id = $attributes['RESPONSEIDENTIFIER']; - array_push ($backlog_message, 'Exercise name : ' . $exercise_info['name'] . ''); - array_push ($backlog_message, 'Exercise description : ' . $exercise_info['description']); + } + break; - foreach ($exercise_info['question'] as $key => $question) - { - $question_number++; - array_push ($backlog_message, ''.$question_number.'- Question found (' .$key. ') : ' . $question['title'] . ''); - if (isset($question['statement'])) array_push ($backlog_message, '* Statement : ' . $question['statement']); - array_push ($backlog_message, '* Type : ' . $question['type']); + case 'INLINECHOICE' : + { + $current_inlinechoice_id = $attributes['IDENTIFIER']; + } + break; - foreach ($exercise_info['question'][$key]['answer'] as $answer) - { - if ($question['type']=="MATCHING") - { - array_push ($backlog_message, '** Matchset : '); - foreach ($answer as $matchSetElement) - { - array_push ($backlog_message, '*** Element ' . $matchSetElement); - } - } - else - { - array_push ($backlog_message, '** Answer found : ' . $answer['value']); - if (isset($answer['feedback'])) array_push ($backlog_message, '*** Answer feedback : ' . $answer['feedback']); - } - } + case 'TEXTENTRYINTERACTION' : + { + $exercise_info['question'][$current_question_ident]['type'] = 'FIB'; + $exercise_info['question'][$current_question_ident]['subtype'] = 'TEXTFIELD_FILL'; + $exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body; - if (isset($question['weighting'])) - { - array_push ($backlog_message, '* WEIGHTING for Answers :'); - foreach ($question['weighting'] as $key => $weighting) - { - array_push ($backlog_message, '** Answer : '.$key.' ==> weighting : '.$weighting); - } - } - - if (isset($question['correct_answers'])) - { - array_push ($backlog_message, '* CORRECT ANSWERS :'); - foreach ($question['correct_answers'] as $answerIdent) - { - array_push ($backlog_message, '* Answer : '.$answerIdent); - } - } - - if (isset($question['response_text'])) - { - array_push ($backlog_message, '* Text to fill in : '.$question['response_text'] ); - } - } - - //--------------------- - //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 - { - array_push ($backlog_message, 'EXERCISE DATA INVALID !!!'); - } - - //For each question found... - - foreach($exercise_info['question'] as $key => $question_array) - { - //2.create question - - $question = new ImsQuestion(); - - if (isset($question_array['title'])) $question->setTitle($question_array['title']); - if (isset($question_array['statement'])) $question->setDescription($question_array['statement']); - $question->setType($question_array['type']); - - if ($question->validate()) - { - $question_id = $question->save(); - - if ($question_id) - { - //3.create answers - - $question->setAnswer(); - $question->import($exercise_info['question'][$key], $exercise_info['question'][$key]['tempdir']); - $exercise->addQuestion($question_id); - $question->answer->save(); - $question->save(); - } - else - { - array_push ($backlog_message, 'IMPOSSIBLE TO SAVE QUESTION !!!'); - } - } - else - { - array_push ($backlog_message, 'QUESTION DATA INVALID !!!'); - } - } - $link = "
".get_lang('See the exercise')."
"; - array_push ($backlog_message, $link); - - //delete the temp dir where the exercise was unzipped - - claro_delete_file($exercisePath); - - return $backlog_message; -} + //replace claroline tags + } + break; + case 'MATCHINTERACTION' : + { + $exercise_info['question'][$current_question_ident]['type'] = 'MATCHING'; + } + break; -function parse_file($exercisePath, $file, $questionFile) -{ - global $exercise_info; - global $element_pile; - global $non_HTML_tag_to_avoid; - global $record_item_body; - - $questionTempDir = $exercisePath.$file.'/'; - $questionFilePath = $questionTempDir.$questionFile; - $backlog_message = array(); - array_push ($backlog_message, "* ".$questionFile); - - if (!($fp = @fopen($questionFilePath, 'r'))) - { - array_push ($backlog_message, get_lang("Error opening question's XML file")); - return $backlog_message; - } - else - { - $data = fread($fp, filesize( $questionFilePath)); - } - - //parse XML question file - - //used global variable start values declaration : - - $record_item_body = false; - $non_HTML_tag_to_avoid = array( - "SIMPLECHOICE", - "CHOICEINTERACTION", - "INLINECHOICEINTERACTION", - "INLINECHOICE", - "SIMPLEMATCHSET", - "SIMPLEASSOCIABLECHOICE", - "TEXTENTRYINTERACTION", - "FEEDBACKINLINE", - "MATCHINTERACTION", - "ITEMBODY", - "BR", - "IMG" - ); - - //this array to detect tag not supported by claroline import in the xml file to warn the user. - - $non_supported_content_in_question = array( - "GAPMATCHINTERACTION", - "EXTENDEDTEXTINTERACTION", - "HOTTEXTINTERACTION", - "HOTSPOTINTERACTION", - "SELECTPOINTINTERACTION", - "GRAPHICORDERINTERACTION", - "GRAPHICASSOCIATIONINTERACTION", - "GRAPHICGAPMATCHINTERACTION", - "POSITIONOBJECTINTERACTION", - "SLIDERINTERACTION", - "DRAWINGINTERACTION", - "UPLOADINTERACTION", - "RESPONSECONDITION", - "RESPONSEIF" - ); - $question_format_supported = true; - - $xml_parser = xml_parser_create(); - xml_set_element_handler($xml_parser, 'startElement', 'endElement'); - xml_set_character_data_handler($xml_parser, 'elementData'); - - if (!xml_parse($xml_parser, $data, feof($fp))) - { - // if reading of the xml file in not successfull : - // set errorFound, set error msg, break while statement - - array_push ($backlog_message, get_lang('Error reading XML file') ); - return $backlog_message; - } - - //close file - - fclose($fp); - - if ($question_format_supported) - { - array_push ($backlog_message, get_lang('Question format found') ); - } - else - { - array_push ($backlog_message, get_lang('ERROR in:'.$questionFile.' Question format unknown') ); - } -} + case 'SIMPLEMATCHSET' : + { + if (!isset ($current_match_set)) { + $current_match_set = 1; + } else { + $current_match_set++; + } + $exercise_info['question'][$current_question_ident]['answer'][$current_match_set] = array (); + } + break; + case 'SIMPLEASSOCIABLECHOICE' : + { + $currentAssociableChoice = $attributes['IDENTIFIER']; + } + break; -/** - * Function used by the SAX xml parser when the parser meets a opening tag - * - * @param unknown_type $parser xml parser created with "xml_parser_create()" - * @param unknown_type $name name of the element - * @param unknown_type $attributes - */ + //retrieve answers id for MCUA and MCMA questions -function startElement($parser, $name, $attributes) -{ - global $element_pile; - global $exercise_info; - global $current_question_ident; - global $current_answer_id; - global $current_match_set; - global $currentAssociableChoice; - global $current_question_item_body; - global $record_item_body; - global $non_HTML_tag_to_avoid; - global $current_inlinechoice_id; - global $cardinality; - global $questionTempDir; - - array_push($element_pile,$name); - $current_element = end($element_pile); - if (sizeof($element_pile)>=2) $parent_element = $element_pile[sizeof($element_pile)-2]; else $parent_element = ""; - if (sizeof($element_pile)>=3) $grant_parent_element = $element_pile[sizeof($element_pile)-3]; else $grant_parent_element =""; - - if ($record_item_body) - { - - if ((!in_array($current_element,$non_HTML_tag_to_avoid))) - { - $current_question_item_body .= "<".$name; - - foreach ($attributes as $attribute_name => $attribute_value) - { - $current_question_item_body .= " ".$attribute_name."=\"".$attribute_value."\""; - } - $current_question_item_body .= ">"; - } - else - { - //in case of FIB question, we replace the IMS-QTI tag b y the correct answer between "[" "]", - //we first save with claroline tags ,then when the answer will be parsed, the claroline tags will be replaced - - if ($current_element=='INLINECHOICEINTERACTION') - { - - $current_question_item_body .="**claroline_start**".$attributes['RESPONSEIDENTIFIER']."**claroline_end**"; - } - if ($current_element=='TEXTENTRYINTERACTION') - { - $correct_answer_value = $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id]; - $current_question_item_body .= "[".$correct_answer_value."]"; - - } - if ($current_element=='BR') - { - $current_question_item_body .= "
"; - } - } - - } - - switch ($current_element) - { - case 'ASSESSMENTITEM' : - { - //retrieve current question - - $current_question_ident = $attributes['IDENTIFIER']; - $exercise_info['question'][$current_question_ident] = array(); - $exercise_info['question'][$current_question_ident]['answer'] = array(); - $exercise_info['question'][$current_question_ident]['correct_answers'] = array(); - $exercise_info['question'][$current_question_ident]['title'] = $attributes['TITLE']; - $exercise_info['question'][$current_question_ident]['tempdir'] = $questionTempDir; - } - break; - - case 'SECTION' : - { - //retrieve exercise name - - $exercise_info['name'] = $attributes['TITLE']; - - } - break; + case 'SIMPLECHOICE' : + { + $current_answer_id = $attributes['IDENTIFIER']; + if (!isset ($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id])) { + $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id] = array (); + } + } + break; - case 'RESPONSEDECLARATION' : - { - //retrieve question type + case 'MAPENTRY' : + { + if ($parent_element == "MAPPING") { + $answer_id = $attributes['MAPKEY']; + + if (!isset ($exercise_info['question'][$current_question_ident]['weighting'])) { + $exercise_info['question'][$current_question_ident]['weighting'] = array (); + } + $exercise_info['question'][$current_question_ident]['weighting'][$answer_id] = $attributes['MAPPEDVALUE']; + } + } + break; - if ( "multiple" == $attributes['CARDINALITY']) + case 'MAPPING' : { - $exercise_info['question'][$current_question_ident]['type'] = 'MCMA'; - $cardinality = 'multiple'; + if (isset ($attributes['DEFAULTVALUE'])) { + $exercise_info['question'][$current_question_ident]['default_weighting'] = $attributes['DEFAULTVALUE']; + } } - if ( "single" == $attributes['CARDINALITY']) + + case 'ITEMBODY' : { - $exercise_info['question'][$current_question_ident]['type'] = 'MCUA'; - $cardinality = 'single'; + $record_item_body = true; + $current_question_item_body = ''; } + break; - //needed for FIB - - $current_answer_id = $attributes['IDENTIFIER']; - - } - break; - - case 'INLINECHOICEINTERACTION' : - { - $exercise_info['question'][$current_question_ident]['type'] = 'FIB'; - $exercise_info['question'][$current_question_ident]['subtype'] = 'LISTBOX_FILL'; - $current_answer_id = $attributes['RESPONSEIDENTIFIER']; - - } - break; - - case 'INLINECHOICE' : - { - $current_inlinechoice_id = $attributes['IDENTIFIER']; - } - break; - - case 'TEXTENTRYINTERACTION' : - { - $exercise_info['question'][$current_question_ident]['type'] = 'FIB'; - $exercise_info['question'][$current_question_ident]['subtype'] = 'TEXTFIELD_FILL'; - $exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body; - - //replace claroline tags - - } - break; - - case 'MATCHINTERACTION' : - { - $exercise_info['question'][$current_question_ident]['type'] = 'MATCHING'; - } - break; - - case 'SIMPLEMATCHSET' : - { - if (!isset($current_match_set)) - { - $current_match_set = 1; - } - else - { - $current_match_set++; - } - $exercise_info['question'][$current_question_ident]['answer'][$current_match_set] = array(); - } - break; - - case 'SIMPLEASSOCIABLECHOICE' : - { - $currentAssociableChoice = $attributes['IDENTIFIER']; - } - break; - - //retrieve answers id for MCUA and MCMA questions - - case 'SIMPLECHOICE': - { - $current_answer_id = $attributes['IDENTIFIER']; - if (!isset($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id])) - { - $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id] = array(); - } - } - break; - - case 'MAPENTRY': - { - if ($parent_element == "MAPPING") - { - $answer_id = $attributes['MAPKEY']; - - if (!isset($exercise_info['question'][$current_question_ident]['weighting'])) - { - $exercise_info['question'][$current_question_ident]['weighting'] = array(); - } - $exercise_info['question'][$current_question_ident]['weighting'][$answer_id] = $attributes['MAPPEDVALUE']; - } - } - break; - - case 'MAPPING': - { - if (isset($attributes['DEFAULTVALUE'])) - { - $exercise_info['question'][$current_question_ident]['default_weighting'] = $attributes['DEFAULTVALUE']; - } - } - - case 'ITEMBODY': - { - $record_item_body = true; - $current_question_item_body = ''; - } - break; - - case 'IMG' : - { - $exercise_info['question'][$current_question_ident]['attached_file_url'] = $attributes['SRC']; - } - break; - } + case 'IMG' : + { + $exercise_info['question'][$current_question_ident]['attached_file_url'] = $attributes['SRC']; + } + break; + } } /** @@ -604,150 +462,134 @@ function startElement($parser, $name, $attributes) * @param $name name of the element */ -function endElement($parser,$name) -{ - global $element_pile; - global $exercise_info; +function endElement($parser, $name) { + global $element_pile; + global $exercise_info; global $current_question_ident; - global $record_item_body; - global $current_question_item_body; - global $non_HTML_tag_to_avoid; - global $cardinality; + global $record_item_body; + global $current_question_item_body; + global $non_HTML_tag_to_avoid; + global $cardinality; $current_element = end($element_pile); - //treat the record of the full content of itembody tag : - - if ($record_item_body && (!in_array($current_element,$non_HTML_tag_to_avoid))) - { - $current_question_item_body .= ""; - } - - switch ($name) - { - case 'ITEMBODY': - { - $record_item_body = false; - if ($exercise_info['question'][$current_question_ident]['type']=='FIB') - { - $exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body; - } - else - { - $exercise_info['question'][$current_question_ident]['statement'] = $current_question_item_body; - } - } - break; - } - array_pop($element_pile); + //treat the record of the full content of itembody tag : + + if ($record_item_body && (!in_array($current_element, $non_HTML_tag_to_avoid))) { + $current_question_item_body .= ""; + } + + switch ($name) { + case 'ITEMBODY' : + { + $record_item_body = false; + if ($exercise_info['question'][$current_question_ident]['type'] == 'FIB') { + $exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body; + } else { + $exercise_info['question'][$current_question_ident]['statement'] = $current_question_item_body; + } + } + break; + } + array_pop($element_pile); } -function elementData($parser,$data) -{ +function elementData($parser, $data) { - global $element_pile; - global $exercise_info; + global $element_pile; + global $exercise_info; global $current_question_ident; - global $current_answer_id; - global $current_match_set; - global $currentAssociableChoice; - global $current_question_item_body; - global $record_item_body; - global $non_HTML_tag_to_avoid; - global $current_inlinechoice_id; - global $cardinality; - - $current_element = end($element_pile); - if (sizeof($element_pile)>=2) $parent_element = $element_pile[sizeof($element_pile)-2]; else $parent_element = ""; - if (sizeof($element_pile)>=3) $grant_parent_element = $element_pile[sizeof($element_pile)-3]; else $grant_parent_element = ""; + global $current_answer_id; + global $current_match_set; + global $currentAssociableChoice; + global $current_question_item_body; + global $record_item_body; + global $non_HTML_tag_to_avoid; + global $current_inlinechoice_id; + global $cardinality; + + $current_element = end($element_pile); + if (sizeof($element_pile) >= 2) + $parent_element = $element_pile[sizeof($element_pile) - 2]; + else + $parent_element = ""; + if (sizeof($element_pile) >= 3) + $grant_parent_element = $element_pile[sizeof($element_pile) - 3]; + else + $grant_parent_element = ""; //treat the record of the full content of itembody tag (needed for question statment and/or FIB text: - if ($record_item_body && (!in_array($current_element,$non_HTML_tag_to_avoid))) - { - $current_question_item_body .= $data; - } - - switch ($current_element) - { - case 'SIMPLECHOICE': - { - if (!isset($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'])) - { - $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'] = trim($data); - } - else - { - $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'] .= ' '.trim($data); - } - } - break; - - case 'FEEDBACKINLINE' : - { - if (!isset($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'])) - { - $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] = trim($data); - } - else - { - $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] .= ' '.trim($data); - } - } - break; - - case 'SIMPLEASSOCIABLECHOICE' : - { - $exercise_info['question'][$current_question_ident]['answer'][$current_match_set][$currentAssociableChoice] = trim($data); - } - break; - - case 'VALUE': - { - if ($parent_element=="CORRECTRESPONSE") - { - if ($cardinality=="single") - { - $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id] = $data; - } - else - { - $exercise_info['question'][$current_question_ident]['correct_answers'][] = $data; - } - } - } - break; - - case 'ITEMBODY' : - { - $current_question_item_body .= $data; - - } - break; - - case 'INLINECHOICE' : - { - - // if this is the right answer, then we must replace the claroline tags in the FIB text bye the answer between "[" and "]" : - - $answer_identifier = $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id]; - - if ($current_inlinechoice_id == $answer_identifier) - { - - $current_question_item_body = str_replace("**claroline_start**".$current_answer_id."**claroline_end**", "[".$data."]", $current_question_item_body); - } - else // save wrong answers in an array - { - if(!isset($exercise_info['question'][$current_question_ident]['wrong_answers'])) - { - $exercise_info['question'][$current_question_ident]['wrong_answers'] = array(); - } - $exercise_info['question'][$current_question_ident]['wrong_answers'][] = $data; - } - } - break; - } + if ($record_item_body && (!in_array($current_element, $non_HTML_tag_to_avoid))) { + $current_question_item_body .= $data; + } + + switch ($current_element) { + case 'SIMPLECHOICE' : + { + if (!isset ($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'])) { + $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'] = trim($data); + } else { + $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'] .= ' ' . trim($data); + } + } + break; + + case 'FEEDBACKINLINE' : + { + if (!isset ($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'])) { + $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] = trim($data); + } else { + $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] .= ' ' . trim($data); + } + } + break; + + case 'SIMPLEASSOCIABLECHOICE' : + { + $exercise_info['question'][$current_question_ident]['answer'][$current_match_set][$currentAssociableChoice] = trim($data); + } + break; + + case 'VALUE' : + { + if ($parent_element == "CORRECTRESPONSE") { + if ($cardinality == "single") { + $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id] = $data; + } else { + $exercise_info['question'][$current_question_ident]['correct_answers'][] = $data; + } + } + } + break; + + case 'ITEMBODY' : + { + $current_question_item_body .= $data; + + } + break; + + case 'INLINECHOICE' : + { + + // if this is the right answer, then we must replace the claroline tags in the FIB text bye the answer between "[" and "]" : + + $answer_identifier = $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id]; + + if ($current_inlinechoice_id == $answer_identifier) { + + $current_question_item_body = str_replace("**claroline_start**" . $current_answer_id . "**claroline_end**", "[" . $data . "]", $current_question_item_body); + } else // save wrong answers in an array + { + if (!isset ($exercise_info['question'][$current_question_ident]['wrong_answers'])) { + $exercise_info['question'][$current_question_ident]['wrong_answers'] = array (); + } + $exercise_info['question'][$current_question_ident]['wrong_answers'][] = $data; + } + } + break; + } } ?> \ No newline at end of file diff --git a/main/exercice/qti2.php b/main/exercice/qti2.php new file mode 100644 index 0000000000..eead6c2354 --- /dev/null +++ b/main/exercice/qti2.php @@ -0,0 +1,101 @@ +"./exercice.php", "name"=> get_lang('Exercices')); +$is_allowedToEdit = api_is_allowed_to_edit(null, true); + +/** + * This function displays the form for import of the zip file with qti2 + */ +function ch_qti2_display_form() { + $name_tools = get_lang('ImportQtiQuiz'); + $form = '
'; + $form .= '' . Display :: return_icon('message_reply_forum.png', get_lang('GoBackToQuestionList')) . get_lang('GoBackToQuestionList') . ''; + $form .= '
'; + $form .= '
'; + $form .= '
'.$name_tools.'
'; + $form .= '
'; + $form .= '
'; + $form .= '*'; + $form .= get_lang('DownloadFile').' :'; + $form .= '
'; + $form .= '
'; + $form .= '
+

+ +
'; + $form .= '
'; + echo $form; +} + +/** + * This function will import the zip file with the respective qti2 + * @param array $uploaded_file ($_FILES) + */ +function ch_qti2_import_file($array_file) { + $unzip = 0; + $lib_path = api_get_path(LIBRARY_PATH); + require_once $lib_path.'fileUpload.lib.php'; + require_once $lib_path.'fileManage.lib.php'; + $process = process_uploaded_file($array_file); + if (preg_match('/\.zip$/i', $array_file['name'])) { + // if it's a zip, allow zip upload + $unzip = 1; + } + if ($process == true && $unzip == 1) { + $main_path = api_get_path(SYS_CODE_PATH); + require_once $main_path.'exercice/export/exercise_import.inc.php'; + require_once $main_path.'exercice/export/qti2/qti2_classes.php'; + $imported = import_exercise($array_file['name']); + if ($imported == true) { + header('Location: exercice.php?' . Security::remove_XSS(api_get_cidreq()) .''); + } else { + Display::display_error_message(get_lang('The import was not performed')); + return false; + } + } +} + +// import file +if ((api_is_allowed_to_edit(null, true))) { + if (isset($_POST['submit'])) { + ch_qti2_import_file($_FILES['userFile']); + } +} + +// display header +Display::display_header($name_tools, get_lang('Exercise')); + +// display qti form +ch_qti2_display_form(); + +// display the footer +Display::display_footer(); +?> \ No newline at end of file diff --git a/main/exercice/question.class.php b/main/exercice/question.class.php index 74395f8ab3..0e0f6d1705 100755 --- a/main/exercice/question.class.php +++ b/main/exercice/question.class.php @@ -775,11 +775,11 @@ abstract class Question * @param - integer $exerciseId - exercise ID * @param - boolean $fromSave - comming from $this->save() or not */ - function addToList($exerciseId, $fromSave=FALSE) { - global $TBL_EXERCICE_QUESTION; - $id=$this->id; + function addToList($exerciseId, $fromSave = FALSE) { + $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); + $id = $this->id; // checks if the exercise ID is not in the list - if(!in_array($exerciseId,$this->exerciseList)) { + if (!in_array($exerciseId,$this->exerciseList)) { $this->exerciseList[]=$exerciseId; $sql="INSERT INTO $TBL_EXERCICE_QUESTION (question_id, exercice_id) VALUES('".Database::escape_string($id)."','".Database::escape_string($exerciseId)."')"; Database::query($sql);