Example #1
0
function logIntoCourse($id_course, $gotofirst_page = true)
{
    // Reset previous opened track session if any
    if (!Docebo::user()->isAnonymous() && isset($_SESSION['idCourse'])) {
        require_once _lms_ . '/lib/lib.track_user.php';
        TrackUser::setActionTrack(getLogUserId(), $_SESSION['idCourse'], '', '');
    }
    // Unset possibile previous session setting
    if (isset($_SESSION['direct_play'])) {
        unset($_SESSION['direct_play']);
    }
    $re_course = sql_query("\r\n\tSELECT level, status, waiting\r\n\tFROM %lms_courseuser\r\n\tWHERE idCourse = " . (int) $id_course . " AND idUser = "******"");
    list($level_c, $status_user, $waiting_user) = sql_fetch_row($re_course);
    Docebo::setCourse($id_course);
    $course_info = Docebo::course()->getAllInfo();
    $course_info['course_status'] = $course_info['status'];
    $course_info['user_status'] = $status_user;
    $course_info['waiting'] = $waiting_user;
    $course_info['level'] = $level_c;
    // Can the user enter into the course ?
    if (!Man_Course::canEnterCourse($course_info)) {
        return false;
    }
    // Disable tracking for ghost level
    $_SESSION['is_ghost'] = $course_info['level'] == 2 ? true : false;
    // If it's the first time we need to change the course status
    if ($course_info['user_status'] == _CUS_SUBSCRIBED) {
        require_once _lms_ . '/lib/lib.stats.php';
        saveTrackStatusChange(getLogUserId(), $id_course, _CUS_BEGIN);
    }
    // Setup some session data
    $_SESSION['timeEnter'] = date("Y-m-d H:i:s");
    $_SESSION['idCourse'] = $id_course;
    $_SESSION['levelCourse'] = $course_info['level'];
    //we need to redo this
    //$_SESSION['idEdition'] 		= $id_e;
    Docebo::user()->loadUserSectionST('/lms/course/private/' . $course_info['level'] . '/');
    Docebo::user()->SaveInSession();
    // Initialize the session into the course
    TrackUser::createSessionCourseTrack();
    $first_page = firstPage();
    $_SESSION['current_main_menu'] = $first_page['idMain'];
    $_SESSION['sel_module_id'] = $first_page['idModule'];
    $jumpurl = 'index.php?modname=' . $first_page['modulename'] . '&op=' . $first_page['op'] . '&id_module_sel=' . $first_page['idModule'];
    // course in direct play or assessment
    if ($course_info['direct_play'] == 1 || $course_info['course_type'] == 'assessment') {
        if ($_SESSION['levelCourse'] >= 4) {
            // direct play with a teacher, basically it's not ok
            // check if we are managing the LOs from admin: if yes, jump into the test management
            if ($course_info['course_type'] == 'assessment' && Get::req('from_admin', DOTY_INT, 0) > 0) {
                // enter the assessment course and go to test editing if there is a test with no question in it
                $query = "SELECT idOrg, idResource " . " FROM %lms_organization " . " WHERE idCourse = " . (int) $_SESSION['idCourse'] . " AND objectType = 'test' " . " ORDER BY path ASC, title ASC " . " LIMIT 0,1";
                $res = sql_query($query);
                if ($res && sql_num_rows($res) > 0) {
                    list($id_org, $id_test) = sql_fetch_row($res);
                    if ($id_test > 0) {
                        require_once _lms_ . '/lib/lib.test.php';
                        $tman = new TestManagement($id_test);
                        if ($tman->getNumberOfQuestion() <= 0) {
                            Util::jump_to('index.php?modname=test&op=modtestgui&idTest=' . $id_test . '&back_url=' . urlencode($jumpurl));
                        }
                    }
                }
            }
        } else {
            // direct play with a student
            // i need to play directly the course if it's not completed and is the only object of the course
            require_once _lms_ . '/lib/lib.orgchart.php';
            $orgman = new OrganizationManagement($_SESSION['idCourse']);
            $first_lo =& $orgman->getInfoWhereType(false, $_SESSION['idCourse']);
            if (count($first_lo) == 1) {
                $_SESSION['direct_play'] = 1;
                $obj = array_shift($first_lo);
                Util::jump_to('index.php?modname=organization&op=custom_playitem&id_item=' . $obj['id_org'] . '');
            } elseif (count($first_lo) >= 2) {
                $obj = array_shift($first_lo);
                // if we have more than an object we need to play the first one until it's completed
                $query = "SELECT status FROM %lms_commontrack WHERE idReference = " . (int) $obj['id_org'] . " AND idUser = "******"assessment") {
    		//check if we are managing the LOs from admin: if yes, jump into the test management
    		if (Get::req('from_admin', DOTY_INT, 0) > 0) {
    			//enter the assessment course and go to test editing
    			$query = "SELECT idOrg, idResource FROM %lms_organization WHERE idCourse=".(int)$_SESSION['idCourse']." AND objectType='test' "
    				." ORDER BY path ASC, title ASC LIMIT 0,1";
    			$res = sql_query($query);
    			if ($res && sql_num_rows($res)>0) {
    
    				list($id_org, $id_test) = sql_fetch_row($res);
    
    				if ($id_test > 0) {
    					require_once(_lms_.'/lib/lib.test.php');
    					$tman = new TestManagement($id_test);
    
    					if ($tman->getNumberOfQuestion() <= 0) {
    						Util::jump_to('index.php?modname=test&op=modtestgui&idTest='.$id_test.'&back_url='.urlencode($jumpurl));
    					}
    				}
    			}
    		}
    	}
    	if($gotofirst_page) Util::jump_to($jumpurl);
    	else return true;
    }
    
    
    switch($course_info['course_type']) {
    	case "assessment" : {
    
    		if($_SESSION['levelCourse'] <= 3) {
    
    			// i need to play directly the test
    			require_once($GLOBALS['where_lms'].'/lib/lib.orgchart.php');
    			$orgman = new OrganizationManagement($_SESSION['idCourse']);
    			$test =& $orgman->getInfoWhereType('test', $_SESSION['idCourse']);
    
    			if(count($test) == 1) {
    				$obj = array_shift($test);
    				$_SESSION['test_assessment'] = 1;
    				Util::jump_to('index.php?modname=organization&op=custom_playitem&id_item='.$obj['id_org'].'');
    			}
    			if($gotofirst_page) Util::jump_to($jumpurl);
    			else return true;
    		} else {
    			if($gotofirst_page) {
    				//...
    				Util::jump_to($jumpurl);
    			}
    			else return true;
    		}
    	};break;
    	default: {
    		if($gotofirst_page) Util::jump_to($jumpurl);
    		else return true;
    	}
    }
    /* not used in
    // now analyze the course type and select the acton to perform
    if(isset($_GET['showresult'])) {
    
    	require_once(_lms_.'/lib/lib.orgchart.php');
    	$orgman = new OrganizationManagement($_SESSION['idCourse']);
    	$scorm =& $orgman->getInfoWhereType('scormorg', $_SESSION['idCourse']);
    
    	if(count($scorm) == '1') {
    		$obj = array_shift($scorm);
    		Util::jump_to('index.php?modname=organization&op=scorm_track&id_user='******'&id_org='.$obj['id_resource'].'&amp;back='.$GLOBALS['course_descriptor']->getValue('direct_play'));
    	}
    	Util::jump_to('index.php?modname=course&op=showresults&id_course='.$_SESSION['idCourse']);
    }
    */
}
Example #2
0
function showResult($object_test, $id_param)
{
    if (!checkPerm('view', true, 'organization') && !checkPerm('view', true, 'storage')) {
        die("You can't access");
    }
    require_once _base_ . '/lib/lib.form.php';
    require_once $GLOBALS['where_lms'] . '/class.module/track.test.php';
    require_once $GLOBALS['where_lms'] . '/lib/lib.param.php';
    require_once $GLOBALS['where_lms'] . '/lib/lib.test.php';
    $lang =& DoceboLanguage::createInstance('test');
    $id_test = $object_test->getId();
    $id_reference = getLoParam($id_param, 'idReference');
    $url_coded = urlencode(serialize($object_test->back_url));
    $id_track = retriveTrack($id_reference, $id_test, Docebo::user()->getIdst());
    if ($id_track === false) {
        $GLOBALS['page']->add(getErrorUi($lang->def('_TEST_TRACK_FAILURE') . getBackUi(Util::str_replace_once('&', '&amp;', $object_test->back_url), $lang->def('_BACK'))), 'content');
    }
    $test_man = new TestManagement($id_test);
    $play_man = new PlayTestManagement($id_test, Docebo::user()->getIdst(), $id_track, $test_man);
    $test_info = $test_man->getTestAllInfo();
    $track_info = $play_man->getTrackAllInfo();
    $previous_page = importVar('previous_page', false, false);
    $new_info = array('last_page_seen' => $previous_page, 'score_status' => 'doing');
    if (isset($_POST['page_to_save']) && ($_POST['page_to_save'] > $track_info['last_page_saved'] || $test_info['mod_doanswer'])) {
        $play_man->storePage($_POST['page_to_save'], $test_info['mod_doanswer']);
        $play_man->closeTrackPageSession($_POST['page_to_save']);
    }
    $now = date('Y-m-d H:i:s');
    $point_do = 0;
    $max_score = 0;
    $num_manual = 0;
    $manual_score = 0;
    $point_do_cat = array();
    $re_visu_quest = sql_query("SELECT idQuest \r\n\tFROM " . $GLOBALS['prefix_lms'] . "_testtrack_quest \r\n\tWHERE idTrack = '" . $id_track . "' ");
    while (list($id_q) = sql_fetch_row($re_visu_quest)) {
        $quest_see[] = $id_q;
    }
    $reQuest = sql_query("\r\n\tSELECT q.idQuest, q.type_quest, t.type_file, t.type_class, q.idCategory \r\n\tFROM %lms_testquest AS q JOIN " . $GLOBALS['prefix_lms'] . "_quest_type AS t\r\n\tWHERE q.idTest = '" . $id_test . "' AND q.type_quest = t.type_quest AND q.idQuest IN (" . implode($quest_see, ',') . ") \r\n\tORDER BY q.sequence");
    //#2093: Conto le domande
    $tot_questions = 0;
    $tot_answers = 0;
    $tot_rightanswers = 0;
    $tot_questions = $test_man->getNumberOfQuestion();
    while (list($id_quest, $type_quest, $type_file, $type_class, $id_cat) = sql_fetch_row($reQuest)) {
        require_once $GLOBALS['where_lms'] . '/modules/question/' . $type_file;
        $quest_point_do = 0;
        $quest_obj = new $type_class($id_quest);
        $quest_point_do = $quest_obj->userScore($id_track);
        $quest_max_score = $quest_obj->getMaxScore();
        if ($quest_obj->getScoreSetType() == 'manual') {
            ++$num_manual;
            $manual_score = round($manual_score + $quest_max_score, 2);
        }
        //#2093: Conto le risposte, conto le risposte corrette
        $tot_answers++;
        if ($quest_point_do == $quest_max_score) {
            $tot_rightanswers++;
        }
        $point_do = round($point_do + $quest_point_do, 2);
        $max_score = round($max_score + $quest_max_score, 2);
        if (isset($point_do_cat[$id_cat])) {
            $point_do_cat[$id_cat] = round($quest_point_do + $point_do_cat[$id_cat], 2);
        } else {
            $point_do_cat[$id_cat] = round($quest_point_do, 2);
        }
    }
    if ($test_info['point_type'] == '1') {
        // percentage score (%)
        // x:100=$point_do:$max_score
        //#2093: calcolo effettivo solo se ho tutte le risposte
        if ($tot_questions == $tot_answers) {
            $point_do = round(100 * $point_do / $max_score);
            //$max_score$test_info['point_required']
        } else {
            $point_do = round(100 * $tot_rightanswers / $tot_questions);
            //$max_score$test_info['point_required']
        }
    }
    $save_score = $point_do;
    // save new status in track
    if ($point_do >= $test_info['point_required']) {
        $next_status = 'passed';
        if ($test_info['show_only_status']) {
            $score_status = 'passed';
        }
    } else {
        $next_status = 'failed';
        if ($test_info['show_only_status']) {
            $score_status = 'not_passed';
        }
    }
    if (!$test_info['show_only_status']) {
        if ($num_manual != 0) {
            $score_status = 'not_checked';
        } else {
            $score_status = 'valid';
        }
    }
    $test_track = new Track_Test($id_track);
    $test_track->setDate($now);
    $test_track->status = $next_status;
    $test_track->update();
    // --
    require_once _lms_ . '/lib/lib.assessment_rule.php';
    $score_arr = array();
    $i = 0;
    foreach ($point_do_cat as $cat_id => $score) {
        $score_arr[$i]['score'] = $score;
        $score_arr[$i]['category_id'] = $cat_id;
        $i++;
    }
    // final score:
    $score_arr[$i]['score'] = $point_do;
    $score_arr[$i]['category_id'] = 0;
    $asrule = new AssessmentRuleManager($id_test);
    $feedback_txt = $asrule->setRulesFromScore($score_arr);
    $asrule->loadJs();
    // --
    $GLOBALS['page']->add(getTitleArea($lang->def('_TITLE') . ' : ' . $test_info['title'], 'test', $lang->def('_TEST_INFO')) . '<div class="std_block">' . ($next_status == 'failed' ? '<b>' . $lang->def('_TEST_FAILED') . '</b>' : $lang->def('_TEST_COMPLETED')) . '<br />', 'content');
    if ($test_info['point_type'] != '1') {
        $save_score = $point_do;
    } else {
        $save_score = $point_do;
        //round(round($point_do / $max_score, 2) * 100, 2);
    }
    $track_info = Track_Test::getTrackInfo(Docebo::user()->getIdst(), $id_test, $id_reference);
    if ($score_status == 'valid' || $score_status == 'not_checked' || $score_status == 'passed' || $score_status == 'not_passed') {
        $new_info['date_end_attempt'] = $now;
        $new_info['number_of_save'] = $track_info['number_of_save'] + 1;
        $new_info['score'] = $save_score;
        $new_info['score_status'] = $score_status;
        $new_info['number_of_attempt'] = $track_info['number_of_attempt'] + 1;
        $re_update = Track_Test::updateTrack($id_track, $new_info);
        if (!isset($_POST['show_review'])) {
            $time = fromDatetimeToTimestamp(date('Y-m-d H:i:s')) - fromDatetimeToTimestamp($_SESSION['test_date_begin']);
            sql_query("\r\n            INSERT INTO " . $GLOBALS['prefix_lms'] . "_testtrack_times\r\n            (idTrack, idReference, idTest, date_attempt, number_time, score, score_status, date_begin, date_end, time) VALUES\r\n            ('" . $id_track . "', '" . $id_reference . "', '" . $id_test . "', now(), '" . $new_info['number_of_save'] . "', '" . $new_info['score'] . "', '" . $new_info['score_status'] . "', '" . $_SESSION['test_date_begin'] . "', '" . date('Y-m-d H:i:s') . "', '" . $time . "')");
            unset($_SESSION['test_date_begin']);
        }
    }
    //--- check suspension conditions ----------------------------------------------
    if ($test_info['use_suspension']) {
        $suspend_info = array();
        if ($next_status == 'failed') {
            $suspend_info['attempts_for_suspension'] = $track_info['attempts_for_suspension'] + 1;
            if ($suspend_info['attempts_for_suspension'] >= $test_info['suspension_num_attempts'] && $test_info['suspension_num_hours'] > 0) {
                //should we reset learning_test.suspension_num_attempts ??
                $suspend_info['attempts_for_suspension'] = 0;
                //from now on, it uses the suspended_until parameter, so only the date is needed, we can reset the attempts count
                $suspend_info['suspended_until'] = date("Y-m-d H:i:s", time() + $test_info['suspension_num_hours'] * 3600);
            }
            //if num_hours is <= 0, never update attempts counter, so user won't never be de-suspended
            $re = Track_Test::updateTrack($id_track, $suspend_info);
        } else {
            if ($next_status == 'completed' || $next_status == 'passed') {
                $suspend_info['attempts_for_suspension'] = 0;
                $re = Track_Test::updateTrack($id_track, $suspend_info);
            }
        }
    }
    //--- end suspensions check ----------------------------------------------------
    list($bonus_score, $score_status) = sql_fetch_row(sql_query("\r\n\tSELECT bonus_score, score_status\r\n\tFROM " . $GLOBALS['prefix_lms'] . "_testtrack \r\n\tWHERE idTrack = '" . (int) $id_track . "'"));
    if ($test_info['show_score'] && $test_info['point_type'] != '1') {
        //$GLOBALS['page']->add('<span class="test_score_note">'.$lang->def('_TEST_TOTAL_SCORE').'</span> '.($point_do + $bonus_score).' / '.$max_score.'<br />', 'content');
        $GLOBALS['page']->add('<span class="test_score_note">' . $lang->def('_TEST_TOTAL_SCORE') . '</span> ' . ($point_do + $bonus_score) . ' / 100<br />', 'content');
        if ($num_manual != 0 && $score_status != 'valid') {
            $GLOBALS['page']->add('<br />' . '<span class="test_score_note">' . $lang->def('_TEST_MANUAL_SCORE') . '</span> ' . $manual_score . ' ' . $lang->def('_TEST_SCORES') . '<br />', 'content');
        }
        if ($test_info['point_required'] != 0) {
            $GLOBALS['page']->add('<br />' . '<span class="test_score_note">' . $lang->def('_TEST_REQUIREDSCORE_RESULT') . '</span> ' . $test_info['point_required'] . '<br />', 'content');
        }
    }
    if ($test_info['show_score'] && $test_info['point_type'] == '1') {
        $GLOBALS['page']->add('<span class="test_score_note">' . $lang->def('_TEST_TOTAL_SCORE') . '</span> ' . $save_score . ' %' . '<br />', 'content');
        if ($num_manual != 0) {
            $GLOBALS['page']->add('<br />' . '<span class="test_score_note">' . $lang->def('_TEST_MANUAL_SCORE') . '</span> ' . $manual_score . ' ' . $lang->def('_TEST_SCORES') . '<br />', 'content');
        }
    }
    if ($test_info['show_score_cat']) {
        $re_category = sql_query("\r\n\t\tSELECT c.idCategory, c.name, COUNT(q.idQuest)\r\n\t\tFROM " . $GLOBALS['prefix_lms'] . "_testquest AS q \r\n\t\t\tJOIN " . $GLOBALS['prefix_lms'] . "_quest_category AS c\r\n\t\tWHERE c.idCategory = q.idCategory AND q.idTest = '" . $id_test . "' AND q.idCategory != 0 \r\n\t\tGROUP BY c.idCategory \r\n\t\tORDER BY c.name");
        if (sql_num_rows($re_category)) {
            $GLOBALS['page']->add('<br />' . '<table summary="' . $lang->def('_TEST_CATEGORY_SCORE') . '" class="category_score">' . '<caption>' . $lang->def('_TEST_CATEGORY_SCORE') . '</caption>' . '<thead>' . '<tr>' . '<th>' . $lang->def('_TEST_QUEST_CATEGORY') . '</th>' . '<th class="number">' . $lang->def('_TEST_QUEST_NUMBER') . '</th' . '<th class="number">' . $lang->def('_TEST_TOTAL_SCORE') . '</th>' . '</tr>' . '</thead>' . '<tbody>', 'content');
            while (list($id_cat, $name_cat, $quest_number) = sql_fetch_row($re_category)) {
                $GLOBALS['page']->add('<tr><td>' . $name_cat . '</td>' . '<td class="number">' . $quest_number . '</td>' . '<td class="number">' . (isset($point_do_cat[$id_cat]) ? $point_do_cat[$id_cat] : 0) . '</td></tr>', 'content');
            }
            /*
            $GLOBALS['page']->add('<br />'
            	.'<span class="test_score_note">'.$lang->def('_TEST_CATEGORY_SCORE').'</span><br />', 'content');
            while(list($id_cat, $name_cat, $quest_number) = sql_fetch_row($re_category)) {
            	
            	$GLOBALS['page']->add($name_cat.', '.$lang->def('_TEST_SCORES').': '
            		.( isset($point_do_cat[$id_cat]) ? $point_do_cat[$id_cat] : 0 ).'<br />', 'content');
            }
            */
            $GLOBALS['page']->add('</tbody></table>', 'content');
        }
    }
    $GLOBALS['page']->add('<br /><br />', 'content');
    //--- if chart visualization enabled, then show it ---------------------------
    require_once _base_ . '/lib/lib.json.php';
    $json = new Services_JSON();
    if ($test_info['chart_options'] !== "") {
        $chart_options = $json->decode($test_info['chart_options']);
    } else {
        $chart_options = new stdClass();
    }
    if (!property_exists($chart_options, 'use_charts')) {
        $chart_options->use_charts = false;
    }
    if (!property_exists($chart_options, 'selected_chart')) {
        $chart_options->selected_chart = 'column';
    }
    if (!property_exists($chart_options, 'show_chart')) {
        $chart_options->show_chart = 'teacher';
    }
    if ($chart_options->use_charts && $chart_options->show_chart == 'course') {
        cout('<div class="align-center">', 'content');
        $chart = new Test_Charts($test_info['idTest'], Docebo::user()->getIdSt());
        $chart->render($chart_options->selected_chart, true);
        cout('</div><br /><br />', 'content');
    }
    //--- end show chart ---------------------------------------------------------
    if ($feedback_txt) {
        cout('<p>' . $feedback_txt . '</p><br />', 'content');
    }
    $points = $point_do + $bonus_score;
    if ($test_info['show_solution'] == 2 && $points >= $test_info['point_required']) {
        $GLOBALS['page']->add(Form::openForm('test_show', 'index.php?modname=test&amp;op=play') . Form::getHidden('next_step', 'next_step', 'test_review') . Form::getHidden('id_test', 'id_test', $id_test) . Form::getHidden('id_param', 'id_param', $id_param) . Form::getHidden('back_url', 'back_url', $url_coded) . Form::getHidden('idTrack', 'idTrack', $id_track) . Form::getButton('review', 'review', $lang->def('_TEST_REVIEW_ANSWER')) . Form::closeForm(), 'content');
    } elseif ($test_info['show_doanswer'] == 2 && $points >= $test_info['point_required']) {
        $GLOBALS['page']->add(Form::openForm('test_show', 'index.php?modname=test&amp;op=play') . Form::getHidden('next_step', 'next_step', 'test_review') . Form::getHidden('id_test', 'id_test', $id_test) . Form::getHidden('id_param', 'id_param', $id_param) . Form::getHidden('back_url', 'back_url', $url_coded) . Form::getHidden('idTrack', 'idTrack', $id_track) . Form::getButton('review', 'review', $lang->def('_TEST_REVIEW_ANSWER')) . Form::closeForm(), 'content');
    } elseif ($test_info['show_solution'] != 2 && $test_info['show_doanswer'] != 2) {
        if ($test_info['show_solution'] || $test_info['show_doanswer']) {
            $GLOBALS['page']->add(Form::openForm('test_show', 'index.php?modname=test&amp;op=play') . Form::getHidden('next_step', 'next_step', 'test_review') . Form::getHidden('id_test', 'id_test', $id_test) . Form::getHidden('id_param', 'id_param', $id_param) . Form::getHidden('back_url', 'back_url', $url_coded) . Form::getHidden('idTrack', 'idTrack', $id_track) . Form::getButton('review', 'review', $lang->def('_TEST_REVIEW_ANSWER')) . Form::closeForm(), 'content');
        }
    }
    $GLOBALS['page']->add(Form::openForm('test_show', Util::str_replace_once('&', '&amp;', $object_test->back_url)) . '<div class="align_right">' . Form::getButton('end_test', 'end_test', $lang->def('_TEST_END_BACKTOLESSON')) . '</div>' . Form::closeForm(), 'content');
    $GLOBALS['page']->add('</div>', 'content');
}
Example #3
0
 /**
  * save some score info related with id_test and is_user
  * @param int 		$id_test 		the id of the test, 
  * @param array		$users_scores	the score of the users associated with the proper idst_userid
  * @param array 	$date_attempts	the date of the attempt time
  * @param array		$comments		comments to the test
  */
 function saveTestUsersScores($id_test, $users_scores, $date_attempts, $comments)
 {
     require_once $GLOBALS['where_lms'] . '/class.module/track.test.php';
     $query_test = "\r\n\t\tSELECT point_required, show_only_status \r\n\t\tFROM " . $GLOBALS['prefix_lms'] . "_test \r\n\t\tWHERE idTest = '" . $id_test . "'";
     $re_test = sql_query($query_test);
     list($point_required, $show_only_status) = sql_fetch_row($re_test);
     $old_scores =& $this->getTestsScores(array($id_test), false, true);
     $re = true;
     while (list($idst_user, $score) = each($users_scores)) {
         $query_scores = "\r\n\t\t\tUPDATE " . $GLOBALS['prefix_lms'] . "_testtrack\r\n\t\t\tSET date_attempt_mod = '" . Format::dateDb($date_attempts[$idst_user]) . "', \r\n\t\t\t\tbonus_score = '" . ($score - $old_scores[$id_test][$idst_user]['score']) . "', \r\n\t\t\t\tscore_status = 'valid',\r\n\t\t\t\tcomment = '" . $comments[$idst_user] . "'\r\n\t\t\tWHERE idTest = '" . $id_test . "' AND idUser = '******'";
         $re &= sql_query($query_scores);
         if ($score >= $point_required) {
             // update status in lesson
             $id_track = Track_Test::getTrack($id_test, $idst_user);
             if ($id_track) {
                 $test_track = new Track_Test($id_track);
                 $test_track->setDate(date('Y-m-d H:i:s'));
                 $test_track->status = 'passed';
                 $test_track->update();
             }
         } else {
             $id_track = Track_Test::getTrack($id_test, $idst_user);
             if ($id_track) {
                 $test_track = new Track_Test($id_track);
                 $test_track->setDate(date('Y-m-d H:i:s'));
                 $test_track->status = 'failed';
                 $test_track->update();
             }
         }
         $test_man = new TestManagement($id_test);
         $play_man = new PlayTestManagement($id_test, $idst_user, $id_track, $test_man);
         $test_info = $test_man->getTestAllInfo();
         $track_info = $play_man->getTrackAllInfo();
         $test_status = $score >= $point_required ? 'passed' : 'failed';
         if ($test_info['use_suspension']) {
             $suspend_info = array();
             if ($test_status == 'failed') {
                 $suspend_info['attempts_for_suspension'] = $track_info['attempts_for_suspension'] + 1;
                 if ($suspend_info['attempts_for_suspension'] >= $test_info['suspension_num_attempts']) {
                     //should we reset learning_test.suspension_num_attempts ??
                     $suspend_info['attempts_for_suspension'] = 0;
                     //from now on, it uses the suspended_until parameter, so only the date is needed, we can reset the attempts count
                     $suspend_info['suspended_until'] = date("Y-m-d H:i:s", time() + $test_info['suspension_num_hours'] * 3600);
                 }
                 $re = Track_Test::updateTrack($id_track, $suspend_info);
             } else {
                 if ($test_status == 'completed' || $test_status == 'passed') {
                     $suspend_info['attempts_for_suspension'] = 0;
                     $re = Track_Test::updateTrack($id_track, $suspend_info);
                 }
             }
         }
     }
     return $re;
 }