| Conditions | 409 |
| Total Lines | 2499 |
| Code Lines | 1706 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.
There are several approaches to avoid long parameter lists:
| 1 | <?php |
||
| 3333 | public function manage_answer( |
||
| 3334 | $exeId, |
||
| 3335 | $questionId, |
||
| 3336 | $choice, |
||
| 3337 | $from = 'exercise_show', |
||
| 3338 | $exerciseResultCoordinates = [], |
||
| 3339 | $saved_results = true, |
||
| 3340 | $from_database = false, |
||
| 3341 | $show_result = true, |
||
| 3342 | $propagate_neg = 0, |
||
| 3343 | $hotspot_delineation_result = [], |
||
| 3344 | $showTotalScoreAndUserChoicesInLastAttempt = true, |
||
| 3345 | $updateResults = false |
||
| 3346 | ) { |
||
| 3347 | $debug = false; |
||
| 3348 | //needed in order to use in the exercise_attempt() for the time |
||
| 3349 | global $learnpath_id, $learnpath_item_id; |
||
| 3350 | require_once api_get_path(LIBRARY_PATH).'geometry.lib.php'; |
||
| 3351 | $em = Database::getManager(); |
||
| 3352 | $feedback_type = $this->selectFeedbackType(); |
||
| 3353 | $results_disabled = $this->selectResultsDisabled(); |
||
| 3354 | |||
| 3355 | if ($debug) { |
||
| 3356 | error_log("<------ manage_answer ------> "); |
||
| 3357 | error_log('exe_id: '.$exeId); |
||
| 3358 | error_log('$from: '.$from); |
||
| 3359 | error_log('$saved_results: '.intval($saved_results)); |
||
| 3360 | error_log('$from_database: '.intval($from_database)); |
||
| 3361 | error_log('$show_result: '.intval($show_result)); |
||
| 3362 | error_log('$propagate_neg: '.$propagate_neg); |
||
| 3363 | error_log('$exerciseResultCoordinates: '.print_r($exerciseResultCoordinates, 1)); |
||
| 3364 | error_log('$hotspot_delineation_result: '.print_r($hotspot_delineation_result, 1)); |
||
| 3365 | error_log('$learnpath_id: '.$learnpath_id); |
||
| 3366 | error_log('$learnpath_item_id: '.$learnpath_item_id); |
||
| 3367 | error_log('$choice: '.print_r($choice, 1)); |
||
| 3368 | } |
||
| 3369 | |||
| 3370 | $final_overlap = 0; |
||
| 3371 | $final_missing = 0; |
||
| 3372 | $final_excess = 0; |
||
| 3373 | $overlap_color = 0; |
||
| 3374 | $missing_color = 0; |
||
| 3375 | $excess_color = 0; |
||
| 3376 | $threadhold1 = 0; |
||
| 3377 | $threadhold2 = 0; |
||
| 3378 | $threadhold3 = 0; |
||
| 3379 | $arrques = null; |
||
| 3380 | $arrans = null; |
||
| 3381 | $studentChoice = null; |
||
| 3382 | $expectedAnswer = ''; |
||
| 3383 | $calculatedChoice = ''; |
||
| 3384 | $calculatedStatus = ''; |
||
| 3385 | $questionId = (int) $questionId; |
||
| 3386 | $exeId = (int) $exeId; |
||
| 3387 | $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
| 3388 | $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER); |
||
| 3389 | |||
| 3390 | // Creates a temporary Question object |
||
| 3391 | $course_id = $this->course_id; |
||
| 3392 | $objQuestionTmp = Question::read($questionId, $course_id); |
||
| 3393 | |||
| 3394 | if ($objQuestionTmp === false) { |
||
| 3395 | return false; |
||
| 3396 | } |
||
| 3397 | |||
| 3398 | $questionName = $objQuestionTmp->selectTitle(); |
||
| 3399 | $questionWeighting = $objQuestionTmp->selectWeighting(); |
||
| 3400 | $answerType = $objQuestionTmp->selectType(); |
||
| 3401 | $quesId = $objQuestionTmp->selectId(); |
||
| 3402 | $extra = $objQuestionTmp->extra; |
||
| 3403 | $next = 1; //not for now |
||
| 3404 | $totalWeighting = 0; |
||
| 3405 | $totalScore = 0; |
||
| 3406 | |||
| 3407 | // Extra information of the question |
||
| 3408 | if (( |
||
| 3409 | $answerType == MULTIPLE_ANSWER_TRUE_FALSE || |
||
| 3410 | $answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY |
||
| 3411 | ) |
||
| 3412 | && !empty($extra) |
||
| 3413 | ) { |
||
| 3414 | $extra = explode(':', $extra); |
||
| 3415 | if ($debug) { |
||
| 3416 | error_log(print_r($extra, 1)); |
||
| 3417 | } |
||
| 3418 | // Fixes problems with negatives values using intval |
||
| 3419 | |||
| 3420 | $true_score = floatval(trim($extra[0])); |
||
| 3421 | $false_score = floatval(trim($extra[1])); |
||
| 3422 | $doubt_score = floatval(trim($extra[2])); |
||
| 3423 | } |
||
| 3424 | |||
| 3425 | // Construction of the Answer object |
||
| 3426 | $objAnswerTmp = new Answer($questionId, $course_id); |
||
| 3427 | $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); |
||
| 3428 | |||
| 3429 | if ($debug) { |
||
| 3430 | error_log('Count of answers: '.$nbrAnswers); |
||
| 3431 | error_log('$answerType: '.$answerType); |
||
| 3432 | } |
||
| 3433 | |||
| 3434 | if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { |
||
| 3435 | $choiceTmp = $choice; |
||
| 3436 | $choice = isset($choiceTmp['choice']) ? $choiceTmp['choice'] : ''; |
||
| 3437 | $choiceDegreeCertainty = isset($choiceTmp['choiceDegreeCertainty']) ? $choiceTmp['choiceDegreeCertainty'] : ''; |
||
| 3438 | } |
||
| 3439 | |||
| 3440 | if ($answerType == FREE_ANSWER || |
||
| 3441 | $answerType == ORAL_EXPRESSION || |
||
| 3442 | $answerType == CALCULATED_ANSWER || |
||
| 3443 | $answerType == ANNOTATION |
||
| 3444 | ) { |
||
| 3445 | $nbrAnswers = 1; |
||
| 3446 | } |
||
| 3447 | |||
| 3448 | $generatedFile = ''; |
||
| 3449 | if ($answerType == ORAL_EXPRESSION) { |
||
| 3450 | $exe_info = Event::get_exercise_results_by_attempt($exeId); |
||
| 3451 | $exe_info = isset($exe_info[$exeId]) ? $exe_info[$exeId] : null; |
||
| 3452 | |||
| 3453 | $objQuestionTmp->initFile( |
||
| 3454 | api_get_session_id(), |
||
| 3455 | isset($exe_info['exe_user_id']) ? $exe_info['exe_user_id'] : api_get_user_id(), |
||
| 3456 | isset($exe_info['exe_exo_id']) ? $exe_info['exe_exo_id'] : $this->id, |
||
| 3457 | isset($exe_info['exe_id']) ? $exe_info['exe_id'] : $exeId |
||
| 3458 | ); |
||
| 3459 | |||
| 3460 | //probably this attempt came in an exercise all question by page |
||
| 3461 | if ($feedback_type == 0) { |
||
| 3462 | $objQuestionTmp->replaceWithRealExe($exeId); |
||
| 3463 | } |
||
| 3464 | $generatedFile = $objQuestionTmp->getFileUrl(); |
||
| 3465 | } |
||
| 3466 | |||
| 3467 | $user_answer = ''; |
||
| 3468 | // Get answer list for matching |
||
| 3469 | $sql = "SELECT id_auto, id, answer |
||
| 3470 | FROM $table_ans |
||
| 3471 | WHERE c_id = $course_id AND question_id = $questionId"; |
||
| 3472 | $res_answer = Database::query($sql); |
||
| 3473 | |||
| 3474 | $answerMatching = []; |
||
| 3475 | while ($real_answer = Database::fetch_array($res_answer)) { |
||
| 3476 | $answerMatching[$real_answer['id_auto']] = $real_answer['answer']; |
||
| 3477 | } |
||
| 3478 | |||
| 3479 | $real_answers = []; |
||
| 3480 | $quiz_question_options = Question::readQuestionOption( |
||
| 3481 | $questionId, |
||
| 3482 | $course_id |
||
| 3483 | ); |
||
| 3484 | |||
| 3485 | $organs_at_risk_hit = 0; |
||
| 3486 | $questionScore = 0; |
||
| 3487 | $answer_correct_array = []; |
||
| 3488 | $orderedHotspots = []; |
||
| 3489 | |||
| 3490 | if ($answerType == HOT_SPOT || $answerType == ANNOTATION) { |
||
| 3491 | $orderedHotspots = $em->getRepository('ChamiloCoreBundle:TrackEHotspot')->findBy( |
||
| 3492 | [ |
||
| 3493 | 'hotspotQuestionId' => $questionId, |
||
| 3494 | 'cId' => $course_id, |
||
| 3495 | 'hotspotExeId' => $exeId, |
||
| 3496 | ], |
||
| 3497 | ['hotspotAnswerId' => 'ASC'] |
||
| 3498 | ); |
||
| 3499 | } |
||
| 3500 | if ($debug) { |
||
| 3501 | error_log('Start answer loop '); |
||
| 3502 | } |
||
| 3503 | for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { |
||
| 3504 | $answer = $objAnswerTmp->selectAnswer($answerId); |
||
| 3505 | $answerComment = $objAnswerTmp->selectComment($answerId); |
||
| 3506 | $answerCorrect = $objAnswerTmp->isCorrect($answerId); |
||
| 3507 | $answerWeighting = (float) $objAnswerTmp->selectWeighting($answerId); |
||
| 3508 | $answerAutoId = $objAnswerTmp->selectAutoId($answerId); |
||
| 3509 | $answerIid = isset($objAnswerTmp->iid[$answerId]) ? $objAnswerTmp->iid[$answerId] : ''; |
||
| 3510 | $answer_correct_array[$answerId] = (bool) $answerCorrect; |
||
| 3511 | |||
| 3512 | if ($debug) { |
||
| 3513 | error_log("answer auto id: $answerAutoId "); |
||
| 3514 | error_log("answer correct: $answerCorrect "); |
||
| 3515 | } |
||
| 3516 | |||
| 3517 | // Delineation |
||
| 3518 | $delineation_cord = $objAnswerTmp->selectHotspotCoordinates(1); |
||
| 3519 | $answer_delineation_destination = $objAnswerTmp->selectDestination(1); |
||
| 3520 | |||
| 3521 | switch ($answerType) { |
||
| 3522 | case UNIQUE_ANSWER: |
||
| 3523 | case UNIQUE_ANSWER_IMAGE: |
||
| 3524 | case UNIQUE_ANSWER_NO_OPTION: |
||
| 3525 | case READING_COMPREHENSION: |
||
| 3526 | if ($from_database) { |
||
| 3527 | $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT |
||
| 3528 | WHERE |
||
| 3529 | exe_id = '".$exeId."' AND |
||
| 3530 | question_id= '".$questionId."'"; |
||
| 3531 | $result = Database::query($sql); |
||
| 3532 | $choice = Database::result($result, 0, 'answer'); |
||
| 3533 | |||
| 3534 | $studentChoice = $choice == $answerAutoId ? 1 : 0; |
||
| 3535 | if ($studentChoice) { |
||
| 3536 | $questionScore += $answerWeighting; |
||
| 3537 | $totalScore += $answerWeighting; |
||
| 3538 | } |
||
| 3539 | } else { |
||
| 3540 | $studentChoice = $choice == $answerAutoId ? 1 : 0; |
||
| 3541 | if ($studentChoice) { |
||
| 3542 | $questionScore += $answerWeighting; |
||
| 3543 | $totalScore += $answerWeighting; |
||
| 3544 | } |
||
| 3545 | } |
||
| 3546 | break; |
||
| 3547 | case MULTIPLE_ANSWER_TRUE_FALSE: |
||
| 3548 | if ($from_database) { |
||
| 3549 | $choice = []; |
||
| 3550 | $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT |
||
| 3551 | WHERE |
||
| 3552 | exe_id = $exeId AND |
||
| 3553 | question_id = ".$questionId; |
||
| 3554 | |||
| 3555 | $result = Database::query($sql); |
||
| 3556 | while ($row = Database::fetch_array($result)) { |
||
| 3557 | $values = explode(':', $row['answer']); |
||
| 3558 | $my_answer_id = isset($values[0]) ? $values[0] : ''; |
||
| 3559 | $option = isset($values[1]) ? $values[1] : ''; |
||
| 3560 | $choice[$my_answer_id] = $option; |
||
| 3561 | } |
||
| 3562 | } |
||
| 3563 | |||
| 3564 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3565 | if (!empty($studentChoice)) { |
||
| 3566 | if ($studentChoice == $answerCorrect) { |
||
| 3567 | $questionScore += $true_score; |
||
| 3568 | } else { |
||
| 3569 | if ($quiz_question_options[$studentChoice]['name'] == "Don't know" || |
||
| 3570 | $quiz_question_options[$studentChoice]['name'] == "DoubtScore" |
||
| 3571 | ) { |
||
| 3572 | $questionScore += $doubt_score; |
||
| 3573 | } else { |
||
| 3574 | $questionScore += $false_score; |
||
| 3575 | } |
||
| 3576 | } |
||
| 3577 | } else { |
||
| 3578 | // If no result then the user just hit don't know |
||
| 3579 | $studentChoice = 3; |
||
| 3580 | $questionScore += $doubt_score; |
||
| 3581 | } |
||
| 3582 | $totalScore = $questionScore; |
||
| 3583 | break; |
||
| 3584 | case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY: |
||
| 3585 | if ($from_database) { |
||
| 3586 | $choice = []; |
||
| 3587 | $choiceDegreeCertainty = []; |
||
| 3588 | $sql = "SELECT answer |
||
| 3589 | FROM $TBL_TRACK_ATTEMPT |
||
| 3590 | WHERE |
||
| 3591 | exe_id = $exeId AND question_id = $questionId"; |
||
| 3592 | |||
| 3593 | $result = Database::query($sql); |
||
| 3594 | while ($row = Database::fetch_array($result)) { |
||
| 3595 | $ind = $row['answer']; |
||
| 3596 | $values = explode(':', $ind); |
||
| 3597 | $myAnswerId = $values[0]; |
||
| 3598 | $option = $values[1]; |
||
| 3599 | $percent = $values[2]; |
||
| 3600 | $choice[$myAnswerId] = $option; |
||
| 3601 | $choiceDegreeCertainty[$myAnswerId] = $percent; |
||
| 3602 | } |
||
| 3603 | } |
||
| 3604 | |||
| 3605 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3606 | $studentChoiceDegree = isset($choiceDegreeCertainty[$answerAutoId]) ? |
||
| 3607 | $choiceDegreeCertainty[$answerAutoId] : null; |
||
| 3608 | |||
| 3609 | // student score update |
||
| 3610 | if (!empty($studentChoice)) { |
||
| 3611 | if ($studentChoice == $answerCorrect) { |
||
| 3612 | // correct answer and student is Unsure or PrettySur |
||
| 3613 | if ($quiz_question_options[$studentChoiceDegree]['position'] >= 3 |
||
| 3614 | && $quiz_question_options[$studentChoiceDegree]['position'] < 9) { |
||
| 3615 | $questionScore += $true_score; |
||
| 3616 | } else { |
||
| 3617 | // student ignore correct answer |
||
| 3618 | $questionScore += $doubt_score; |
||
| 3619 | } |
||
| 3620 | } else { |
||
| 3621 | // false answer and student is Unsure or PrettySur |
||
| 3622 | if ($quiz_question_options[$studentChoiceDegree]['position'] >= 3 |
||
| 3623 | && $quiz_question_options[$studentChoiceDegree]['position'] < 9) { |
||
| 3624 | $questionScore += $false_score; |
||
| 3625 | } else { |
||
| 3626 | // student ignore correct answer |
||
| 3627 | $questionScore += $doubt_score; |
||
| 3628 | } |
||
| 3629 | } |
||
| 3630 | } |
||
| 3631 | $totalScore = $questionScore; |
||
| 3632 | break; |
||
| 3633 | case MULTIPLE_ANSWER: //2 |
||
| 3634 | if ($from_database) { |
||
| 3635 | $choice = []; |
||
| 3636 | $sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." |
||
| 3637 | WHERE exe_id = '".$exeId."' AND question_id= '".$questionId."'"; |
||
| 3638 | $resultans = Database::query($sql); |
||
| 3639 | while ($row = Database::fetch_array($resultans)) { |
||
| 3640 | $choice[$row['answer']] = 1; |
||
| 3641 | } |
||
| 3642 | |||
| 3643 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3644 | $real_answers[$answerId] = (bool) $studentChoice; |
||
| 3645 | |||
| 3646 | if ($studentChoice) { |
||
| 3647 | $questionScore += $answerWeighting; |
||
| 3648 | } |
||
| 3649 | } else { |
||
| 3650 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3651 | $real_answers[$answerId] = (bool) $studentChoice; |
||
| 3652 | |||
| 3653 | if (isset($studentChoice)) { |
||
| 3654 | $questionScore += $answerWeighting; |
||
| 3655 | } |
||
| 3656 | } |
||
| 3657 | $totalScore += $answerWeighting; |
||
| 3658 | |||
| 3659 | if ($debug) { |
||
| 3660 | error_log("studentChoice: $studentChoice"); |
||
| 3661 | } |
||
| 3662 | break; |
||
| 3663 | case GLOBAL_MULTIPLE_ANSWER: |
||
| 3664 | if ($from_database) { |
||
| 3665 | $choice = []; |
||
| 3666 | $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT |
||
| 3667 | WHERE exe_id = '".$exeId."' AND question_id= '".$questionId."'"; |
||
| 3668 | $resultans = Database::query($sql); |
||
| 3669 | while ($row = Database::fetch_array($resultans)) { |
||
| 3670 | $choice[$row['answer']] = 1; |
||
| 3671 | } |
||
| 3672 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3673 | $real_answers[$answerId] = (bool) $studentChoice; |
||
| 3674 | if ($studentChoice) { |
||
| 3675 | $questionScore += $answerWeighting; |
||
| 3676 | } |
||
| 3677 | } else { |
||
| 3678 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3679 | if (isset($studentChoice)) { |
||
| 3680 | $questionScore += $answerWeighting; |
||
| 3681 | } |
||
| 3682 | $real_answers[$answerId] = (bool) $studentChoice; |
||
| 3683 | } |
||
| 3684 | $totalScore += $answerWeighting; |
||
| 3685 | if ($debug) { |
||
| 3686 | error_log("studentChoice: $studentChoice"); |
||
| 3687 | } |
||
| 3688 | break; |
||
| 3689 | case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE: |
||
| 3690 | if ($from_database) { |
||
| 3691 | $choice = []; |
||
| 3692 | $sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." |
||
| 3693 | WHERE exe_id = $exeId AND question_id= ".$questionId; |
||
| 3694 | $resultans = Database::query($sql); |
||
| 3695 | while ($row = Database::fetch_array($resultans)) { |
||
| 3696 | $result = explode(':', $row['answer']); |
||
| 3697 | if (isset($result[0])) { |
||
| 3698 | $my_answer_id = isset($result[0]) ? $result[0] : ''; |
||
| 3699 | $option = isset($result[1]) ? $result[1] : ''; |
||
| 3700 | $choice[$my_answer_id] = $option; |
||
| 3701 | } |
||
| 3702 | } |
||
| 3703 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : ''; |
||
| 3704 | |||
| 3705 | if ($answerCorrect == $studentChoice) { |
||
| 3706 | //$answerCorrect = 1; |
||
| 3707 | $real_answers[$answerId] = true; |
||
| 3708 | } else { |
||
| 3709 | //$answerCorrect = 0; |
||
| 3710 | $real_answers[$answerId] = false; |
||
| 3711 | } |
||
| 3712 | } else { |
||
| 3713 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : ''; |
||
| 3714 | if ($answerCorrect == $studentChoice) { |
||
| 3715 | //$answerCorrect = 1; |
||
| 3716 | $real_answers[$answerId] = true; |
||
| 3717 | } else { |
||
| 3718 | //$answerCorrect = 0; |
||
| 3719 | $real_answers[$answerId] = false; |
||
| 3720 | } |
||
| 3721 | } |
||
| 3722 | break; |
||
| 3723 | case MULTIPLE_ANSWER_COMBINATION: |
||
| 3724 | if ($from_database) { |
||
| 3725 | $choice = []; |
||
| 3726 | $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT |
||
| 3727 | WHERE exe_id = $exeId AND question_id= $questionId"; |
||
| 3728 | $resultans = Database::query($sql); |
||
| 3729 | while ($row = Database::fetch_array($resultans)) { |
||
| 3730 | $choice[$row['answer']] = 1; |
||
| 3731 | } |
||
| 3732 | |||
| 3733 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3734 | if ($answerCorrect == 1) { |
||
| 3735 | if ($studentChoice) { |
||
| 3736 | $real_answers[$answerId] = true; |
||
| 3737 | } else { |
||
| 3738 | $real_answers[$answerId] = false; |
||
| 3739 | } |
||
| 3740 | } else { |
||
| 3741 | if ($studentChoice) { |
||
| 3742 | $real_answers[$answerId] = false; |
||
| 3743 | } else { |
||
| 3744 | $real_answers[$answerId] = true; |
||
| 3745 | } |
||
| 3746 | } |
||
| 3747 | } else { |
||
| 3748 | $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; |
||
| 3749 | if ($answerCorrect == 1) { |
||
| 3750 | if ($studentChoice) { |
||
| 3751 | $real_answers[$answerId] = true; |
||
| 3752 | } else { |
||
| 3753 | $real_answers[$answerId] = false; |
||
| 3754 | } |
||
| 3755 | } else { |
||
| 3756 | if ($studentChoice) { |
||
| 3757 | $real_answers[$answerId] = false; |
||
| 3758 | } else { |
||
| 3759 | $real_answers[$answerId] = true; |
||
| 3760 | } |
||
| 3761 | } |
||
| 3762 | } |
||
| 3763 | break; |
||
| 3764 | case FILL_IN_BLANKS: |
||
| 3765 | $str = ''; |
||
| 3766 | $answerFromDatabase = ''; |
||
| 3767 | if ($from_database) { |
||
| 3768 | $sql = "SELECT answer |
||
| 3769 | FROM $TBL_TRACK_ATTEMPT |
||
| 3770 | WHERE |
||
| 3771 | exe_id = $exeId AND |
||
| 3772 | question_id= ".intval($questionId); |
||
| 3773 | $result = Database::query($sql); |
||
| 3774 | if ($debug) { |
||
| 3775 | error_log($sql); |
||
| 3776 | } |
||
| 3777 | $str = $answerFromDatabase = Database::result($result, 0, 'answer'); |
||
| 3778 | } |
||
| 3779 | |||
| 3780 | // if ($saved_results == false && strpos($answerFromDatabase, 'font color') !== false) { |
||
| 3781 | if (false) { |
||
| 3782 | // the question is encoded like this |
||
| 3783 | // [A] B [C] D [E] F::10,10,10@1 |
||
| 3784 | // number 1 before the "@" means that is a switchable fill in blank question |
||
| 3785 | // [A] B [C] D [E] F::10,10,10@ or [A] B [C] D [E] F::10,10,10 |
||
| 3786 | // means that is a normal fill blank question |
||
| 3787 | // first we explode the "::" |
||
| 3788 | $pre_array = explode('::', $answer); |
||
| 3789 | |||
| 3790 | // is switchable fill blank or not |
||
| 3791 | $last = count($pre_array) - 1; |
||
| 3792 | $is_set_switchable = explode('@', $pre_array[$last]); |
||
| 3793 | $switchable_answer_set = false; |
||
| 3794 | if (isset($is_set_switchable[1]) && $is_set_switchable[1] == 1) { |
||
| 3795 | $switchable_answer_set = true; |
||
| 3796 | } |
||
| 3797 | $answer = ''; |
||
| 3798 | for ($k = 0; $k < $last; $k++) { |
||
| 3799 | $answer .= $pre_array[$k]; |
||
| 3800 | } |
||
| 3801 | // splits weightings that are joined with a comma |
||
| 3802 | $answerWeighting = explode(',', $is_set_switchable[0]); |
||
| 3803 | // we save the answer because it will be modified |
||
| 3804 | $temp = $answer; |
||
| 3805 | $answer = ''; |
||
| 3806 | $j = 0; |
||
| 3807 | //initialise answer tags |
||
| 3808 | $user_tags = $correct_tags = $real_text = []; |
||
| 3809 | // the loop will stop at the end of the text |
||
| 3810 | while (1) { |
||
| 3811 | // quits the loop if there are no more blanks (detect '[') |
||
| 3812 | if ($temp == false || ($pos = api_strpos($temp, '[')) === false) { |
||
| 3813 | // adds the end of the text |
||
| 3814 | $answer = $temp; |
||
| 3815 | $real_text[] = $answer; |
||
| 3816 | break; //no more "blanks", quit the loop |
||
| 3817 | } |
||
| 3818 | // adds the piece of text that is before the blank |
||
| 3819 | //and ends with '[' into a general storage array |
||
| 3820 | $real_text[] = api_substr($temp, 0, $pos + 1); |
||
| 3821 | $answer .= api_substr($temp, 0, $pos + 1); |
||
| 3822 | //take the string remaining (after the last "[" we found) |
||
| 3823 | $temp = api_substr($temp, $pos + 1); |
||
| 3824 | // quit the loop if there are no more blanks, and update $pos to the position of next ']' |
||
| 3825 | if (($pos = api_strpos($temp, ']')) === false) { |
||
| 3826 | // adds the end of the text |
||
| 3827 | $answer .= $temp; |
||
| 3828 | break; |
||
| 3829 | } |
||
| 3830 | if ($from_database) { |
||
| 3831 | $str = $answerFromDatabase; |
||
| 3832 | api_preg_match_all('#\[([^[]*)\]#', $str, $arr); |
||
| 3833 | $str = str_replace('\r\n', '', $str); |
||
| 3834 | |||
| 3835 | $choice = $arr[1]; |
||
| 3836 | if (isset($choice[$j])) { |
||
| 3837 | $tmp = api_strrpos($choice[$j], ' / '); |
||
| 3838 | $choice[$j] = api_substr($choice[$j], 0, $tmp); |
||
| 3839 | $choice[$j] = trim($choice[$j]); |
||
| 3840 | // Needed to let characters ' and " to work as part of an answer |
||
| 3841 | $choice[$j] = stripslashes($choice[$j]); |
||
| 3842 | } else { |
||
| 3843 | $choice[$j] = null; |
||
| 3844 | } |
||
| 3845 | } else { |
||
| 3846 | // This value is the user input, not escaped while correct answer is escaped by ckeditor |
||
| 3847 | $choice[$j] = api_htmlentities(trim($choice[$j])); |
||
| 3848 | } |
||
| 3849 | |||
| 3850 | $user_tags[] = $choice[$j]; |
||
| 3851 | // Put the contents of the [] answer tag into correct_tags[] |
||
| 3852 | $correct_tags[] = api_substr($temp, 0, $pos); |
||
| 3853 | $j++; |
||
| 3854 | $temp = api_substr($temp, $pos + 1); |
||
| 3855 | } |
||
| 3856 | $answer = ''; |
||
| 3857 | $real_correct_tags = $correct_tags; |
||
| 3858 | $chosen_list = []; |
||
| 3859 | |||
| 3860 | for ($i = 0; $i < count($real_correct_tags); $i++) { |
||
| 3861 | if ($i == 0) { |
||
| 3862 | $answer .= $real_text[0]; |
||
| 3863 | } |
||
| 3864 | if (!$switchable_answer_set) { |
||
| 3865 | // Needed to parse ' and " characters |
||
| 3866 | $user_tags[$i] = stripslashes($user_tags[$i]); |
||
| 3867 | if ($correct_tags[$i] == $user_tags[$i]) { |
||
| 3868 | // gives the related weighting to the student |
||
| 3869 | $questionScore += $answerWeighting[$i]; |
||
| 3870 | // increments total score |
||
| 3871 | $totalScore += $answerWeighting[$i]; |
||
| 3872 | // adds the word in green at the end of the string |
||
| 3873 | $answer .= $correct_tags[$i]; |
||
| 3874 | } elseif (!empty($user_tags[$i])) { |
||
| 3875 | // else if the word entered by the student IS NOT the same as |
||
| 3876 | // the one defined by the professor |
||
| 3877 | // adds the word in red at the end of the string, and strikes it |
||
| 3878 | $answer .= '<font color="red"><s>'.$user_tags[$i].'</s></font>'; |
||
| 3879 | } else { |
||
| 3880 | // adds a tabulation if no word has been typed by the student |
||
| 3881 | $answer .= ''; // remove that causes issue |
||
| 3882 | } |
||
| 3883 | } else { |
||
| 3884 | // switchable fill in the blanks |
||
| 3885 | if (in_array($user_tags[$i], $correct_tags)) { |
||
| 3886 | $chosen_list[] = $user_tags[$i]; |
||
| 3887 | $correct_tags = array_diff($correct_tags, $chosen_list); |
||
| 3888 | // gives the related weighting to the student |
||
| 3889 | $questionScore += $answerWeighting[$i]; |
||
| 3890 | // increments total score |
||
| 3891 | $totalScore += $answerWeighting[$i]; |
||
| 3892 | // adds the word in green at the end of the string |
||
| 3893 | $answer .= $user_tags[$i]; |
||
| 3894 | } elseif (!empty($user_tags[$i])) { |
||
| 3895 | // else if the word entered by the student IS NOT the same |
||
| 3896 | // as the one defined by the professor |
||
| 3897 | // adds the word in red at the end of the string, and strikes it |
||
| 3898 | $answer .= '<font color="red"><s>'.$user_tags[$i].'</s></font>'; |
||
| 3899 | } else { |
||
| 3900 | // adds a tabulation if no word has been typed by the student |
||
| 3901 | $answer .= ''; // remove that causes issue |
||
| 3902 | } |
||
| 3903 | } |
||
| 3904 | |||
| 3905 | // adds the correct word, followed by ] to close the blank |
||
| 3906 | $answer .= ' / <font color="green"><b>'.$real_correct_tags[$i].'</b></font>]'; |
||
| 3907 | if (isset($real_text[$i + 1])) { |
||
| 3908 | $answer .= $real_text[$i + 1]; |
||
| 3909 | } |
||
| 3910 | } |
||
| 3911 | } else { |
||
| 3912 | // insert the student result in the track_e_attempt table, field answer |
||
| 3913 | // $answer is the answer like in the c_quiz_answer table for the question |
||
| 3914 | // student data are choice[] |
||
| 3915 | $listCorrectAnswers = FillBlanks::getAnswerInfo($answer); |
||
| 3916 | $switchableAnswerSet = $listCorrectAnswers['switchable']; |
||
| 3917 | $answerWeighting = $listCorrectAnswers['weighting']; |
||
| 3918 | // user choices is an array $choice |
||
| 3919 | |||
| 3920 | // get existing user data in n the BDD |
||
| 3921 | if ($from_database) { |
||
| 3922 | $listStudentResults = FillBlanks::getAnswerInfo( |
||
| 3923 | $answerFromDatabase, |
||
| 3924 | true |
||
| 3925 | ); |
||
| 3926 | $choice = $listStudentResults['student_answer']; |
||
| 3927 | } |
||
| 3928 | |||
| 3929 | // loop other all blanks words |
||
| 3930 | if (!$switchableAnswerSet) { |
||
| 3931 | // not switchable answer, must be in the same place than teacher order |
||
| 3932 | for ($i = 0; $i < count($listCorrectAnswers['words']); $i++) { |
||
| 3933 | $studentAnswer = isset($choice[$i]) ? $choice[$i] : ''; |
||
| 3934 | $correctAnswer = $listCorrectAnswers['words'][$i]; |
||
| 3935 | |||
| 3936 | if ($debug) { |
||
| 3937 | error_log("Student answer: $i"); |
||
| 3938 | error_log($studentAnswer); |
||
| 3939 | } |
||
| 3940 | |||
| 3941 | // This value is the user input, not escaped while correct answer is escaped by ckeditor |
||
| 3942 | // Works with cyrillic alphabet and when using ">" chars see #7718 #7610 #7618 |
||
| 3943 | // ENT_QUOTES is used in order to transform ' to ' |
||
| 3944 | if (!$from_database) { |
||
| 3945 | $studentAnswer = FillBlanks::clearStudentAnswer($studentAnswer); |
||
| 3946 | if ($debug) { |
||
| 3947 | error_log("Student answer cleaned:"); |
||
| 3948 | error_log($studentAnswer); |
||
| 3949 | } |
||
| 3950 | } |
||
| 3951 | |||
| 3952 | $isAnswerCorrect = 0; |
||
| 3953 | if (FillBlanks::isStudentAnswerGood($studentAnswer, $correctAnswer, $from_database)) { |
||
| 3954 | // gives the related weighting to the student |
||
| 3955 | $questionScore += $answerWeighting[$i]; |
||
| 3956 | // increments total score |
||
| 3957 | $totalScore += $answerWeighting[$i]; |
||
| 3958 | $isAnswerCorrect = 1; |
||
| 3959 | } |
||
| 3960 | if ($debug) { |
||
| 3961 | error_log("isAnswerCorrect $i: $isAnswerCorrect"); |
||
| 3962 | } |
||
| 3963 | |||
| 3964 | $studentAnswerToShow = $studentAnswer; |
||
| 3965 | $type = FillBlanks::getFillTheBlankAnswerType($correctAnswer); |
||
| 3966 | if ($debug) { |
||
| 3967 | error_log("Fill in blank type: $type"); |
||
| 3968 | } |
||
| 3969 | if ($type == FillBlanks::FILL_THE_BLANK_MENU) { |
||
| 3970 | $listMenu = FillBlanks::getFillTheBlankMenuAnswers($correctAnswer, false); |
||
| 3971 | if ($studentAnswer != '') { |
||
| 3972 | foreach ($listMenu as $item) { |
||
| 3973 | if (sha1($item) == $studentAnswer) { |
||
| 3974 | $studentAnswerToShow = $item; |
||
| 3975 | } |
||
| 3976 | } |
||
| 3977 | } |
||
| 3978 | } |
||
| 3979 | $listCorrectAnswers['student_answer'][$i] = $studentAnswerToShow; |
||
| 3980 | $listCorrectAnswers['student_score'][$i] = $isAnswerCorrect; |
||
| 3981 | } |
||
| 3982 | } else { |
||
| 3983 | // switchable answer |
||
| 3984 | $listStudentAnswerTemp = $choice; |
||
| 3985 | $listTeacherAnswerTemp = $listCorrectAnswers['words']; |
||
| 3986 | |||
| 3987 | // for every teacher answer, check if there is a student answer |
||
| 3988 | for ($i = 0; $i < count($listStudentAnswerTemp); $i++) { |
||
| 3989 | $studentAnswer = trim($listStudentAnswerTemp[$i]); |
||
| 3990 | $studentAnswerToShow = $studentAnswer; |
||
| 3991 | |||
| 3992 | if ($debug) { |
||
| 3993 | error_log("Student answer: $i"); |
||
| 3994 | error_log($studentAnswer); |
||
| 3995 | } |
||
| 3996 | |||
| 3997 | $found = false; |
||
| 3998 | for ($j = 0; $j < count($listTeacherAnswerTemp); $j++) { |
||
| 3999 | $correctAnswer = $listTeacherAnswerTemp[$j]; |
||
| 4000 | $type = FillBlanks::getFillTheBlankAnswerType($correctAnswer); |
||
| 4001 | if ($type == FillBlanks::FILL_THE_BLANK_MENU) { |
||
| 4002 | $listMenu = FillBlanks::getFillTheBlankMenuAnswers($correctAnswer, false); |
||
| 4003 | if (!empty($studentAnswer)) { |
||
| 4004 | foreach ($listMenu as $key => $item) { |
||
| 4005 | if ($key == $correctAnswer) { |
||
| 4006 | $studentAnswerToShow = $item; |
||
| 4007 | break; |
||
| 4008 | } |
||
| 4009 | } |
||
| 4010 | } |
||
| 4011 | } |
||
| 4012 | |||
| 4013 | if (!$found) { |
||
| 4014 | if (FillBlanks::isStudentAnswerGood( |
||
| 4015 | $studentAnswer, |
||
| 4016 | $correctAnswer, |
||
| 4017 | $from_database |
||
| 4018 | ) |
||
| 4019 | ) { |
||
| 4020 | $questionScore += $answerWeighting[$i]; |
||
| 4021 | $totalScore += $answerWeighting[$i]; |
||
| 4022 | $listTeacherAnswerTemp[$j] = ''; |
||
| 4023 | $found = true; |
||
| 4024 | } |
||
| 4025 | } |
||
| 4026 | } |
||
| 4027 | $listCorrectAnswers['student_answer'][$i] = $studentAnswerToShow; |
||
| 4028 | if (!$found) { |
||
| 4029 | $listCorrectAnswers['student_score'][$i] = 0; |
||
| 4030 | } else { |
||
| 4031 | $listCorrectAnswers['student_score'][$i] = 1; |
||
| 4032 | } |
||
| 4033 | } |
||
| 4034 | } |
||
| 4035 | $answer = FillBlanks::getAnswerInStudentAttempt($listCorrectAnswers); |
||
| 4036 | } |
||
| 4037 | break; |
||
| 4038 | case CALCULATED_ANSWER: |
||
| 4039 | $calculatedAnswerList = Session::read('calculatedAnswerId'); |
||
| 4040 | if (!empty($calculatedAnswerList)) { |
||
| 4041 | $answer = $objAnswerTmp->selectAnswer($calculatedAnswerList[$questionId]); |
||
| 4042 | $preArray = explode('@@', $answer); |
||
| 4043 | $last = count($preArray) - 1; |
||
| 4044 | $answer = ''; |
||
| 4045 | for ($k = 0; $k < $last; $k++) { |
||
| 4046 | $answer .= $preArray[$k]; |
||
| 4047 | } |
||
| 4048 | $answerWeighting = [$answerWeighting]; |
||
| 4049 | // we save the answer because it will be modified |
||
| 4050 | $temp = $answer; |
||
| 4051 | $answer = ''; |
||
| 4052 | $j = 0; |
||
| 4053 | //initialise answer tags |
||
| 4054 | $userTags = $correctTags = $realText = []; |
||
| 4055 | // the loop will stop at the end of the text |
||
| 4056 | while (1) { |
||
| 4057 | // quits the loop if there are no more blanks (detect '[') |
||
| 4058 | if ($temp == false || ($pos = api_strpos($temp, '[')) === false) { |
||
| 4059 | // adds the end of the text |
||
| 4060 | $answer = $temp; |
||
| 4061 | $realText[] = $answer; |
||
| 4062 | break; //no more "blanks", quit the loop |
||
| 4063 | } |
||
| 4064 | // adds the piece of text that is before the blank |
||
| 4065 | //and ends with '[' into a general storage array |
||
| 4066 | $realText[] = api_substr($temp, 0, $pos + 1); |
||
| 4067 | $answer .= api_substr($temp, 0, $pos + 1); |
||
| 4068 | //take the string remaining (after the last "[" we found) |
||
| 4069 | $temp = api_substr($temp, $pos + 1); |
||
| 4070 | // quit the loop if there are no more blanks, and update $pos to the position of next ']' |
||
| 4071 | if (($pos = api_strpos($temp, ']')) === false) { |
||
| 4072 | // adds the end of the text |
||
| 4073 | $answer .= $temp; |
||
| 4074 | break; |
||
| 4075 | } |
||
| 4076 | |||
| 4077 | if ($from_database) { |
||
| 4078 | $sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." |
||
| 4079 | WHERE |
||
| 4080 | exe_id = '".$exeId."' AND |
||
| 4081 | question_id = ".intval($questionId); |
||
| 4082 | $result = Database::query($sql); |
||
| 4083 | $str = Database::result($result, 0, 'answer'); |
||
| 4084 | api_preg_match_all('#\[([^[]*)\]#', $str, $arr); |
||
| 4085 | $str = str_replace('\r\n', '', $str); |
||
| 4086 | $choice = $arr[1]; |
||
| 4087 | if (isset($choice[$j])) { |
||
| 4088 | $tmp = api_strrpos($choice[$j], ' / '); |
||
| 4089 | |||
| 4090 | if ($tmp) { |
||
| 4091 | $choice[$j] = api_substr($choice[$j], 0, $tmp); |
||
| 4092 | } else { |
||
| 4093 | $tmp = ltrim($tmp, '['); |
||
| 4094 | $tmp = rtrim($tmp, ']'); |
||
| 4095 | } |
||
| 4096 | |||
| 4097 | $choice[$j] = trim($choice[$j]); |
||
| 4098 | // Needed to let characters ' and " to work as part of an answer |
||
| 4099 | $choice[$j] = stripslashes($choice[$j]); |
||
| 4100 | } else { |
||
| 4101 | $choice[$j] = null; |
||
| 4102 | } |
||
| 4103 | } else { |
||
| 4104 | // This value is the user input, not escaped while correct answer is escaped by fckeditor |
||
| 4105 | $choice[$j] = api_htmlentities(trim($choice[$j])); |
||
| 4106 | } |
||
| 4107 | $userTags[] = $choice[$j]; |
||
| 4108 | //put the contents of the [] answer tag into correct_tags[] |
||
| 4109 | $correctTags[] = api_substr($temp, 0, $pos); |
||
| 4110 | $j++; |
||
| 4111 | $temp = api_substr($temp, $pos + 1); |
||
| 4112 | } |
||
| 4113 | $answer = ''; |
||
| 4114 | $realCorrectTags = $correctTags; |
||
| 4115 | $calculatedStatus = Display::label(get_lang('Incorrect'), 'danger'); |
||
| 4116 | $expectedAnswer = ''; |
||
| 4117 | $calculatedChoice = ''; |
||
| 4118 | |||
| 4119 | for ($i = 0; $i < count($realCorrectTags); $i++) { |
||
| 4120 | if ($i == 0) { |
||
| 4121 | $answer .= $realText[0]; |
||
| 4122 | } |
||
| 4123 | // Needed to parse ' and " characters |
||
| 4124 | $userTags[$i] = stripslashes($userTags[$i]); |
||
| 4125 | if ($correctTags[$i] == $userTags[$i]) { |
||
| 4126 | // gives the related weighting to the student |
||
| 4127 | $questionScore += $answerWeighting[$i]; |
||
| 4128 | // increments total score |
||
| 4129 | $totalScore += $answerWeighting[$i]; |
||
| 4130 | // adds the word in green at the end of the string |
||
| 4131 | $answer .= $correctTags[$i]; |
||
| 4132 | $calculatedChoice = $correctTags[$i]; |
||
| 4133 | } elseif (!empty($userTags[$i])) { |
||
| 4134 | // else if the word entered by the student IS NOT the same as |
||
| 4135 | // the one defined by the professor |
||
| 4136 | // adds the word in red at the end of the string, and strikes it |
||
| 4137 | $answer .= '<font color="red"><s>'.$userTags[$i].'</s></font>'; |
||
| 4138 | $calculatedChoice = $userTags[$i]; |
||
| 4139 | } else { |
||
| 4140 | // adds a tabulation if no word has been typed by the student |
||
| 4141 | $answer .= ''; // remove that causes issue |
||
| 4142 | } |
||
| 4143 | // adds the correct word, followed by ] to close the blank |
||
| 4144 | |||
| 4145 | if ($this->results_disabled != EXERCISE_FEEDBACK_TYPE_EXAM) { |
||
| 4146 | $answer .= ' / <font color="green"><b>'.$realCorrectTags[$i].'</b></font>'; |
||
| 4147 | $calculatedStatus = Display::label(get_lang('Correct'), 'success'); |
||
| 4148 | $expectedAnswer = $realCorrectTags[$i]; |
||
| 4149 | } |
||
| 4150 | $answer .= ']'; |
||
| 4151 | |||
| 4152 | if (isset($realText[$i + 1])) { |
||
| 4153 | $answer .= $realText[$i + 1]; |
||
| 4154 | } |
||
| 4155 | } |
||
| 4156 | } else { |
||
| 4157 | if ($from_database) { |
||
| 4158 | $sql = "SELECT * |
||
| 4159 | FROM $TBL_TRACK_ATTEMPT |
||
| 4160 | WHERE |
||
| 4161 | exe_id = $exeId AND |
||
| 4162 | question_id= ".intval($questionId); |
||
| 4163 | $result = Database::query($sql); |
||
| 4164 | $resultData = Database::fetch_array($result, 'ASSOC'); |
||
| 4165 | $answer = $resultData['answer']; |
||
| 4166 | $questionScore = $resultData['marks']; |
||
| 4167 | } |
||
| 4168 | } |
||
| 4169 | break; |
||
| 4170 | case FREE_ANSWER: |
||
| 4171 | if ($from_database) { |
||
| 4172 | $sql = "SELECT answer, marks FROM $TBL_TRACK_ATTEMPT |
||
| 4173 | WHERE |
||
| 4174 | exe_id = $exeId AND |
||
| 4175 | question_id= ".$questionId; |
||
| 4176 | $result = Database::query($sql); |
||
| 4177 | $data = Database::fetch_array($result); |
||
| 4178 | |||
| 4179 | $choice = $data['answer']; |
||
| 4180 | $choice = str_replace('\r\n', '', $choice); |
||
| 4181 | $choice = stripslashes($choice); |
||
| 4182 | $questionScore = $data['marks']; |
||
| 4183 | |||
| 4184 | if ($questionScore == -1) { |
||
| 4185 | $totalScore += 0; |
||
| 4186 | } else { |
||
| 4187 | $totalScore += $questionScore; |
||
| 4188 | } |
||
| 4189 | if ($questionScore == '') { |
||
| 4190 | $questionScore = 0; |
||
| 4191 | } |
||
| 4192 | $arrques = $questionName; |
||
| 4193 | $arrans = $choice; |
||
| 4194 | } else { |
||
| 4195 | $studentChoice = $choice; |
||
| 4196 | if ($studentChoice) { |
||
| 4197 | //Fixing negative puntation see #2193 |
||
| 4198 | $questionScore = 0; |
||
| 4199 | $totalScore += 0; |
||
| 4200 | } |
||
| 4201 | } |
||
| 4202 | break; |
||
| 4203 | case ORAL_EXPRESSION: |
||
| 4204 | if ($from_database) { |
||
| 4205 | $query = "SELECT answer, marks |
||
| 4206 | FROM $TBL_TRACK_ATTEMPT |
||
| 4207 | WHERE |
||
| 4208 | exe_id = $exeId AND |
||
| 4209 | question_id = $questionId |
||
| 4210 | "; |
||
| 4211 | $resq = Database::query($query); |
||
| 4212 | $row = Database::fetch_assoc($resq); |
||
| 4213 | $choice = $row['answer']; |
||
| 4214 | $choice = str_replace('\r\n', '', $choice); |
||
| 4215 | $choice = stripslashes($choice); |
||
| 4216 | $questionScore = $row['marks']; |
||
| 4217 | if ($questionScore == -1) { |
||
| 4218 | $totalScore += 0; |
||
| 4219 | } else { |
||
| 4220 | $totalScore += $questionScore; |
||
| 4221 | } |
||
| 4222 | $arrques = $questionName; |
||
| 4223 | $arrans = $choice; |
||
| 4224 | } else { |
||
| 4225 | $studentChoice = $choice; |
||
| 4226 | if ($studentChoice) { |
||
| 4227 | //Fixing negative puntation see #2193 |
||
| 4228 | $questionScore = 0; |
||
| 4229 | $totalScore += 0; |
||
| 4230 | } |
||
| 4231 | } |
||
| 4232 | break; |
||
| 4233 | case DRAGGABLE: |
||
| 4234 | case MATCHING_DRAGGABLE: |
||
| 4235 | case MATCHING: |
||
| 4236 | if ($from_database) { |
||
| 4237 | $sql = "SELECT id, answer, id_auto |
||
| 4238 | FROM $table_ans |
||
| 4239 | WHERE |
||
| 4240 | c_id = $course_id AND |
||
| 4241 | question_id = $questionId AND |
||
| 4242 | correct = 0 |
||
| 4243 | "; |
||
| 4244 | $result = Database::query($sql); |
||
| 4245 | // Getting the real answer |
||
| 4246 | $real_list = []; |
||
| 4247 | while ($realAnswer = Database::fetch_array($result)) { |
||
| 4248 | $real_list[$realAnswer['id_auto']] = $realAnswer['answer']; |
||
| 4249 | } |
||
| 4250 | |||
| 4251 | $sql = "SELECT id, answer, correct, id_auto, ponderation |
||
| 4252 | FROM $table_ans |
||
| 4253 | WHERE |
||
| 4254 | c_id = $course_id AND |
||
| 4255 | question_id = $questionId AND |
||
| 4256 | correct <> 0 |
||
| 4257 | ORDER BY id_auto"; |
||
| 4258 | $result = Database::query($sql); |
||
| 4259 | $options = []; |
||
| 4260 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||
| 4261 | $options[] = $row; |
||
| 4262 | } |
||
| 4263 | |||
| 4264 | $questionScore = 0; |
||
| 4265 | $counterAnswer = 1; |
||
| 4266 | foreach ($options as $a_answers) { |
||
| 4267 | $i_answer_id = $a_answers['id']; //3 |
||
| 4268 | $s_answer_label = $a_answers['answer']; // your daddy - your mother |
||
| 4269 | $i_answer_correct_answer = $a_answers['correct']; //1 - 2 |
||
| 4270 | $i_answer_id_auto = $a_answers['id_auto']; // 3 - 4 |
||
| 4271 | $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT |
||
| 4272 | WHERE |
||
| 4273 | exe_id = '$exeId' AND |
||
| 4274 | question_id = '$questionId' AND |
||
| 4275 | position = '$i_answer_id_auto'"; |
||
| 4276 | $result = Database::query($sql); |
||
| 4277 | $s_user_answer = 0; |
||
| 4278 | if (Database::num_rows($result) > 0) { |
||
| 4279 | // rich - good looking |
||
| 4280 | $s_user_answer = Database::result($result, 0, 0); |
||
| 4281 | } |
||
| 4282 | $i_answerWeighting = $a_answers['ponderation']; |
||
| 4283 | $user_answer = ''; |
||
| 4284 | $status = Display::label(get_lang('Incorrect'), 'danger'); |
||
| 4285 | if (!empty($s_user_answer)) { |
||
| 4286 | if ($answerType == DRAGGABLE) { |
||
| 4287 | if ($s_user_answer == $i_answer_correct_answer) { |
||
| 4288 | $questionScore += $i_answerWeighting; |
||
| 4289 | $totalScore += $i_answerWeighting; |
||
| 4290 | $user_answer = Display::label(get_lang('Correct'), 'success'); |
||
| 4291 | if ($this->showExpectedChoice()) { |
||
| 4292 | $user_answer = $answerMatching[$i_answer_id_auto]; |
||
| 4293 | } |
||
| 4294 | $status = Display::label(get_lang('Correct'), 'success'); |
||
| 4295 | } else { |
||
| 4296 | $user_answer = Display::label(get_lang('Incorrect'), 'danger'); |
||
| 4297 | if ($this->showExpectedChoice()) { |
||
| 4298 | $data = $options[$real_list[$s_user_answer] - 1]; |
||
| 4299 | $user_answer = $data['answer']; |
||
| 4300 | } |
||
| 4301 | } |
||
| 4302 | } else { |
||
| 4303 | if ($s_user_answer == $i_answer_correct_answer) { |
||
| 4304 | $questionScore += $i_answerWeighting; |
||
| 4305 | $totalScore += $i_answerWeighting; |
||
| 4306 | $status = Display::label(get_lang('Correct'), 'success'); |
||
| 4307 | |||
| 4308 | // Try with id |
||
| 4309 | if (isset($real_list[$i_answer_id])) { |
||
| 4310 | $user_answer = Display::span($real_list[$i_answer_id]); |
||
| 4311 | } |
||
| 4312 | |||
| 4313 | // Try with $i_answer_id_auto |
||
| 4314 | if (empty($user_answer)) { |
||
| 4315 | if (isset($real_list[$i_answer_id_auto])) { |
||
| 4316 | $user_answer = Display::span($real_list[$i_answer_id_auto]); |
||
| 4317 | } |
||
| 4318 | } |
||
| 4319 | if ($this->showExpectedChoice()) { |
||
| 4320 | if (isset($real_list[$i_answer_correct_answer])) { |
||
| 4321 | $user_answer = Display::span($real_list[$i_answer_correct_answer]); |
||
| 4322 | } |
||
| 4323 | } |
||
| 4324 | } else { |
||
| 4325 | $user_answer = Display::span( |
||
| 4326 | $real_list[$s_user_answer], |
||
| 4327 | ['style' => 'color: #FF0000; text-decoration: line-through;'] |
||
| 4328 | ); |
||
| 4329 | if ($this->showExpectedChoice()) { |
||
| 4330 | if (isset($real_list[$s_user_answer])) { |
||
| 4331 | $user_answer = Display::span($real_list[$s_user_answer]); |
||
| 4332 | } |
||
| 4333 | } |
||
| 4334 | } |
||
| 4335 | } |
||
| 4336 | } elseif ($answerType == DRAGGABLE) { |
||
| 4337 | $user_answer = Display::label(get_lang('Incorrect'), 'danger'); |
||
| 4338 | if ($this->showExpectedChoice()) { |
||
| 4339 | $user_answer = ''; |
||
| 4340 | } |
||
| 4341 | } else { |
||
| 4342 | $user_answer = Display::span( |
||
| 4343 | get_lang('Incorrect').' ', |
||
| 4344 | ['style' => 'color: #FF0000; text-decoration: line-through;'] |
||
| 4345 | ); |
||
| 4346 | if ($this->showExpectedChoice()) { |
||
| 4347 | $user_answer = ''; |
||
| 4348 | } |
||
| 4349 | } |
||
| 4350 | |||
| 4351 | if ($show_result) { |
||
| 4352 | if ($this->showExpectedChoice() == false && |
||
| 4353 | $showTotalScoreAndUserChoicesInLastAttempt === false |
||
| 4354 | ) { |
||
| 4355 | $user_answer = ''; |
||
| 4356 | } |
||
| 4357 | switch ($answerType) { |
||
| 4358 | case MATCHING: |
||
| 4359 | case MATCHING_DRAGGABLE: |
||
| 4360 | echo '<tr>'; |
||
| 4361 | if ($this->showExpectedChoice()) { |
||
| 4362 | echo '<td>'.$s_answer_label.'</td>'; |
||
| 4363 | echo '<td>'.$user_answer.'</td>'; |
||
| 4364 | echo '<td>'; |
||
| 4365 | if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { |
||
| 4366 | if (isset($real_list[$i_answer_correct_answer]) && |
||
| 4367 | $showTotalScoreAndUserChoicesInLastAttempt == true |
||
| 4368 | ) { |
||
| 4369 | echo Display::span( |
||
| 4370 | $real_list[$i_answer_correct_answer] |
||
| 4371 | ); |
||
| 4372 | } |
||
| 4373 | } |
||
| 4374 | echo '</td>'; |
||
| 4375 | echo '<td>'.$status.'</td>'; |
||
| 4376 | } else { |
||
| 4377 | echo '<td>'.$s_answer_label.'</td>'; |
||
| 4378 | //echo '<td>'.$user_answer.'</td>'; |
||
| 4379 | echo '<td>'; |
||
| 4380 | if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { |
||
| 4381 | if (isset($real_list[$i_answer_correct_answer]) && |
||
| 4382 | $showTotalScoreAndUserChoicesInLastAttempt === true |
||
| 4383 | ) { |
||
| 4384 | echo Display::span( |
||
| 4385 | $real_list[$i_answer_correct_answer], |
||
| 4386 | ['style' => 'color: #008000; font-weight: bold;'] |
||
| 4387 | ); |
||
| 4388 | } |
||
| 4389 | } |
||
| 4390 | echo '</td>'; |
||
| 4391 | } |
||
| 4392 | echo '</tr>'; |
||
| 4393 | break; |
||
| 4394 | case DRAGGABLE: |
||
| 4395 | if ($showTotalScoreAndUserChoicesInLastAttempt == false) { |
||
| 4396 | $s_answer_label = ''; |
||
| 4397 | } |
||
| 4398 | echo '<tr>'; |
||
| 4399 | if ($this->showExpectedChoice()) { |
||
| 4400 | echo '<td>'.$user_answer.'</td>'; |
||
| 4401 | echo '<td>'.$s_answer_label.'</td>'; |
||
| 4402 | echo '<td>'.$status.'</td>'; |
||
| 4403 | } else { |
||
| 4404 | echo '<td>'.$s_answer_label.'</td>'; |
||
| 4405 | echo '<td>'.$user_answer.'</td>'; |
||
| 4406 | echo '<td>'; |
||
| 4407 | if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { |
||
| 4408 | if (isset($real_list[$i_answer_correct_answer]) && |
||
| 4409 | $showTotalScoreAndUserChoicesInLastAttempt === true |
||
| 4410 | ) { |
||
| 4411 | echo Display::span( |
||
| 4412 | $real_list[$i_answer_correct_answer], |
||
| 4413 | ['style' => 'color: #008000; font-weight: bold;'] |
||
| 4414 | ); |
||
| 4415 | } |
||
| 4416 | } |
||
| 4417 | echo '</td>'; |
||
| 4418 | } |
||
| 4419 | echo '</tr>'; |
||
| 4420 | break; |
||
| 4421 | } |
||
| 4422 | } |
||
| 4423 | $counterAnswer++; |
||
| 4424 | } |
||
| 4425 | break 2; // break the switch and the "for" condition |
||
| 4426 | } else { |
||
| 4427 | if ($answerCorrect) { |
||
| 4428 | if (isset($choice[$answerAutoId]) && |
||
| 4429 | $answerCorrect == $choice[$answerAutoId] |
||
| 4430 | ) { |
||
| 4431 | $questionScore += $answerWeighting; |
||
| 4432 | $totalScore += $answerWeighting; |
||
| 4433 | $user_answer = Display::span($answerMatching[$choice[$answerAutoId]]); |
||
| 4434 | } else { |
||
| 4435 | if (isset($answerMatching[$choice[$answerAutoId]])) { |
||
| 4436 | $user_answer = Display::span( |
||
| 4437 | $answerMatching[$choice[$answerAutoId]], |
||
| 4438 | ['style' => 'color: #FF0000; text-decoration: line-through;'] |
||
| 4439 | ); |
||
| 4440 | } |
||
| 4441 | } |
||
| 4442 | $matching[$answerAutoId] = $choice[$answerAutoId]; |
||
| 4443 | } |
||
| 4444 | } |
||
| 4445 | break; |
||
| 4446 | case HOT_SPOT: |
||
| 4447 | if ($from_database) { |
||
| 4448 | $TBL_TRACK_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); |
||
| 4449 | // Check auto id |
||
| 4450 | $sql = "SELECT hotspot_correct |
||
| 4451 | FROM $TBL_TRACK_HOTSPOT |
||
| 4452 | WHERE |
||
| 4453 | hotspot_exe_id = $exeId AND |
||
| 4454 | hotspot_question_id= $questionId AND |
||
| 4455 | hotspot_answer_id = ".intval($answerAutoId)." |
||
| 4456 | ORDER BY hotspot_id ASC"; |
||
| 4457 | $result = Database::query($sql); |
||
| 4458 | if (Database::num_rows($result)) { |
||
| 4459 | $studentChoice = Database::result( |
||
| 4460 | $result, |
||
| 4461 | 0, |
||
| 4462 | 'hotspot_correct' |
||
| 4463 | ); |
||
| 4464 | |||
| 4465 | if ($studentChoice) { |
||
| 4466 | $questionScore += $answerWeighting; |
||
| 4467 | $totalScore += $answerWeighting; |
||
| 4468 | } |
||
| 4469 | } else { |
||
| 4470 | // If answer.id is different: |
||
| 4471 | $sql = "SELECT hotspot_correct |
||
| 4472 | FROM $TBL_TRACK_HOTSPOT |
||
| 4473 | WHERE |
||
| 4474 | hotspot_exe_id = $exeId AND |
||
| 4475 | hotspot_question_id= $questionId AND |
||
| 4476 | hotspot_answer_id = ".intval($answerId)." |
||
| 4477 | ORDER BY hotspot_id ASC"; |
||
| 4478 | $result = Database::query($sql); |
||
| 4479 | |||
| 4480 | if (Database::num_rows($result)) { |
||
| 4481 | $studentChoice = Database::result( |
||
| 4482 | $result, |
||
| 4483 | 0, |
||
| 4484 | 'hotspot_correct' |
||
| 4485 | ); |
||
| 4486 | |||
| 4487 | if ($studentChoice) { |
||
| 4488 | $questionScore += $answerWeighting; |
||
| 4489 | $totalScore += $answerWeighting; |
||
| 4490 | } |
||
| 4491 | } else { |
||
| 4492 | // check answer.iid |
||
| 4493 | if (!empty($answerIid)) { |
||
| 4494 | $sql = "SELECT hotspot_correct |
||
| 4495 | FROM $TBL_TRACK_HOTSPOT |
||
| 4496 | WHERE |
||
| 4497 | hotspot_exe_id = $exeId AND |
||
| 4498 | hotspot_question_id= $questionId AND |
||
| 4499 | hotspot_answer_id = ".intval($answerIid)." |
||
| 4500 | ORDER BY hotspot_id ASC"; |
||
| 4501 | $result = Database::query($sql); |
||
| 4502 | |||
| 4503 | $studentChoice = Database::result( |
||
| 4504 | $result, |
||
| 4505 | 0, |
||
| 4506 | 'hotspot_correct' |
||
| 4507 | ); |
||
| 4508 | |||
| 4509 | if ($studentChoice) { |
||
| 4510 | $questionScore += $answerWeighting; |
||
| 4511 | $totalScore += $answerWeighting; |
||
| 4512 | } |
||
| 4513 | } |
||
| 4514 | } |
||
| 4515 | } |
||
| 4516 | } else { |
||
| 4517 | if (!isset($choice[$answerAutoId]) && !isset($choice[$answerIid])) { |
||
| 4518 | $choice[$answerAutoId] = 0; |
||
| 4519 | $choice[$answerIid] = 0; |
||
| 4520 | } else { |
||
| 4521 | $studentChoice = $choice[$answerAutoId]; |
||
| 4522 | if (empty($studentChoice)) { |
||
| 4523 | $studentChoice = $choice[$answerIid]; |
||
| 4524 | } |
||
| 4525 | $choiceIsValid = false; |
||
| 4526 | if (!empty($studentChoice)) { |
||
| 4527 | $hotspotType = $objAnswerTmp->selectHotspotType($answerId); |
||
| 4528 | $hotspotCoordinates = $objAnswerTmp->selectHotspotCoordinates($answerId); |
||
| 4529 | $choicePoint = Geometry::decodePoint($studentChoice); |
||
| 4530 | |||
| 4531 | switch ($hotspotType) { |
||
| 4532 | case 'square': |
||
| 4533 | $hotspotProperties = Geometry::decodeSquare($hotspotCoordinates); |
||
| 4534 | $choiceIsValid = Geometry::pointIsInSquare($hotspotProperties, $choicePoint); |
||
| 4535 | break; |
||
| 4536 | case 'circle': |
||
| 4537 | $hotspotProperties = Geometry::decodeEllipse($hotspotCoordinates); |
||
| 4538 | $choiceIsValid = Geometry::pointIsInEllipse($hotspotProperties, $choicePoint); |
||
| 4539 | break; |
||
| 4540 | case 'poly': |
||
| 4541 | $hotspotProperties = Geometry::decodePolygon($hotspotCoordinates); |
||
| 4542 | $choiceIsValid = Geometry::pointIsInPolygon($hotspotProperties, $choicePoint); |
||
| 4543 | break; |
||
| 4544 | } |
||
| 4545 | } |
||
| 4546 | |||
| 4547 | $choice[$answerAutoId] = 0; |
||
| 4548 | if ($choiceIsValid) { |
||
| 4549 | $questionScore += $answerWeighting; |
||
| 4550 | $totalScore += $answerWeighting; |
||
| 4551 | $choice[$answerAutoId] = 1; |
||
| 4552 | $choice[$answerIid] = 1; |
||
| 4553 | } |
||
| 4554 | } |
||
| 4555 | } |
||
| 4556 | break; |
||
| 4557 | case HOT_SPOT_ORDER: |
||
| 4558 | // @todo never added to chamilo |
||
| 4559 | // for hotspot with fixed order |
||
| 4560 | $studentChoice = $choice['order'][$answerId]; |
||
| 4561 | if ($studentChoice == $answerId) { |
||
| 4562 | $questionScore += $answerWeighting; |
||
| 4563 | $totalScore += $answerWeighting; |
||
| 4564 | $studentChoice = true; |
||
| 4565 | } else { |
||
| 4566 | $studentChoice = false; |
||
| 4567 | } |
||
| 4568 | break; |
||
| 4569 | case HOT_SPOT_DELINEATION: |
||
| 4570 | // for hotspot with delineation |
||
| 4571 | if ($from_database) { |
||
| 4572 | // getting the user answer |
||
| 4573 | $TBL_TRACK_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); |
||
| 4574 | $query = "SELECT hotspot_correct, hotspot_coordinate |
||
| 4575 | FROM $TBL_TRACK_HOTSPOT |
||
| 4576 | WHERE |
||
| 4577 | hotspot_exe_id = '".$exeId."' AND |
||
| 4578 | hotspot_question_id= '".$questionId."' AND |
||
| 4579 | hotspot_answer_id='1'"; |
||
| 4580 | //by default we take 1 because it's a delineation |
||
| 4581 | $resq = Database::query($query); |
||
| 4582 | $row = Database::fetch_array($resq, 'ASSOC'); |
||
| 4583 | |||
| 4584 | $choice = $row['hotspot_correct']; |
||
| 4585 | $user_answer = $row['hotspot_coordinate']; |
||
| 4586 | |||
| 4587 | // THIS is very important otherwise the poly_compile will throw an error!! |
||
| 4588 | // round-up the coordinates |
||
| 4589 | $coords = explode('/', $user_answer); |
||
| 4590 | $user_array = ''; |
||
| 4591 | foreach ($coords as $coord) { |
||
| 4592 | list($x, $y) = explode(';', $coord); |
||
| 4593 | $user_array .= round($x).';'.round($y).'/'; |
||
| 4594 | } |
||
| 4595 | $user_array = substr($user_array, 0, -1); |
||
| 4596 | } else { |
||
| 4597 | if (!empty($studentChoice)) { |
||
| 4598 | $newquestionList[] = $questionId; |
||
| 4599 | } |
||
| 4600 | |||
| 4601 | if ($answerId === 1) { |
||
| 4602 | $studentChoice = $choice[$answerId]; |
||
| 4603 | $questionScore += $answerWeighting; |
||
| 4604 | |||
| 4605 | if ($hotspot_delineation_result[1] == 1) { |
||
| 4606 | $totalScore += $answerWeighting; //adding the total |
||
| 4607 | } |
||
| 4608 | } |
||
| 4609 | } |
||
| 4610 | $_SESSION['hotspot_coord'][1] = $delineation_cord; |
||
| 4611 | $_SESSION['hotspot_dest'][1] = $answer_delineation_destination; |
||
| 4612 | break; |
||
| 4613 | case ANNOTATION: |
||
| 4614 | if ($from_database) { |
||
| 4615 | $sql = "SELECT answer, marks FROM $TBL_TRACK_ATTEMPT |
||
| 4616 | WHERE |
||
| 4617 | exe_id = $exeId AND |
||
| 4618 | question_id= ".$questionId; |
||
| 4619 | $resq = Database::query($sql); |
||
| 4620 | $data = Database::fetch_array($resq); |
||
| 4621 | |||
| 4622 | $questionScore = empty($data['marks']) ? 0 : $data['marks']; |
||
| 4623 | $totalScore += $questionScore == -1 ? 0 : $questionScore; |
||
| 4624 | |||
| 4625 | $arrques = $questionName; |
||
| 4626 | break; |
||
| 4627 | } |
||
| 4628 | $studentChoice = $choice; |
||
| 4629 | if ($studentChoice) { |
||
| 4630 | $questionScore = 0; |
||
| 4631 | $totalScore += 0; |
||
| 4632 | } |
||
| 4633 | break; |
||
| 4634 | } // end switch Answertype |
||
| 4635 | |||
| 4636 | if ($show_result) { |
||
| 4637 | if ($debug) { |
||
| 4638 | error_log('Showing questions $from '.$from); |
||
| 4639 | } |
||
| 4640 | if ($from === 'exercise_result') { |
||
| 4641 | //display answers (if not matching type, or if the answer is correct) |
||
| 4642 | if (!in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE]) || |
||
| 4643 | $answerCorrect |
||
| 4644 | ) { |
||
| 4645 | if (in_array( |
||
| 4646 | $answerType, |
||
| 4647 | [ |
||
| 4648 | UNIQUE_ANSWER, |
||
| 4649 | UNIQUE_ANSWER_IMAGE, |
||
| 4650 | UNIQUE_ANSWER_NO_OPTION, |
||
| 4651 | MULTIPLE_ANSWER, |
||
| 4652 | MULTIPLE_ANSWER_COMBINATION, |
||
| 4653 | GLOBAL_MULTIPLE_ANSWER, |
||
| 4654 | READING_COMPREHENSION, |
||
| 4655 | ] |
||
| 4656 | )) { |
||
| 4657 | ExerciseShowFunctions::display_unique_or_multiple_answer( |
||
| 4658 | $this, |
||
| 4659 | $feedback_type, |
||
| 4660 | $answerType, |
||
| 4661 | $studentChoice, |
||
| 4662 | $answer, |
||
| 4663 | $answerComment, |
||
| 4664 | $answerCorrect, |
||
| 4665 | 0, |
||
| 4666 | 0, |
||
| 4667 | 0, |
||
| 4668 | $results_disabled, |
||
| 4669 | $showTotalScoreAndUserChoicesInLastAttempt, |
||
| 4670 | $this->export |
||
| 4671 | ); |
||
| 4672 | } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { |
||
| 4673 | ExerciseShowFunctions::display_multiple_answer_true_false( |
||
| 4674 | $this, |
||
| 4675 | $feedback_type, |
||
| 4676 | $answerType, |
||
| 4677 | $studentChoice, |
||
| 4678 | $answer, |
||
| 4679 | $answerComment, |
||
| 4680 | $answerCorrect, |
||
| 4681 | 0, |
||
| 4682 | $questionId, |
||
| 4683 | 0, |
||
| 4684 | $results_disabled, |
||
| 4685 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 4686 | ); |
||
| 4687 | } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { |
||
| 4688 | ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( |
||
| 4689 | $feedback_type, |
||
| 4690 | $studentChoice, |
||
| 4691 | $studentChoiceDegree, |
||
| 4692 | $answer, |
||
| 4693 | $answerComment, |
||
| 4694 | $answerCorrect, |
||
| 4695 | $questionId, |
||
| 4696 | $results_disabled |
||
| 4697 | ); |
||
| 4698 | } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { |
||
| 4699 | ExerciseShowFunctions::display_multiple_answer_combination_true_false( |
||
| 4700 | $this, |
||
| 4701 | $feedback_type, |
||
| 4702 | $answerType, |
||
| 4703 | $studentChoice, |
||
| 4704 | $answer, |
||
| 4705 | $answerComment, |
||
| 4706 | $answerCorrect, |
||
| 4707 | 0, |
||
| 4708 | 0, |
||
| 4709 | 0, |
||
| 4710 | $results_disabled, |
||
| 4711 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 4712 | ); |
||
| 4713 | } elseif ($answerType == FILL_IN_BLANKS) { |
||
| 4714 | ExerciseShowFunctions::display_fill_in_blanks_answer( |
||
| 4715 | $feedback_type, |
||
| 4716 | $answer, |
||
| 4717 | 0, |
||
| 4718 | 0, |
||
| 4719 | $results_disabled, |
||
| 4720 | '', |
||
| 4721 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 4722 | ); |
||
| 4723 | } elseif ($answerType == CALCULATED_ANSWER) { |
||
| 4724 | ExerciseShowFunctions::display_calculated_answer( |
||
| 4725 | $this, |
||
| 4726 | $feedback_type, |
||
| 4727 | $answer, |
||
| 4728 | 0, |
||
| 4729 | 0, |
||
| 4730 | $results_disabled, |
||
| 4731 | $showTotalScoreAndUserChoicesInLastAttempt, |
||
| 4732 | $expectedAnswer, |
||
| 4733 | $calculatedChoice, |
||
| 4734 | $calculatedStatus |
||
| 4735 | ); |
||
| 4736 | } elseif ($answerType == FREE_ANSWER) { |
||
| 4737 | ExerciseShowFunctions::display_free_answer( |
||
| 4738 | $feedback_type, |
||
| 4739 | $choice, |
||
| 4740 | $exeId, |
||
| 4741 | $questionId, |
||
| 4742 | $questionScore, |
||
| 4743 | $results_disabled |
||
| 4744 | ); |
||
| 4745 | } elseif ($answerType == ORAL_EXPRESSION) { |
||
| 4746 | // to store the details of open questions in an array to be used in mail |
||
| 4747 | /** @var OralExpression $objQuestionTmp */ |
||
| 4748 | ExerciseShowFunctions::display_oral_expression_answer( |
||
| 4749 | $feedback_type, |
||
| 4750 | $choice, |
||
| 4751 | 0, |
||
| 4752 | 0, |
||
| 4753 | $objQuestionTmp->getFileUrl(true), |
||
| 4754 | $results_disabled, |
||
| 4755 | $questionScore |
||
| 4756 | ); |
||
| 4757 | } elseif ($answerType == HOT_SPOT) { |
||
| 4758 | $correctAnswerId = 0; |
||
| 4759 | /** |
||
| 4760 | * @var int |
||
| 4761 | * @var TrackEHotspot $hotspot |
||
| 4762 | */ |
||
| 4763 | foreach ($orderedHotspots as $correctAnswerId => $hotspot) { |
||
| 4764 | if ($hotspot->getHotspotAnswerId() == $answerAutoId) { |
||
| 4765 | break; |
||
| 4766 | } |
||
| 4767 | } |
||
| 4768 | |||
| 4769 | // force to show whether the choice is correct or not |
||
| 4770 | $showTotalScoreAndUserChoicesInLastAttempt = true; |
||
| 4771 | ExerciseShowFunctions::display_hotspot_answer( |
||
| 4772 | $feedback_type, |
||
| 4773 | ++$correctAnswerId, |
||
| 4774 | $answer, |
||
| 4775 | $studentChoice, |
||
| 4776 | $answerComment, |
||
| 4777 | $results_disabled, |
||
| 4778 | $correctAnswerId, |
||
| 4779 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 4780 | ); |
||
| 4781 | } elseif ($answerType == HOT_SPOT_ORDER) { |
||
| 4782 | ExerciseShowFunctions::display_hotspot_order_answer( |
||
| 4783 | $feedback_type, |
||
| 4784 | $answerId, |
||
| 4785 | $answer, |
||
| 4786 | $studentChoice, |
||
| 4787 | $answerComment |
||
| 4788 | ); |
||
| 4789 | } elseif ($answerType == HOT_SPOT_DELINEATION) { |
||
| 4790 | $user_answer = $_SESSION['exerciseResultCoordinates'][$questionId]; |
||
| 4791 | |||
| 4792 | //round-up the coordinates |
||
| 4793 | $coords = explode('/', $user_answer); |
||
| 4794 | $user_array = ''; |
||
| 4795 | foreach ($coords as $coord) { |
||
| 4796 | list($x, $y) = explode(';', $coord); |
||
| 4797 | $user_array .= round($x).';'.round($y).'/'; |
||
| 4798 | } |
||
| 4799 | $user_array = substr($user_array, 0, -1); |
||
| 4800 | |||
| 4801 | if ($next) { |
||
| 4802 | $user_answer = $user_array; |
||
| 4803 | // we compare only the delineation not the other points |
||
| 4804 | $answer_question = $_SESSION['hotspot_coord'][1]; |
||
| 4805 | $answerDestination = $_SESSION['hotspot_dest'][1]; |
||
| 4806 | |||
| 4807 | //calculating the area |
||
| 4808 | $poly_user = convert_coordinates($user_answer, '/'); |
||
| 4809 | $poly_answer = convert_coordinates($answer_question, '|'); |
||
| 4810 | $max_coord = poly_get_max($poly_user, $poly_answer); |
||
| 4811 | $poly_user_compiled = poly_compile($poly_user, $max_coord); |
||
| 4812 | $poly_answer_compiled = poly_compile($poly_answer, $max_coord); |
||
| 4813 | $poly_results = poly_result($poly_answer_compiled, $poly_user_compiled, $max_coord); |
||
| 4814 | |||
| 4815 | $overlap = $poly_results['both']; |
||
| 4816 | $poly_answer_area = $poly_results['s1']; |
||
| 4817 | $poly_user_area = $poly_results['s2']; |
||
| 4818 | $missing = $poly_results['s1Only']; |
||
| 4819 | $excess = $poly_results['s2Only']; |
||
| 4820 | |||
| 4821 | //$overlap = round(polygons_overlap($poly_answer,$poly_user)); |
||
| 4822 | // //this is an area in pixels |
||
| 4823 | if ($debug > 0) { |
||
| 4824 | error_log(__LINE__.' - Polygons results are '.print_r($poly_results, 1), 0); |
||
| 4825 | } |
||
| 4826 | |||
| 4827 | if ($overlap < 1) { |
||
| 4828 | //shortcut to avoid complicated calculations |
||
| 4829 | $final_overlap = 0; |
||
| 4830 | $final_missing = 100; |
||
| 4831 | $final_excess = 100; |
||
| 4832 | } else { |
||
| 4833 | // the final overlap is the percentage of the initial polygon |
||
| 4834 | // that is overlapped by the user's polygon |
||
| 4835 | $final_overlap = round(((float) $overlap / (float) $poly_answer_area) * 100); |
||
| 4836 | if ($debug > 1) { |
||
| 4837 | error_log(__LINE__.' - Final overlap is '.$final_overlap, 0); |
||
| 4838 | } |
||
| 4839 | // the final missing area is the percentage of the initial polygon |
||
| 4840 | // that is not overlapped by the user's polygon |
||
| 4841 | $final_missing = 100 - $final_overlap; |
||
| 4842 | if ($debug > 1) { |
||
| 4843 | error_log(__LINE__.' - Final missing is '.$final_missing, 0); |
||
| 4844 | } |
||
| 4845 | // the final excess area is the percentage of the initial polygon's size |
||
| 4846 | // that is covered by the user's polygon outside of the initial polygon |
||
| 4847 | $final_excess = round((((float) $poly_user_area - (float) $overlap) / (float) $poly_answer_area) * 100); |
||
| 4848 | if ($debug > 1) { |
||
| 4849 | error_log(__LINE__.' - Final excess is '.$final_excess, 0); |
||
| 4850 | } |
||
| 4851 | } |
||
| 4852 | |||
| 4853 | //checking the destination parameters parsing the "@@" |
||
| 4854 | $destination_items = explode( |
||
| 4855 | '@@', |
||
| 4856 | $answerDestination |
||
| 4857 | ); |
||
| 4858 | $threadhold_total = $destination_items[0]; |
||
| 4859 | $threadhold_items = explode( |
||
| 4860 | ';', |
||
| 4861 | $threadhold_total |
||
| 4862 | ); |
||
| 4863 | $threadhold1 = $threadhold_items[0]; // overlap |
||
| 4864 | $threadhold2 = $threadhold_items[1]; // excess |
||
| 4865 | $threadhold3 = $threadhold_items[2]; //missing |
||
| 4866 | |||
| 4867 | // if is delineation |
||
| 4868 | if ($answerId === 1) { |
||
| 4869 | //setting colors |
||
| 4870 | if ($final_overlap >= $threadhold1) { |
||
| 4871 | $overlap_color = true; //echo 'a'; |
||
| 4872 | } |
||
| 4873 | //echo $excess.'-'.$threadhold2; |
||
| 4874 | if ($final_excess <= $threadhold2) { |
||
| 4875 | $excess_color = true; //echo 'b'; |
||
| 4876 | } |
||
| 4877 | //echo '--------'.$missing.'-'.$threadhold3; |
||
| 4878 | if ($final_missing <= $threadhold3) { |
||
| 4879 | $missing_color = true; //echo 'c'; |
||
| 4880 | } |
||
| 4881 | |||
| 4882 | // if pass |
||
| 4883 | if ($final_overlap >= $threadhold1 && |
||
| 4884 | $final_missing <= $threadhold3 && |
||
| 4885 | $final_excess <= $threadhold2 |
||
| 4886 | ) { |
||
| 4887 | $next = 1; //go to the oars |
||
| 4888 | $result_comment = get_lang('Acceptable'); |
||
| 4889 | $final_answer = 1; // do not update with update_exercise_attempt |
||
| 4890 | } else { |
||
| 4891 | $next = 0; |
||
| 4892 | $result_comment = get_lang('Unacceptable'); |
||
| 4893 | $comment = $answerDestination = $objAnswerTmp->selectComment(1); |
||
| 4894 | $answerDestination = $objAnswerTmp->selectDestination(1); |
||
| 4895 | // checking the destination parameters parsing the "@@" |
||
| 4896 | $destination_items = explode('@@', $answerDestination); |
||
| 4897 | } |
||
| 4898 | } elseif ($answerId > 1) { |
||
| 4899 | if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') { |
||
| 4900 | if ($debug > 0) { |
||
| 4901 | error_log(__LINE__.' - answerId is of type noerror', 0); |
||
| 4902 | } |
||
| 4903 | //type no error shouldn't be treated |
||
| 4904 | $next = 1; |
||
| 4905 | continue; |
||
| 4906 | } |
||
| 4907 | if ($debug > 0) { |
||
| 4908 | error_log(__LINE__.' - answerId is >1 so we\'re probably in OAR', 0); |
||
| 4909 | } |
||
| 4910 | $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId); |
||
| 4911 | $poly_answer = convert_coordinates($delineation_cord, '|'); |
||
| 4912 | $max_coord = poly_get_max($poly_user, $poly_answer); |
||
| 4913 | $poly_answer_compiled = poly_compile($poly_answer, $max_coord); |
||
| 4914 | $overlap = poly_touch($poly_user_compiled, $poly_answer_compiled, $max_coord); |
||
| 4915 | |||
| 4916 | if ($overlap == false) { |
||
| 4917 | //all good, no overlap |
||
| 4918 | $next = 1; |
||
| 4919 | continue; |
||
| 4920 | } else { |
||
| 4921 | if ($debug > 0) { |
||
| 4922 | error_log(__LINE__.' - Overlap is '.$overlap.': OAR hit', 0); |
||
| 4923 | } |
||
| 4924 | $organs_at_risk_hit++; |
||
| 4925 | //show the feedback |
||
| 4926 | $next = 0; |
||
| 4927 | $comment = $answerDestination = $objAnswerTmp->selectComment($answerId); |
||
| 4928 | $answerDestination = $objAnswerTmp->selectDestination($answerId); |
||
| 4929 | |||
| 4930 | $destination_items = explode('@@', $answerDestination); |
||
| 4931 | $try_hotspot = $destination_items[1]; |
||
| 4932 | $lp_hotspot = $destination_items[2]; |
||
| 4933 | $select_question_hotspot = $destination_items[3]; |
||
| 4934 | $url_hotspot = $destination_items[4]; |
||
| 4935 | } |
||
| 4936 | } |
||
| 4937 | } else { |
||
| 4938 | // the first delineation feedback |
||
| 4939 | if ($debug > 0) { |
||
| 4940 | error_log(__LINE__.' first', 0); |
||
| 4941 | } |
||
| 4942 | } |
||
| 4943 | } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { |
||
| 4944 | echo '<tr>'; |
||
| 4945 | echo Display::tag('td', $answerMatching[$answerId]); |
||
| 4946 | echo Display::tag( |
||
| 4947 | 'td', |
||
| 4948 | "$user_answer / ".Display::tag( |
||
| 4949 | 'strong', |
||
| 4950 | $answerMatching[$answerCorrect], |
||
| 4951 | ['style' => 'color: #008000; font-weight: bold;'] |
||
| 4952 | ) |
||
| 4953 | ); |
||
| 4954 | echo '</tr>'; |
||
| 4955 | } elseif ($answerType == ANNOTATION) { |
||
| 4956 | ExerciseShowFunctions::displayAnnotationAnswer( |
||
| 4957 | $feedback_type, |
||
| 4958 | $exeId, |
||
| 4959 | $questionId, |
||
| 4960 | $questionScore, |
||
| 4961 | $results_disabled |
||
| 4962 | ); |
||
| 4963 | } |
||
| 4964 | } |
||
| 4965 | } else { |
||
| 4966 | if ($debug) { |
||
| 4967 | error_log('Showing questions $from '.$from); |
||
| 4968 | } |
||
| 4969 | switch ($answerType) { |
||
| 4970 | case UNIQUE_ANSWER: |
||
| 4971 | case UNIQUE_ANSWER_IMAGE: |
||
| 4972 | case UNIQUE_ANSWER_NO_OPTION: |
||
| 4973 | case MULTIPLE_ANSWER: |
||
| 4974 | case GLOBAL_MULTIPLE_ANSWER: |
||
| 4975 | case MULTIPLE_ANSWER_COMBINATION: |
||
| 4976 | case READING_COMPREHENSION: |
||
| 4977 | if ($answerId == 1) { |
||
| 4978 | ExerciseShowFunctions::display_unique_or_multiple_answer( |
||
| 4979 | $this, |
||
| 4980 | $feedback_type, |
||
| 4981 | $answerType, |
||
| 4982 | $studentChoice, |
||
| 4983 | $answer, |
||
| 4984 | $answerComment, |
||
| 4985 | $answerCorrect, |
||
| 4986 | $exeId, |
||
| 4987 | $questionId, |
||
| 4988 | $answerId, |
||
| 4989 | $results_disabled, |
||
| 4990 | $showTotalScoreAndUserChoicesInLastAttempt, |
||
| 4991 | $this->export |
||
| 4992 | ); |
||
| 4993 | } else { |
||
| 4994 | ExerciseShowFunctions::display_unique_or_multiple_answer( |
||
| 4995 | $this, |
||
| 4996 | $feedback_type, |
||
| 4997 | $answerType, |
||
| 4998 | $studentChoice, |
||
| 4999 | $answer, |
||
| 5000 | $answerComment, |
||
| 5001 | $answerCorrect, |
||
| 5002 | $exeId, |
||
| 5003 | $questionId, |
||
| 5004 | '', |
||
| 5005 | $results_disabled, |
||
| 5006 | $showTotalScoreAndUserChoicesInLastAttempt, |
||
| 5007 | $this->export |
||
| 5008 | ); |
||
| 5009 | } |
||
| 5010 | break; |
||
| 5011 | case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE: |
||
| 5012 | if ($answerId == 1) { |
||
| 5013 | ExerciseShowFunctions::display_multiple_answer_combination_true_false( |
||
| 5014 | $this, |
||
| 5015 | $feedback_type, |
||
| 5016 | $answerType, |
||
| 5017 | $studentChoice, |
||
| 5018 | $answer, |
||
| 5019 | $answerComment, |
||
| 5020 | $answerCorrect, |
||
| 5021 | $exeId, |
||
| 5022 | $questionId, |
||
| 5023 | $answerId, |
||
| 5024 | $results_disabled, |
||
| 5025 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5026 | ); |
||
| 5027 | } else { |
||
| 5028 | ExerciseShowFunctions::display_multiple_answer_combination_true_false( |
||
| 5029 | $this, |
||
| 5030 | $feedback_type, |
||
| 5031 | $answerType, |
||
| 5032 | $studentChoice, |
||
| 5033 | $answer, |
||
| 5034 | $answerComment, |
||
| 5035 | $answerCorrect, |
||
| 5036 | $exeId, |
||
| 5037 | $questionId, |
||
| 5038 | '', |
||
| 5039 | $results_disabled, |
||
| 5040 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5041 | ); |
||
| 5042 | } |
||
| 5043 | break; |
||
| 5044 | case MULTIPLE_ANSWER_TRUE_FALSE: |
||
| 5045 | if ($answerId == 1) { |
||
| 5046 | ExerciseShowFunctions::display_multiple_answer_true_false( |
||
| 5047 | $this, |
||
| 5048 | $feedback_type, |
||
| 5049 | $answerType, |
||
| 5050 | $studentChoice, |
||
| 5051 | $answer, |
||
| 5052 | $answerComment, |
||
| 5053 | $answerCorrect, |
||
| 5054 | $exeId, |
||
| 5055 | $questionId, |
||
| 5056 | $answerId, |
||
| 5057 | $results_disabled, |
||
| 5058 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5059 | ); |
||
| 5060 | } else { |
||
| 5061 | ExerciseShowFunctions::display_multiple_answer_true_false( |
||
| 5062 | $this, |
||
| 5063 | $feedback_type, |
||
| 5064 | $answerType, |
||
| 5065 | $studentChoice, |
||
| 5066 | $answer, |
||
| 5067 | $answerComment, |
||
| 5068 | $answerCorrect, |
||
| 5069 | $exeId, |
||
| 5070 | $questionId, |
||
| 5071 | '', |
||
| 5072 | $results_disabled, |
||
| 5073 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5074 | ); |
||
| 5075 | } |
||
| 5076 | break; |
||
| 5077 | case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY: |
||
| 5078 | if ($answerId == 1) { |
||
| 5079 | ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( |
||
| 5080 | $feedback_type, |
||
| 5081 | $studentChoice, |
||
| 5082 | $studentChoiceDegree, |
||
| 5083 | $answer, |
||
| 5084 | $answerComment, |
||
| 5085 | $answerCorrect, |
||
| 5086 | $questionId, |
||
| 5087 | $results_disabled |
||
| 5088 | ); |
||
| 5089 | } else { |
||
| 5090 | ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( |
||
| 5091 | $feedback_type, |
||
| 5092 | $studentChoice, |
||
| 5093 | $studentChoiceDegree, |
||
| 5094 | $answer, |
||
| 5095 | $answerComment, |
||
| 5096 | $answerCorrect, |
||
| 5097 | $questionId, |
||
| 5098 | $results_disabled |
||
| 5099 | ); |
||
| 5100 | } |
||
| 5101 | break; |
||
| 5102 | case FILL_IN_BLANKS: |
||
| 5103 | ExerciseShowFunctions::display_fill_in_blanks_answer( |
||
| 5104 | $feedback_type, |
||
| 5105 | $answer, |
||
| 5106 | $exeId, |
||
| 5107 | $questionId, |
||
| 5108 | $results_disabled, |
||
| 5109 | $str, |
||
| 5110 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5111 | ); |
||
| 5112 | break; |
||
| 5113 | case CALCULATED_ANSWER: |
||
| 5114 | ExerciseShowFunctions::display_calculated_answer( |
||
| 5115 | $this, |
||
| 5116 | $feedback_type, |
||
| 5117 | $answer, |
||
| 5118 | $exeId, |
||
| 5119 | $questionId, |
||
| 5120 | $results_disabled, |
||
| 5121 | '', |
||
| 5122 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5123 | ); |
||
| 5124 | break; |
||
| 5125 | case FREE_ANSWER: |
||
| 5126 | echo ExerciseShowFunctions::display_free_answer( |
||
| 5127 | $feedback_type, |
||
| 5128 | $choice, |
||
| 5129 | $exeId, |
||
| 5130 | $questionId, |
||
| 5131 | $questionScore, |
||
| 5132 | $results_disabled |
||
| 5133 | ); |
||
| 5134 | break; |
||
| 5135 | case ORAL_EXPRESSION: |
||
| 5136 | echo '<tr> |
||
| 5137 | <td valign="top">'. |
||
| 5138 | ExerciseShowFunctions::display_oral_expression_answer( |
||
| 5139 | $feedback_type, |
||
| 5140 | $choice, |
||
| 5141 | $exeId, |
||
| 5142 | $questionId, |
||
| 5143 | $objQuestionTmp->getFileUrl(), |
||
| 5144 | $results_disabled, |
||
| 5145 | $questionScore |
||
| 5146 | ).'</td> |
||
| 5147 | </tr> |
||
| 5148 | </table>'; |
||
| 5149 | break; |
||
| 5150 | case HOT_SPOT: |
||
| 5151 | ExerciseShowFunctions::display_hotspot_answer( |
||
| 5152 | $feedback_type, |
||
| 5153 | $answerId, |
||
| 5154 | $answer, |
||
| 5155 | $studentChoice, |
||
| 5156 | $answerComment, |
||
| 5157 | $results_disabled, |
||
| 5158 | $answerId, |
||
| 5159 | $showTotalScoreAndUserChoicesInLastAttempt |
||
| 5160 | ); |
||
| 5161 | break; |
||
| 5162 | case HOT_SPOT_DELINEATION: |
||
| 5163 | $user_answer = $user_array; |
||
| 5164 | if ($next) { |
||
| 5165 | //$tbl_track_e_hotspot = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); |
||
| 5166 | // Save into db |
||
| 5167 | /* $sql = "INSERT INTO $tbl_track_e_hotspot ( |
||
| 5168 | * hotspot_user_id, |
||
| 5169 | * hotspot_course_code, |
||
| 5170 | * hotspot_exe_id, |
||
| 5171 | * hotspot_question_id, |
||
| 5172 | * hotspot_answer_id, |
||
| 5173 | * hotspot_correct, |
||
| 5174 | * hotspot_coordinate |
||
| 5175 | * ) |
||
| 5176 | VALUES ( |
||
| 5177 | * '".Database::escape_string($_user['user_id'])."', |
||
| 5178 | * '".Database::escape_string($_course['id'])."', |
||
| 5179 | * '".Database::escape_string($exeId)."', '".Database::escape_string($questionId)."', |
||
| 5180 | * '".Database::escape_string($answerId)."', |
||
| 5181 | * '".Database::escape_string($studentChoice)."', |
||
| 5182 | * '".Database::escape_string($user_array)."')"; |
||
| 5183 | $result = Database::query($sql,__FILE__,__LINE__); |
||
| 5184 | */ |
||
| 5185 | $user_answer = $user_array; |
||
| 5186 | // we compare only the delineation not the other points |
||
| 5187 | $answer_question = $_SESSION['hotspot_coord'][1]; |
||
| 5188 | $answerDestination = $_SESSION['hotspot_dest'][1]; |
||
| 5189 | |||
| 5190 | // calculating the area |
||
| 5191 | $poly_user = convert_coordinates($user_answer, '/'); |
||
| 5192 | $poly_answer = convert_coordinates($answer_question, '|'); |
||
| 5193 | $max_coord = poly_get_max($poly_user, $poly_answer); |
||
| 5194 | $poly_user_compiled = poly_compile($poly_user, $max_coord); |
||
| 5195 | $poly_answer_compiled = poly_compile($poly_answer, $max_coord); |
||
| 5196 | $poly_results = poly_result($poly_answer_compiled, $poly_user_compiled, $max_coord); |
||
| 5197 | |||
| 5198 | $overlap = $poly_results['both']; |
||
| 5199 | $poly_answer_area = $poly_results['s1']; |
||
| 5200 | $poly_user_area = $poly_results['s2']; |
||
| 5201 | $missing = $poly_results['s1Only']; |
||
| 5202 | $excess = $poly_results['s2Only']; |
||
| 5203 | if ($debug > 0) { |
||
| 5204 | error_log(__LINE__.' - Polygons results are '.print_r($poly_results, 1), 0); |
||
| 5205 | } |
||
| 5206 | if ($overlap < 1) { |
||
| 5207 | //shortcut to avoid complicated calculations |
||
| 5208 | $final_overlap = 0; |
||
| 5209 | $final_missing = 100; |
||
| 5210 | $final_excess = 100; |
||
| 5211 | } else { |
||
| 5212 | // the final overlap is the percentage of the initial polygon that is overlapped by the user's polygon |
||
| 5213 | $final_overlap = round(((float) $overlap / (float) $poly_answer_area) * 100); |
||
| 5214 | if ($debug > 1) { |
||
| 5215 | error_log(__LINE__.' - Final overlap is '.$final_overlap, 0); |
||
| 5216 | } |
||
| 5217 | // the final missing area is the percentage of the initial polygon that is not overlapped by the user's polygon |
||
| 5218 | $final_missing = 100 - $final_overlap; |
||
| 5219 | if ($debug > 1) { |
||
| 5220 | error_log(__LINE__.' - Final missing is '.$final_missing, 0); |
||
| 5221 | } |
||
| 5222 | // the final excess area is the percentage of the initial polygon's size that is covered by the user's polygon outside of the initial polygon |
||
| 5223 | $final_excess = round((((float) $poly_user_area - (float) $overlap) / (float) $poly_answer_area) * 100); |
||
| 5224 | if ($debug > 1) { |
||
| 5225 | error_log(__LINE__.' - Final excess is '.$final_excess, 0); |
||
| 5226 | } |
||
| 5227 | } |
||
| 5228 | |||
| 5229 | // Checking the destination parameters parsing the "@@" |
||
| 5230 | $destination_items = explode('@@', $answerDestination); |
||
| 5231 | $threadhold_total = $destination_items[0]; |
||
| 5232 | $threadhold_items = explode(';', $threadhold_total); |
||
| 5233 | $threadhold1 = $threadhold_items[0]; // overlap |
||
| 5234 | $threadhold2 = $threadhold_items[1]; // excess |
||
| 5235 | $threadhold3 = $threadhold_items[2]; //missing |
||
| 5236 | // if is delineation |
||
| 5237 | if ($answerId === 1) { |
||
| 5238 | //setting colors |
||
| 5239 | if ($final_overlap >= $threadhold1) { |
||
| 5240 | $overlap_color = true; //echo 'a'; |
||
| 5241 | } |
||
| 5242 | if ($final_excess <= $threadhold2) { |
||
| 5243 | $excess_color = true; //echo 'b'; |
||
| 5244 | } |
||
| 5245 | if ($final_missing <= $threadhold3) { |
||
| 5246 | $missing_color = true; //echo 'c'; |
||
| 5247 | } |
||
| 5248 | |||
| 5249 | // if pass |
||
| 5250 | if ($final_overlap >= $threadhold1 && |
||
| 5251 | $final_missing <= $threadhold3 && |
||
| 5252 | $final_excess <= $threadhold2 |
||
| 5253 | ) { |
||
| 5254 | $next = 1; //go to the oars |
||
| 5255 | $result_comment = get_lang('Acceptable'); |
||
| 5256 | $final_answer = 1; // do not update with update_exercise_attempt |
||
| 5257 | } else { |
||
| 5258 | $next = 0; |
||
| 5259 | $result_comment = get_lang('Unacceptable'); |
||
| 5260 | $comment = $answerDestination = $objAnswerTmp->selectComment(1); |
||
| 5261 | $answerDestination = $objAnswerTmp->selectDestination(1); |
||
| 5262 | //checking the destination parameters parsing the "@@" |
||
| 5263 | $destination_items = explode('@@', $answerDestination); |
||
| 5264 | } |
||
| 5265 | } elseif ($answerId > 1) { |
||
| 5266 | if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') { |
||
| 5267 | if ($debug > 0) { |
||
| 5268 | error_log(__LINE__.' - answerId is of type noerror', 0); |
||
| 5269 | } |
||
| 5270 | //type no error shouldn't be treated |
||
| 5271 | $next = 1; |
||
| 5272 | continue; |
||
| 5273 | } |
||
| 5274 | if ($debug > 0) { |
||
| 5275 | error_log(__LINE__.' - answerId is >1 so we\'re probably in OAR', 0); |
||
| 5276 | } |
||
| 5277 | $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId); |
||
| 5278 | $poly_answer = convert_coordinates($delineation_cord, '|'); |
||
| 5279 | $max_coord = poly_get_max($poly_user, $poly_answer); |
||
| 5280 | $poly_answer_compiled = poly_compile($poly_answer, $max_coord); |
||
| 5281 | $overlap = poly_touch($poly_user_compiled, $poly_answer_compiled, $max_coord); |
||
| 5282 | |||
| 5283 | if ($overlap == false) { |
||
| 5284 | //all good, no overlap |
||
| 5285 | $next = 1; |
||
| 5286 | continue; |
||
| 5287 | } else { |
||
| 5288 | if ($debug > 0) { |
||
| 5289 | error_log(__LINE__.' - Overlap is '.$overlap.': OAR hit', 0); |
||
| 5290 | } |
||
| 5291 | $organs_at_risk_hit++; |
||
| 5292 | //show the feedback |
||
| 5293 | $next = 0; |
||
| 5294 | $comment = $answerDestination = $objAnswerTmp->selectComment($answerId); |
||
| 5295 | $answerDestination = $objAnswerTmp->selectDestination($answerId); |
||
| 5296 | |||
| 5297 | $destination_items = explode('@@', $answerDestination); |
||
| 5298 | $try_hotspot = $destination_items[1]; |
||
| 5299 | $lp_hotspot = $destination_items[2]; |
||
| 5300 | $select_question_hotspot = $destination_items[3]; |
||
| 5301 | $url_hotspot = $destination_items[4]; |
||
| 5302 | } |
||
| 5303 | } |
||
| 5304 | } else { |
||
| 5305 | // the first delineation feedback |
||
| 5306 | if ($debug > 0) { |
||
| 5307 | error_log(__LINE__.' first', 0); |
||
| 5308 | } |
||
| 5309 | } |
||
| 5310 | break; |
||
| 5311 | case HOT_SPOT_ORDER: |
||
| 5312 | ExerciseShowFunctions::display_hotspot_order_answer( |
||
| 5313 | $feedback_type, |
||
| 5314 | $answerId, |
||
| 5315 | $answer, |
||
| 5316 | $studentChoice, |
||
| 5317 | $answerComment |
||
| 5318 | ); |
||
| 5319 | break; |
||
| 5320 | case DRAGGABLE: |
||
| 5321 | case MATCHING_DRAGGABLE: |
||
| 5322 | case MATCHING: |
||
| 5323 | echo '<tr>'; |
||
| 5324 | echo Display::tag('td', $answerMatching[$answerId]); |
||
| 5325 | echo Display::tag( |
||
| 5326 | 'td', |
||
| 5327 | "$user_answer / ".Display::tag( |
||
| 5328 | 'strong', |
||
| 5329 | $answerMatching[$answerCorrect], |
||
| 5330 | ['style' => 'color: #008000; font-weight: bold;'] |
||
| 5331 | ) |
||
| 5332 | ); |
||
| 5333 | echo '</tr>'; |
||
| 5334 | |||
| 5335 | break; |
||
| 5336 | case ANNOTATION: |
||
| 5337 | ExerciseShowFunctions::displayAnnotationAnswer( |
||
| 5338 | $feedback_type, |
||
| 5339 | $exeId, |
||
| 5340 | $questionId, |
||
| 5341 | $questionScore, |
||
| 5342 | $results_disabled |
||
| 5343 | ); |
||
| 5344 | break; |
||
| 5345 | } |
||
| 5346 | } |
||
| 5347 | } |
||
| 5348 | if ($debug) { |
||
| 5349 | error_log(' ------ '); |
||
| 5350 | } |
||
| 5351 | } // end for that loops over all answers of the current question |
||
| 5352 | |||
| 5353 | if ($debug) { |
||
| 5354 | error_log('-- end answer loop --'); |
||
| 5355 | } |
||
| 5356 | |||
| 5357 | $final_answer = true; |
||
| 5358 | |||
| 5359 | foreach ($real_answers as $my_answer) { |
||
| 5360 | if (!$my_answer) { |
||
| 5361 | $final_answer = false; |
||
| 5362 | } |
||
| 5363 | } |
||
| 5364 | |||
| 5365 | //we add the total score after dealing with the answers |
||
| 5366 | if ($answerType == MULTIPLE_ANSWER_COMBINATION || |
||
| 5367 | $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE |
||
| 5368 | ) { |
||
| 5369 | if ($final_answer) { |
||
| 5370 | //getting only the first score where we save the weight of all the question |
||
| 5371 | $answerWeighting = $objAnswerTmp->selectWeighting(1); |
||
| 5372 | $questionScore += $answerWeighting; |
||
| 5373 | $totalScore += $answerWeighting; |
||
| 5374 | } |
||
| 5375 | } |
||
| 5376 | |||
| 5377 | //Fixes multiple answer question in order to be exact |
||
| 5378 | //if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { |
||
| 5379 | /* if ($answerType == GLOBAL_MULTIPLE_ANSWER) { |
||
| 5380 | $diff = @array_diff($answer_correct_array, $real_answers); |
||
| 5381 | |||
| 5382 | // All good answers or nothing works like exact |
||
| 5383 | |||
| 5384 | $counter = 1; |
||
| 5385 | $correct_answer = true; |
||
| 5386 | foreach ($real_answers as $my_answer) { |
||
| 5387 | if ($debug) |
||
| 5388 | error_log(" my_answer: $my_answer answer_correct_array[counter]: ".$answer_correct_array[$counter]); |
||
| 5389 | if ($my_answer != $answer_correct_array[$counter]) { |
||
| 5390 | $correct_answer = false; |
||
| 5391 | break; |
||
| 5392 | } |
||
| 5393 | $counter++; |
||
| 5394 | } |
||
| 5395 | |||
| 5396 | if ($debug) error_log(" answer_correct_array: ".print_r($answer_correct_array, 1).""); |
||
| 5397 | if ($debug) error_log(" real_answers: ".print_r($real_answers, 1).""); |
||
| 5398 | if ($debug) error_log(" correct_answer: ".$correct_answer); |
||
| 5399 | |||
| 5400 | if ($correct_answer == false) { |
||
| 5401 | $questionScore = 0; |
||
| 5402 | } |
||
| 5403 | |||
| 5404 | // This makes the result non exact |
||
| 5405 | if (!empty($diff)) { |
||
| 5406 | $questionScore = 0; |
||
| 5407 | } |
||
| 5408 | }*/ |
||
| 5409 | |||
| 5410 | $extra_data = [ |
||
| 5411 | 'final_overlap' => $final_overlap, |
||
| 5412 | 'final_missing' => $final_missing, |
||
| 5413 | 'final_excess' => $final_excess, |
||
| 5414 | 'overlap_color' => $overlap_color, |
||
| 5415 | 'missing_color' => $missing_color, |
||
| 5416 | 'excess_color' => $excess_color, |
||
| 5417 | 'threadhold1' => $threadhold1, |
||
| 5418 | 'threadhold2' => $threadhold2, |
||
| 5419 | 'threadhold3' => $threadhold3, |
||
| 5420 | ]; |
||
| 5421 | if ($from == 'exercise_result') { |
||
| 5422 | // if answer is hotspot. To the difference of exercise_show.php, |
||
| 5423 | // we use the results from the session (from_db=0) |
||
| 5424 | // TODO Change this, because it is wrong to show the user |
||
| 5425 | // some results that haven't been stored in the database yet |
||
| 5426 | if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER || $answerType == HOT_SPOT_DELINEATION) { |
||
| 5427 | if ($debug) { |
||
| 5428 | error_log('$from AND this is a hotspot kind of question '); |
||
| 5429 | } |
||
| 5430 | $my_exe_id = 0; |
||
| 5431 | $from_database = 0; |
||
| 5432 | if ($answerType == HOT_SPOT_DELINEATION) { |
||
| 5433 | if (0) { |
||
| 5434 | if ($overlap_color) { |
||
| 5435 | $overlap_color = 'green'; |
||
| 5436 | } else { |
||
| 5437 | $overlap_color = 'red'; |
||
| 5438 | } |
||
| 5439 | if ($missing_color) { |
||
| 5440 | $missing_color = 'green'; |
||
| 5441 | } else { |
||
| 5442 | $missing_color = 'red'; |
||
| 5443 | } |
||
| 5444 | if ($excess_color) { |
||
| 5445 | $excess_color = 'green'; |
||
| 5446 | } else { |
||
| 5447 | $excess_color = 'red'; |
||
| 5448 | } |
||
| 5449 | if (!is_numeric($final_overlap)) { |
||
| 5450 | $final_overlap = 0; |
||
| 5451 | } |
||
| 5452 | if (!is_numeric($final_missing)) { |
||
| 5453 | $final_missing = 0; |
||
| 5454 | } |
||
| 5455 | if (!is_numeric($final_excess)) { |
||
| 5456 | $final_excess = 0; |
||
| 5457 | } |
||
| 5458 | |||
| 5459 | if ($final_overlap > 100) { |
||
| 5460 | $final_overlap = 100; |
||
| 5461 | } |
||
| 5462 | |||
| 5463 | $table_resume = '<table class="data_table"> |
||
| 5464 | <tr class="row_odd" > |
||
| 5465 | <td></td> |
||
| 5466 | <td ><b>'.get_lang('Requirements').'</b></td> |
||
| 5467 | <td><b>'.get_lang('YourAnswer').'</b></td> |
||
| 5468 | </tr> |
||
| 5469 | <tr class="row_even"> |
||
| 5470 | <td><b>'.get_lang('Overlap').'</b></td> |
||
| 5471 | <td>'.get_lang('Min').' '.$threadhold1.'</td> |
||
| 5472 | <td><div style="color:'.$overlap_color.'">' |
||
| 5473 | .(($final_overlap < 0) ? 0 : intval($final_overlap)).'</div></td> |
||
| 5474 | </tr> |
||
| 5475 | <tr> |
||
| 5476 | <td><b>'.get_lang('Excess').'</b></td> |
||
| 5477 | <td>'.get_lang('Max').' '.$threadhold2.'</td> |
||
| 5478 | <td><div style="color:'.$excess_color.'">' |
||
| 5479 | .(($final_excess < 0) ? 0 : intval($final_excess)).'</div></td> |
||
| 5480 | </tr> |
||
| 5481 | <tr class="row_even"> |
||
| 5482 | <td><b>'.get_lang('Missing').'</b></td> |
||
| 5483 | <td>'.get_lang('Max').' '.$threadhold3.'</td> |
||
| 5484 | <td><div style="color:'.$missing_color.'">' |
||
| 5485 | .(($final_missing < 0) ? 0 : intval($final_missing)).'</div></td> |
||
| 5486 | </tr> |
||
| 5487 | </table>'; |
||
| 5488 | if ($next == 0) { |
||
| 5489 | $try = $try_hotspot; |
||
| 5490 | $lp = $lp_hotspot; |
||
| 5491 | $destinationid = $select_question_hotspot; |
||
| 5492 | $url = $url_hotspot; |
||
| 5493 | } else { |
||
| 5494 | //show if no error |
||
| 5495 | //echo 'no error'; |
||
| 5496 | $comment = $answerComment = $objAnswerTmp->selectComment($nbrAnswers); |
||
| 5497 | $answerDestination = $objAnswerTmp->selectDestination($nbrAnswers); |
||
| 5498 | } |
||
| 5499 | |||
| 5500 | echo '<h1><div style="color:#333;">'.get_lang('Feedback').'</div></h1> |
||
| 5501 | <p style="text-align:center">'; |
||
| 5502 | |||
| 5503 | $message = '<p>'.get_lang('YourDelineation').'</p>'; |
||
| 5504 | $message .= $table_resume; |
||
| 5505 | $message .= '<br />'.get_lang('ResultIs').' '.$result_comment.'<br />'; |
||
| 5506 | if ($organs_at_risk_hit > 0) { |
||
| 5507 | $message .= '<p><b>'.get_lang('OARHit').'</b></p>'; |
||
| 5508 | } |
||
| 5509 | $message .= '<p>'.$comment.'</p>'; |
||
| 5510 | echo $message; |
||
| 5511 | } else { |
||
| 5512 | echo $hotspot_delineation_result[0]; //prints message |
||
| 5513 | $from_database = 1; // the hotspot_solution.swf needs this variable |
||
| 5514 | } |
||
| 5515 | |||
| 5516 | //save the score attempts |
||
| 5517 | if (1) { |
||
| 5518 | //getting the answer 1 or 0 comes from exercise_submit_modal.php |
||
| 5519 | $final_answer = $hotspot_delineation_result[1]; |
||
| 5520 | if ($final_answer == 0) { |
||
| 5521 | $questionScore = 0; |
||
| 5522 | } |
||
| 5523 | // we always insert the answer_id 1 = delineation |
||
| 5524 | Event::saveQuestionAttempt($questionScore, 1, $quesId, $exeId, 0); |
||
| 5525 | //in delineation mode, get the answer from $hotspot_delineation_result[1] |
||
| 5526 | $hotspotValue = (int) $hotspot_delineation_result[1] === 1 ? 1 : 0; |
||
| 5527 | Event::saveExerciseAttemptHotspot( |
||
| 5528 | $exeId, |
||
| 5529 | $quesId, |
||
| 5530 | 1, |
||
| 5531 | $hotspotValue, |
||
| 5532 | $exerciseResultCoordinates[$quesId] |
||
| 5533 | ); |
||
| 5534 | } else { |
||
| 5535 | if ($final_answer == 0) { |
||
| 5536 | $questionScore = 0; |
||
| 5537 | $answer = 0; |
||
| 5538 | Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0); |
||
| 5539 | if (is_array($exerciseResultCoordinates[$quesId])) { |
||
| 5540 | foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) { |
||
| 5541 | Event::saveExerciseAttemptHotspot( |
||
| 5542 | $exeId, |
||
| 5543 | $quesId, |
||
| 5544 | $idx, |
||
| 5545 | 0, |
||
| 5546 | $val |
||
| 5547 | ); |
||
| 5548 | } |
||
| 5549 | } |
||
| 5550 | } else { |
||
| 5551 | Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0); |
||
| 5552 | if (is_array($exerciseResultCoordinates[$quesId])) { |
||
| 5553 | foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) { |
||
| 5554 | $hotspotValue = (int) $choice[$idx] === 1 ? 1 : 0; |
||
| 5555 | Event::saveExerciseAttemptHotspot( |
||
| 5556 | $exeId, |
||
| 5557 | $quesId, |
||
| 5558 | $idx, |
||
| 5559 | $hotspotValue, |
||
| 5560 | $val |
||
| 5561 | ); |
||
| 5562 | } |
||
| 5563 | } |
||
| 5564 | } |
||
| 5565 | } |
||
| 5566 | $my_exe_id = $exeId; |
||
| 5567 | } |
||
| 5568 | } |
||
| 5569 | |||
| 5570 | $relPath = api_get_path(WEB_CODE_PATH); |
||
| 5571 | |||
| 5572 | if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER) { |
||
| 5573 | // We made an extra table for the answers |
||
| 5574 | if ($show_result) { |
||
| 5575 | echo '</table></td></tr>'; |
||
| 5576 | echo " |
||
| 5577 | <tr> |
||
| 5578 | <td colspan=\"2\"> |
||
| 5579 | <p><em>".get_lang('HotSpot')."</em></p> |
||
| 5580 | <div id=\"hotspot-solution-$questionId\"></div> |
||
| 5581 | <script> |
||
| 5582 | $(document).on('ready', function () { |
||
| 5583 | new HotspotQuestion({ |
||
| 5584 | questionId: $questionId, |
||
| 5585 | exerciseId: {$this->id}, |
||
| 5586 | exeId: $exeId, |
||
| 5587 | selector: '#hotspot-solution-$questionId', |
||
| 5588 | for: 'solution', |
||
| 5589 | relPath: '$relPath' |
||
| 5590 | }); |
||
| 5591 | }); |
||
| 5592 | </script> |
||
| 5593 | </td> |
||
| 5594 | </tr> |
||
| 5595 | "; |
||
| 5596 | } |
||
| 5597 | } elseif ($answerType == ANNOTATION) { |
||
| 5598 | if ($show_result) { |
||
| 5599 | echo ' |
||
| 5600 | <p><em>'.get_lang('Annotation').'</em></p> |
||
| 5601 | <div id="annotation-canvas-'.$questionId.'"></div> |
||
| 5602 | <script> |
||
| 5603 | AnnotationQuestion({ |
||
| 5604 | questionId: parseInt('.$questionId.'), |
||
| 5605 | exerciseId: parseInt('.$exeId.'), |
||
| 5606 | relPath: \''.$relPath.'\', |
||
| 5607 | courseId: parseInt('.$course_id.') |
||
| 5608 | }); |
||
| 5609 | </script> |
||
| 5610 | '; |
||
| 5611 | } |
||
| 5612 | } |
||
| 5613 | |||
| 5614 | //if ($origin != 'learnpath') { |
||
| 5615 | if ($show_result && $answerType != ANNOTATION) { |
||
| 5616 | echo '</table>'; |
||
| 5617 | } |
||
| 5618 | // } |
||
| 5619 | } |
||
| 5620 | unset($objAnswerTmp); |
||
| 5621 | |||
| 5622 | $totalWeighting += $questionWeighting; |
||
| 5623 | // Store results directly in the database |
||
| 5624 | // For all in one page exercises, the results will be |
||
| 5625 | // stored by exercise_results.php (using the session) |
||
| 5626 | if ($saved_results) { |
||
| 5627 | if ($debug) { |
||
| 5628 | error_log("Save question results $saved_results"); |
||
| 5629 | error_log('choice: '); |
||
| 5630 | error_log(print_r($choice, 1)); |
||
| 5631 | } |
||
| 5632 | |||
| 5633 | if (empty($choice)) { |
||
| 5634 | $choice = 0; |
||
| 5635 | } |
||
| 5636 | // with certainty degree |
||
| 5637 | if (empty($choiceDegreeCertainty)) { |
||
| 5638 | $choiceDegreeCertainty = 0; |
||
| 5639 | } |
||
| 5640 | if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || |
||
| 5641 | $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE || |
||
| 5642 | $answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY |
||
| 5643 | ) { |
||
| 5644 | if ($choice != 0) { |
||
| 5645 | $reply = array_keys($choice); |
||
| 5646 | for ($i = 0; $i < sizeof($reply); $i++) { |
||
| 5647 | $chosenAnswer = $reply[$i]; |
||
| 5648 | if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { |
||
| 5649 | if ($choiceDegreeCertainty != 0) { |
||
| 5650 | $replyDegreeCertainty = array_keys($choiceDegreeCertainty); |
||
| 5651 | $answerDegreeCertainty = $replyDegreeCertainty[$i]; |
||
| 5652 | Event::saveQuestionAttempt( |
||
| 5653 | $questionScore, |
||
| 5654 | $chosenAnswer.':'.$choice[$chosenAnswer].':'. |
||
| 5655 | $choiceDegreeCertainty[$answerDegreeCertainty], |
||
| 5656 | $quesId, |
||
| 5657 | $exeId, |
||
| 5658 | $i, |
||
| 5659 | $this->id, |
||
| 5660 | $updateResults |
||
| 5661 | ); |
||
| 5662 | } |
||
| 5663 | } else { |
||
| 5664 | Event::saveQuestionAttempt( |
||
| 5665 | $questionScore, |
||
| 5666 | $chosenAnswer.':'.$choice[$chosenAnswer], |
||
| 5667 | $quesId, |
||
| 5668 | $exeId, |
||
| 5669 | $i, |
||
| 5670 | $this->id, |
||
| 5671 | $updateResults |
||
| 5672 | ); |
||
| 5673 | } |
||
| 5674 | if ($debug) { |
||
| 5675 | error_log('result =>'.$questionScore.' '.$chosenAnswer.':'.$choice[$chosenAnswer]); |
||
| 5676 | } |
||
| 5677 | } |
||
| 5678 | } else { |
||
| 5679 | Event::saveQuestionAttempt( |
||
| 5680 | $questionScore, |
||
| 5681 | 0, |
||
| 5682 | $quesId, |
||
| 5683 | $exeId, |
||
| 5684 | 0, |
||
| 5685 | $this->id |
||
| 5686 | ); |
||
| 5687 | } |
||
| 5688 | } elseif ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { |
||
| 5689 | if ($choice != 0) { |
||
| 5690 | $reply = array_keys($choice); |
||
| 5691 | |||
| 5692 | if ($debug) { |
||
| 5693 | error_log("reply ".print_r($reply, 1).""); |
||
| 5694 | } |
||
| 5695 | for ($i = 0; $i < sizeof($reply); $i++) { |
||
| 5696 | $ans = $reply[$i]; |
||
| 5697 | Event::saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id); |
||
| 5698 | } |
||
| 5699 | } else { |
||
| 5700 | Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id); |
||
| 5701 | } |
||
| 5702 | } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { |
||
| 5703 | if ($choice != 0) { |
||
| 5704 | $reply = array_keys($choice); |
||
| 5705 | for ($i = 0; $i < sizeof($reply); $i++) { |
||
| 5706 | $ans = $reply[$i]; |
||
| 5707 | Event::saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id); |
||
| 5708 | } |
||
| 5709 | } else { |
||
| 5710 | Event::saveQuestionAttempt( |
||
| 5711 | $questionScore, |
||
| 5712 | 0, |
||
| 5713 | $quesId, |
||
| 5714 | $exeId, |
||
| 5715 | 0, |
||
| 5716 | $this->id |
||
| 5717 | ); |
||
| 5718 | } |
||
| 5719 | } elseif (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) { |
||
| 5720 | if (isset($matching)) { |
||
| 5721 | foreach ($matching as $j => $val) { |
||
| 5722 | Event::saveQuestionAttempt( |
||
| 5723 | $questionScore, |
||
| 5724 | $val, |
||
| 5725 | $quesId, |
||
| 5726 | $exeId, |
||
| 5727 | $j, |
||
| 5728 | $this->id |
||
| 5729 | ); |
||
| 5730 | } |
||
| 5731 | } |
||
| 5732 | } elseif ($answerType == FREE_ANSWER) { |
||
| 5733 | $answer = $choice; |
||
| 5734 | Event::saveQuestionAttempt( |
||
| 5735 | $questionScore, |
||
| 5736 | $answer, |
||
| 5737 | $quesId, |
||
| 5738 | $exeId, |
||
| 5739 | 0, |
||
| 5740 | $this->id |
||
| 5741 | ); |
||
| 5742 | } elseif ($answerType == ORAL_EXPRESSION) { |
||
| 5743 | $answer = $choice; |
||
| 5744 | Event::saveQuestionAttempt( |
||
| 5745 | $questionScore, |
||
| 5746 | $answer, |
||
| 5747 | $quesId, |
||
| 5748 | $exeId, |
||
| 5749 | 0, |
||
| 5750 | $this->id, |
||
| 5751 | false, |
||
| 5752 | $objQuestionTmp->getAbsoluteFilePath() |
||
| 5753 | ); |
||
| 5754 | } elseif ( |
||
| 5755 | in_array( |
||
| 5756 | $answerType, |
||
| 5757 | [UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, READING_COMPREHENSION] |
||
| 5758 | ) |
||
| 5759 | ) { |
||
| 5760 | $answer = $choice; |
||
| 5761 | Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); |
||
| 5762 | } elseif ($answerType == HOT_SPOT || $answerType == ANNOTATION) { |
||
| 5763 | $answer = []; |
||
| 5764 | if (isset($exerciseResultCoordinates[$questionId]) && !empty($exerciseResultCoordinates[$questionId])) { |
||
| 5765 | if ($debug) { |
||
| 5766 | error_log('Checking result coordinates'); |
||
| 5767 | } |
||
| 5768 | Database::delete( |
||
| 5769 | Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT), |
||
| 5770 | [ |
||
| 5771 | 'hotspot_exe_id = ? AND hotspot_question_id = ? AND c_id = ?' => [ |
||
| 5772 | $exeId, |
||
| 5773 | $questionId, |
||
| 5774 | api_get_course_int_id(), |
||
| 5775 | ], |
||
| 5776 | ] |
||
| 5777 | ); |
||
| 5778 | |||
| 5779 | foreach ($exerciseResultCoordinates[$questionId] as $idx => $val) { |
||
| 5780 | $answer[] = $val; |
||
| 5781 | $hotspotValue = (int) $choice[$idx] === 1 ? 1 : 0; |
||
| 5782 | if ($debug) { |
||
| 5783 | error_log('Hotspot value: '.$hotspotValue); |
||
| 5784 | } |
||
| 5785 | Event::saveExerciseAttemptHotspot( |
||
| 5786 | $exeId, |
||
| 5787 | $quesId, |
||
| 5788 | $idx, |
||
| 5789 | $hotspotValue, |
||
| 5790 | $val, |
||
| 5791 | false, |
||
| 5792 | $this->id |
||
| 5793 | ); |
||
| 5794 | } |
||
| 5795 | } else { |
||
| 5796 | if ($debug) { |
||
| 5797 | error_log('Empty: exerciseResultCoordinates'); |
||
| 5798 | } |
||
| 5799 | } |
||
| 5800 | Event::saveQuestionAttempt($questionScore, implode('|', $answer), $quesId, $exeId, 0, $this->id); |
||
| 5801 | } else { |
||
| 5802 | Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); |
||
| 5803 | } |
||
| 5804 | } |
||
| 5805 | |||
| 5806 | if ($propagate_neg == 0 && $questionScore < 0) { |
||
| 5807 | $questionScore = 0; |
||
| 5808 | } |
||
| 5809 | |||
| 5810 | if ($saved_results) { |
||
| 5811 | $statsTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
| 5812 | $sql = "UPDATE $statsTable SET |
||
| 5813 | score = score + ".floatval($questionScore)." |
||
| 5814 | WHERE exe_id = $exeId"; |
||
| 5815 | Database::query($sql); |
||
| 5816 | if ($debug) { |
||
| 5817 | error_log($sql); |
||
| 5818 | } |
||
| 5819 | } |
||
| 5820 | |||
| 5821 | $return_array = [ |
||
| 5822 | 'score' => $questionScore, |
||
| 5823 | 'weight' => $questionWeighting, |
||
| 5824 | 'extra' => $extra_data, |
||
| 5825 | 'open_question' => $arrques, |
||
| 5826 | 'open_answer' => $arrans, |
||
| 5827 | 'answer_type' => $answerType, |
||
| 5828 | 'generated_oral_file' => $generatedFile, |
||
| 5829 | ]; |
||
| 5830 | |||
| 5831 | return $return_array; |
||
| 5832 | } |
||
| 8406 |
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: