@@ -2599,85 +2599,253 @@ public function manage_answer(
25992599 }
26002600 break ;
26012601 case FILL_IN_BLANKS :
2602-
2603- // insert the student result in the track_e_attempt table, field answer
2604- // $answer is the answer like in the c_quiz_answer table for the question
2605- // student data are choice[]
2606-
2607- $ listCorrectAnswers = FillBlanks::getAnswerInfo ($ answer );
2608- $ switchableAnswerSet = $ listCorrectAnswers ["switchable " ];
2609- $ answerWeighting = $ listCorrectAnswers ["tabweighting " ];
2610- // user choices is an array $choice
2611-
2612- // get existing user data in n the BDD
2602+ $ str = '' ;
26132603 if ($ from_database ) {
26142604 $ sql = "SELECT answer
2615- FROM $ TBL_TRACK_ATTEMPT
2616- WHERE
2617- exe_id = $ exeId AND
2618- question_id= " .intval ($ questionId );
2605+ FROM $ TBL_TRACK_ATTEMPT
2606+ WHERE
2607+ exe_id = $ exeId AND
2608+ question_id= " .intval ($ questionId );
26192609 $ result = Database::query ($ sql );
26202610 $ str = Database::result ($ result , 0 , 'answer ' );
2621-
2622- $ listStudentResults = FillBlanks::getAnswerInfo ($ str , true );
2623- $ choice = $ listStudentResults ['studentanswer ' ];
26242611 }
26252612
2626- // loop other all blanks words
2627- if (!$ switchableAnswerSet ) {
2628- // not switchable answer, must be in the same place than teacher order
2629- for ($ i =0 ; $ i < count ($ listCorrectAnswers ['tabwords ' ]); $ i ++) {
2630- $ studentAnswer = isset ($ choice [$ i ]) ? trim ($ choice [$ i ]) : '' ;
2613+ if ($ saved_results == false && strpos ($ str , 'font color ' ) !== false ) {
2614+ // the question is encoded like this
2615+ // [A] B [C] D [E] F::10,10,10@1
2616+ // number 1 before the "@" means that is a switchable fill in blank question
2617+ // [A] B [C] D [E] F::10,10,10@ or [A] B [C] D [E] F::10,10,10
2618+ // means that is a normal fill blank question
2619+ // first we explode the "::"
2620+ $ pre_array = explode (':: ' , $ answer );
2621+
2622+ // is switchable fill blank or not
2623+ $ last = count ($ pre_array ) - 1 ;
2624+ $ is_set_switchable = explode ('@ ' , $ pre_array [$ last ]);
2625+ $ switchable_answer_set = false ;
2626+ if (isset ($ is_set_switchable [1 ]) && $ is_set_switchable [1 ] == 1 ) {
2627+ $ switchable_answer_set = true ;
2628+ }
2629+ $ answer = '' ;
2630+ for ($ k = 0 ; $ k < $ last ; $ k ++) {
2631+ $ answer .= $ pre_array [$ k ];
2632+ }
2633+ // splits weightings that are joined with a comma
2634+ $ answerWeighting = explode (', ' , $ is_set_switchable [0 ]);
2635+ // we save the answer because it will be modified
2636+ $ temp = $ answer ;
2637+ $ answer = '' ;
2638+ $ j = 0 ;
2639+ //initialise answer tags
2640+ $ user_tags = $ correct_tags = $ real_text = array ();
2641+ // the loop will stop at the end of the text
2642+ while (1 ) {
2643+ // quits the loop if there are no more blanks (detect '[')
2644+ if (($ pos = api_strpos ($ temp , '[ ' )) === false ) {
2645+ // adds the end of the text
2646+ $ answer = $ temp ;
2647+ $ real_text [] = $ answer ;
2648+ break ; //no more "blanks", quit the loop
2649+ }
2650+ // adds the piece of text that is before the blank
2651+ //and ends with '[' into a general storage array
2652+ $ real_text [] = api_substr ($ temp , 0 , $ pos +1 );
2653+ $ answer .= api_substr ($ temp , 0 , $ pos +1 );
2654+ //take the string remaining (after the last "[" we found)
2655+ $ temp = api_substr ($ temp , $ pos +1 );
2656+ // quit the loop if there are no more blanks, and update $pos to the position of next ']'
2657+ if (($ pos = api_strpos ($ temp , '] ' )) === false ) {
2658+ // adds the end of the text
2659+ $ answer .= $ temp ;
2660+ break ;
2661+ }
2662+ if ($ from_database ) {
2663+ $ queryfill = "SELECT answer FROM " .$ TBL_TRACK_ATTEMPT ."
2664+ WHERE
2665+ exe_id = ' " .$ exeId ."' AND
2666+ question_id= " .intval ($ questionId )."" ;
2667+ $ resfill = Database::query ($ queryfill );
2668+ $ str = Database::result ($ resfill , 0 , 'answer ' );
2669+ api_preg_match_all ('#\[([^[]*)\]# ' , $ str , $ arr );
2670+ $ str = str_replace ('\r\n ' , '' , $ str );
2671+
2672+ $ choice = $ arr [1 ];
2673+ if (isset ($ choice [$ j ])) {
2674+ $ tmp = api_strrpos ($ choice [$ j ], ' / ' );
2675+ $ choice [$ j ] = api_substr ($ choice [$ j ], 0 , $ tmp );
2676+ $ choice [$ j ] = trim ($ choice [$ j ]);
2677+ // Needed to let characters ' and " to work as part of an answer
2678+ $ choice [$ j ] = stripslashes ($ choice [$ j ]);
2679+ } else {
2680+ $ choice [$ j ] = null ;
2681+ }
2682+ } else {
2683+ // This value is the user input, not escaped while correct answer is escaped by fckeditor
2684+ $ choice [$ j ] = api_htmlentities (trim ($ choice [$ j ]));
2685+ }
2686+
2687+ $ user_tags [] = $ choice [$ j ];
2688+ //put the contents of the [] answer tag into correct_tags[]
2689+ $ correct_tags [] = api_substr ($ temp , 0 , $ pos );
2690+ $ j ++;
2691+ $ temp = api_substr ($ temp , $ pos +1 );
2692+ }
2693+ $ answer = '' ;
2694+ $ real_correct_tags = $ correct_tags ;
2695+ $ chosen_list = array ();
26312696
2632- // This value is the user input, not escaped while correct answer is escaped by fckeditor
2633- // Works with cyrillic alphabet and when using ">" chars see #7718 #7610 #7618
2634- if (!$ from_database ) {
2635- $ studentAnswer = htmlentities (
2636- api_utf8_encode ($ studentAnswer )
2637- );
2697+ for ($ i = 0 ; $ i < count ($ real_correct_tags ); $ i ++) {
2698+ if ($ i == 0 ) {
2699+ $ answer .= $ real_text [0 ];
2700+ }
2701+ if (!$ switchable_answer_set ) {
2702+ // Needed to parse ' and " characters
2703+ $ user_tags [$ i ] = stripslashes ($ user_tags [$ i ]);
2704+ if ($ correct_tags [$ i ] == $ user_tags [$ i ]) {
2705+ // gives the related weighting to the student
2706+ $ questionScore += $ answerWeighting [$ i ];
2707+ // increments total score
2708+ $ totalScore += $ answerWeighting [$ i ];
2709+ // adds the word in green at the end of the string
2710+ $ answer .= $ correct_tags [$ i ];
2711+ } elseif (!empty ($ user_tags [$ i ])) {
2712+ // else if the word entered by the student IS NOT the same as the one defined by the professor
2713+ // adds the word in red at the end of the string, and strikes it
2714+ $ answer .= '<font color="red"><s> ' . $ user_tags [$ i ] . '</s></font> ' ;
2715+ } else {
2716+ // adds a tabulation if no word has been typed by the student
2717+ $ answer .= '' ; // remove that causes issue
2718+ }
2719+ } else {
2720+ // switchable fill in the blanks
2721+ if (in_array ($ user_tags [$ i ], $ correct_tags )) {
2722+ $ chosen_list [] = $ user_tags [$ i ];
2723+ $ correct_tags = array_diff ($ correct_tags , $ chosen_list );
2724+ // gives the related weighting to the student
2725+ $ questionScore += $ answerWeighting [$ i ];
2726+ // increments total score
2727+ $ totalScore += $ answerWeighting [$ i ];
2728+ // adds the word in green at the end of the string
2729+ $ answer .= $ user_tags [$ i ];
2730+ } elseif (!empty ($ user_tags [$ i ])) {
2731+ // else if the word entered by the student IS NOT the same as the one defined by the professor
2732+ // adds the word in red at the end of the string, and strikes it
2733+ $ answer .= '<font color="red"><s> ' . $ user_tags [$ i ] . '</s></font> ' ;
2734+ } else {
2735+ // adds a tabulation if no word has been typed by the student
2736+ $ answer .= '' ; // remove that causes issue
2737+ }
26382738 }
26392739
2640- $ correctAnswer = $ listCorrectAnswers ['tabwords ' ][$ i ];
2641- $ isAnswerCorrect = 0 ;
2642- if (FillBlanks::isGoodStudentAnswer ($ studentAnswer , $ correctAnswer )) {
2643- // gives the related weighting to the student
2644- $ questionScore += $ answerWeighting [$ i ];
2645- // increments total score
2646- $ totalScore += $ answerWeighting [$ i ];
2647- $ isAnswerCorrect = 1 ;
2740+ // adds the correct word, followed by ] to close the blank
2741+ $ answer .= ' / <font color="green"><b> ' . $ real_correct_tags [$ i ] . '</b></font>] ' ;
2742+ if (isset ($ real_text [$ i +1 ])) {
2743+ $ answer .= $ real_text [$ i +1 ];
26482744 }
2649- $ listCorrectAnswers ['studentanswer ' ][$ i ] = $ studentAnswer ;
2650- $ listCorrectAnswers ['studentscore ' ][$ i ] = $ isAnswerCorrect ;
26512745 }
26522746 } else {
2653- // switchable answer
2654- $ listStudentAnswerTemp = $ choice ;
2655- $ listTeacherAnswerTemp = $ listCorrectAnswers ['tabwords ' ];
2656- // for every teacher answer, check if there is a student answer
2657- for ($ i =0 ; $ i < count ($ listStudentAnswerTemp ); $ i ++) {
2658- $ studentAnswer = trim ($ listStudentAnswerTemp [$ i ]);
2659- $ found = false ;
2660- for ($ j =0 ; $ j < count ($ listTeacherAnswerTemp ); $ j ++) {
2661- $ correctAnswer = $ listTeacherAnswerTemp [$ j ];
2662- if (!$ found ) {
2663- if (FillBlanks::isGoodStudentAnswer ($ studentAnswer , $ correctAnswer )) {
2664- $ questionScore += $ answerWeighting [$ i ];
2665- $ totalScore += $ answerWeighting [$ i ];
2666- $ listTeacherAnswerTemp [$ j ] = "" ;
2667- $ found = true ;
2668- }
2747+ // insert the student result in the track_e_attempt table, field answer
2748+ // $answer is the answer like in the c_quiz_answer table for the question
2749+ // student data are choice[]
2750+ $ listCorrectAnswers = FillBlanks::getAnswerInfo (
2751+ $ answer
2752+ );
2753+ $ switchableAnswerSet = $ listCorrectAnswers ["switchable " ];
2754+ $ answerWeighting = $ listCorrectAnswers ["tabweighting " ];
2755+ // user choices is an array $choice
2756+
2757+ // get existing user data in n the BDD
2758+ if ($ from_database ) {
2759+ $ sql = "SELECT answer
2760+ FROM $ TBL_TRACK_ATTEMPT
2761+ WHERE
2762+ exe_id = $ exeId AND
2763+ question_id= " .intval ($ questionId );
2764+ $ result = Database::query ($ sql );
2765+ $ str = Database::result ($ result , 0 , 'answer ' );
2766+ $ listStudentResults = FillBlanks::getAnswerInfo (
2767+ $ str ,
2768+ true
2769+ );
2770+ $ choice = $ listStudentResults ['studentanswer ' ];
2771+ }
2772+
2773+ // loop other all blanks words
2774+ if (!$ switchableAnswerSet ) {
2775+ // not switchable answer, must be in the same place than teacher order
2776+ for ($ i = 0 ; $ i < count (
2777+ $ listCorrectAnswers ['tabwords ' ]
2778+ ); $ i ++) {
2779+ $ studentAnswer = isset ($ choice [$ i ]) ? trim (
2780+ $ choice [$ i ]
2781+ ) : '' ;
2782+
2783+ // This value is the user input, not escaped while correct answer is escaped by fckeditor
2784+ // Works with cyrillic alphabet and when using ">" chars see #7718 #7610 #7618
2785+ if (!$ from_database ) {
2786+ $ studentAnswer = htmlentities (
2787+ api_utf8_encode ($ studentAnswer )
2788+ );
2789+ }
2790+
2791+ $ correctAnswer = $ listCorrectAnswers ['tabwords ' ][$ i ];
2792+ $ isAnswerCorrect = 0 ;
2793+ if (FillBlanks::isGoodStudentAnswer (
2794+ $ studentAnswer ,
2795+ $ correctAnswer
2796+ )
2797+ ) {
2798+ // gives the related weighting to the student
2799+ $ questionScore += $ answerWeighting [$ i ];
2800+ // increments total score
2801+ $ totalScore += $ answerWeighting [$ i ];
2802+ $ isAnswerCorrect = 1 ;
26692803 }
2804+ $ listCorrectAnswers ['studentanswer ' ][$ i ] = $ studentAnswer ;
2805+ $ listCorrectAnswers ['studentscore ' ][$ i ] = $ isAnswerCorrect ;
26702806 }
2671- $ listCorrectAnswers ['studentanswer ' ][$ i ] = $ studentAnswer ;
2672- if (!$ found ) {
2673- $ listCorrectAnswers ['studentscore ' ][$ i ] = 0 ;
2674- } else {
2675- $ listCorrectAnswers ['studentscore ' ][$ i ] = 1 ;
2807+ } else {
2808+ // switchable answer
2809+ $ listStudentAnswerTemp = $ choice ;
2810+ $ listTeacherAnswerTemp = $ listCorrectAnswers ['tabwords ' ];
2811+ // for every teacher answer, check if there is a student answer
2812+ for ($ i = 0 ; $ i < count (
2813+ $ listStudentAnswerTemp
2814+ ); $ i ++) {
2815+ $ studentAnswer = trim (
2816+ $ listStudentAnswerTemp [$ i ]
2817+ );
2818+ $ found = false ;
2819+ for ($ j = 0 ; $ j < count (
2820+ $ listTeacherAnswerTemp
2821+ ); $ j ++) {
2822+ $ correctAnswer = $ listTeacherAnswerTemp [$ j ];
2823+ if (!$ found ) {
2824+ if (FillBlanks::isGoodStudentAnswer (
2825+ $ studentAnswer ,
2826+ $ correctAnswer
2827+ )
2828+ ) {
2829+ $ questionScore += $ answerWeighting [$ i ];
2830+ $ totalScore += $ answerWeighting [$ i ];
2831+ $ listTeacherAnswerTemp [$ j ] = "" ;
2832+ $ found = true ;
2833+ }
2834+ }
2835+ }
2836+ $ listCorrectAnswers ['studentanswer ' ][$ i ] = $ studentAnswer ;
2837+ if (!$ found ) {
2838+ $ listCorrectAnswers ['studentscore ' ][$ i ] = 0 ;
2839+ } else {
2840+ $ listCorrectAnswers ['studentscore ' ][$ i ] = 1 ;
2841+ }
26762842 }
26772843 }
2844+ $ answer = FillBlanks::getAnswerInStudentAttempt (
2845+ $ listCorrectAnswers
2846+ );
26782847 }
26792848
2680- $ answer = FillBlanks::getAnswerInStudentAttempt ($ listCorrectAnswers );
26812849 break ;
26822850 // for calculated answer
26832851 case CALCULATED_ANSWER :
@@ -3426,7 +3594,8 @@ public function manage_answer(
34263594 $ answer ,
34273595 $ exeId ,
34283596 $ questionId ,
3429- $ results_disabled
3597+ $ results_disabled ,
3598+ $ str
34303599 );
34313600 break ;
34323601 case CALCULATED_ANSWER :
0 commit comments