Exemple #1
0
 public static function CheckFields(&$arFields, $ID = false)
 {
     global $DB, $APPLICATION;
     if ($ID === false) {
         if (is_set($arFields, "ATTEMPT_ID")) {
             $r = CTestAttempt::GetByID($arFields["ATTEMPT_ID"]);
             if (!$r->Fetch()) {
                 $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_ATTEMPT_ID_EX"), "ERROR_NO_ATTEMPT_ID");
                 return false;
             }
         } else {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_ATTEMPT_ID"), "EMPTY_ATTEMPT_ID");
             return false;
         }
         if (is_set($arFields, "QUESTION_ID")) {
             $r = CLQuestion::GetByID($arFields["QUESTION_ID"]);
             if (!$r->Fetch()) {
                 $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_QUESTION_ID"), "EMPTY_QUESTION_ID");
                 return false;
             }
         } else {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_QUESTION_ID"), "EMPTY_QUESTION_ID");
             return false;
         }
     }
     if (is_set($arFields, "RESPONSE") && is_array($arFields["RESPONSE"])) {
         $s = "";
         foreach ($arFields["RESPONSE"] as $val) {
             $s .= $val . ",";
         }
         $arFields["RESPONSE"] = substr($s, 0, -1);
     }
     /*
     if (is_set($arFields, "ANSWERED") && is_set($arFields, "RESPONSE"))
     {
     	if ($arFields["ANSWERED"]=="Y" && strlen($arFields["RESPONSE"]) <= 0)
     	{
     		$APPLICATION->ThrowException(GetMessage("LEARNING_BAD_NO_ANSWERS"), "EMPTY_ANSWERS");
     		return false;
     	}
     }
     */
     if (is_set($arFields, "CORRECT") && $arFields["CORRECT"] != "Y") {
         $arFields["CORRECT"] = "N";
     }
     return true;
 }
Exemple #2
0
     }
     $sessAttemptID = null;
     $sessAttemptFinished = true;
     $sessAttemptError = GetMessage("LEARNING_TIME_LIMIT");
     LocalRedirect($arResult["REDIRECT_PAGE"]);
 } elseif ($arTest["TIME_LIMIT"] > 0) {
     $arResult["SECONDS_TO_END"] = $arTest["TIME_LIMIT"] * 60 - (time() - MakeTimeStamp($arAttempt["DATE_START"]));
     $arResult["SECONDS_TO_END_STRING"] = _TimeToStringFormat($arResult["SECONDS_TO_END"]);
 }
 //If there are no questions, finish the attempt
 if ($arTest["PASSAGE_TYPE"] < 2) {
     $arProgress = CTestResult::GetProgress($sessAttemptID);
     if ($arProgress["TODO"] == 0) {
         $rsTestAttempt = new CTestAttempt();
         $rsTestAttempt->AttemptFinished($sessAttemptID);
         $rsAtt = CTestAttempt::GetByID((int) $sessAttemptID);
         if (($arAtt = $rsAtt->GetNext()) && $arTest["APPROVED"] == "Y") {
             $arAtt["CORRECT_COUNT"] = CTestResult::GetCorrectCount($arAtt["ID"]);
             $sessAttempt = $arAtt;
         }
         $sessAttemptID = null;
         $sessAttemptFinished = true;
         LocalRedirect($arResult["REDIRECT_PAGE"]);
     }
 }
 //Get questions
 $rsTestResult = CTestResult::GetList(array("ID" => "ASC"), array("ATTEMPT_ID" => $sessAttemptID, 'CHECK_PERMISSIONS' => 'N'));
 $rsTestResult->NavStart(10000);
 $arResult["NAV"]["PAGE_COUNT"] = $rsTestResult->SelectedRowsCount();
 //If no questions
 if ($arResult["NAV"]["PAGE_COUNT"] <= 0) {
 protected static function _CreateAttemptQuestions($arCallbackSqlFormer, $ATTEMPT_ID)
 {
     global $APPLICATION, $DB, $DBType;
     $ATTEMPT_ID = intval($ATTEMPT_ID);
     $attempt = CTestAttempt::GetByID($ATTEMPT_ID);
     if (!($arAttempt = $attempt->Fetch())) {
         $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_ATTEMPT_ID_EX"), "ERROR_NO_ATTEMPT_ID");
         return false;
     }
     $test = CTest::GetByID($arAttempt["TEST_ID"]);
     if (!($arTest = $test->Fetch())) {
         $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_ID_EX"), "ERROR_NO_TEST_ID");
         return false;
     }
     $strSql = "DELETE FROM b_learn_test_result WHERE ATTEMPT_ID = " . $ATTEMPT_ID;
     if (!$DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__)) {
         return false;
     }
     /**
      * QUESTIONS_FROM values:
      * 'L' - X questions from every lesson in course
      * 'C' - X questions from every lesson from every chapter in the course
      *       In this case questions taken from immediate lessons of all chapters (X per chapter) in the course.
      *       In new data model it means, get X questions from every lesson in the course, except
      *       1) immediate lessons-childs of the course and
      *       2) lessons, contains other lessons (because, in old data model chapters doesn't contains questions)
      * 
      * 'H' - all questions from the selected chapter (recursive) in the course 
      *       This case must be ignored, because converter to new data model updates 'H' to 'R', but in case
      *       when chapter is not exists updates didn't become. So QUESTIONS_FROM stayed in 'H' value. And it means,
      *       that there is no chapter exists with QUESTIONS_FROM_ID, so we can't do work. And we should just
      *       ignore, for backward compatibility (so, don't throw an error).
      * 'S' - all questions from the selected lesson (unilesson_id in QUESTIONS_FROM_ID)
      * 'A' - all questions of the course (nothing interesting in QUESTIONS_FROM_ID)
      * 
      * new values:
      * 'R' - all questions from the tree with root at selected lesson (include questions of selected lesson) 
      *       in the course (unilesson_id in QUESTIONS_FROM_ID)
      */
     if ($arTest["QUESTIONS_FROM"] == "C" || $arTest["QUESTIONS_FROM"] == "L") {
         $courseId = $arTest['COURSE_ID'] + 0;
         $courseLessonId = CCourse::CourseGetLinkedLesson($courseId);
         if ($courseLessonId === false) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_IS_EMPTY"), "ERROR_TEST_IS_EMPTY");
             return false;
         }
         $clauseAllChildsLessons = CLearnHelper::SQLClauseForAllSubLessons($courseLessonId);
         if ($arTest["QUESTIONS_FROM"] == "C") {
             $strSql = "SELECT Q.ID as QUESTION_ID, TLEUP.SOURCE_NODE as FROM_ID\n\t\t\t\tFROM b_learn_lesson L\n\t\t\t\tINNER JOIN b_learn_question Q ON L.ID = Q.LESSON_ID\n\t\t\t\tINNER JOIN b_learn_lesson_edges TLEUP ON L.ID = TLEUP.TARGET_NODE\n\t\t\t\tLEFT OUTER JOIN b_learn_lesson_edges TLEDOWN ON L.ID = TLEDOWN.SOURCE_NODE " . "WHERE L.ID IN (" . $clauseAllChildsLessons . ") \n" . " AND TLEDOWN.SOURCE_NODE IS NULL \n" . " AND TLEUP.SOURCE_NODE IN (" . $clauseAllChildsLessons . ") \n" . " AND Q.ACTIVE = 'Y' " . ($arTest["INCLUDE_SELF_TEST"] != "Y" ? "AND Q.SELF = 'N' " : "") . "ORDER BY " . ($arTest["RANDOM_QUESTIONS"] == "Y" ? CTest::GetRandFunction() : "L.SORT, Q.SORT");
         } else {
             $strSql = "SELECT Q.ID as QUESTION_ID, L.ID as FROM_ID " . "FROM b_learn_lesson L " . "INNER JOIN b_learn_question Q ON L.ID = Q.LESSON_ID " . "WHERE L.ID IN (" . $clauseAllChildsLessons . ") AND Q.ACTIVE = 'Y' " . ($arTest["INCLUDE_SELF_TEST"] != "Y" ? "AND Q.SELF = 'N' " : "") . "ORDER BY " . ($arTest["RANDOM_QUESTIONS"] == "Y" ? CTest::GetRandFunction() : "L.SORT, Q.SORT");
         }
         if (!($res = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__))) {
             return false;
         }
         $Values = array();
         $tmp = array();
         while ($arRecord = $res->Fetch()) {
             if (is_set($tmp, $arRecord["FROM_ID"])) {
                 if ($tmp[$arRecord["FROM_ID"]] < $arTest["QUESTIONS_AMOUNT"]) {
                     $tmp[$arRecord["FROM_ID"]]++;
                 } else {
                     continue;
                 }
             } else {
                 $tmp[$arRecord["FROM_ID"]] = 1;
             }
             $Values[] = $arRecord["QUESTION_ID"];
         }
         if (empty($Values)) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_IS_EMPTY"), "ERROR_TEST_IS_EMPTY");
             return false;
         }
         $DB->StartTransaction();
         foreach ($Values as $ID) {
             $strSql = "INSERT INTO b_learn_test_result (ATTEMPT_ID, QUESTION_ID) VALUES (" . $ATTEMPT_ID . "," . $ID . ")";
             if (!$DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__)) {
                 $DB->Rollback();
                 return false;
             }
         }
         $DB->Commit();
     } elseif (($arTest["QUESTIONS_FROM"] == "H" || $arTest["QUESTIONS_FROM"] == "S" || $arTest["QUESTIONS_FROM"] == "R") && $arTest["QUESTIONS_FROM_ID"]) {
         $WHERE = '';
         if ($arTest["QUESTIONS_FROM"] == "H") {
             /**
              * 'H' - all questions from the selected chapter (recursive) in the course 
              *       This case must be ignored, because converter to new data model updates 'H' to 'R', but in case
              *       when chapter is not exists updates didn't become. So QUESTIONS_FROM stayed in 'H' value. And it means,
              *       that there is no chapter exists with QUESTIONS_FROM_ID, so we can't do work. And we should just
              *       ignore, for backward compatibility (so, don't throw an error).
              */
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_IS_EMPTY"), "ERROR_TEST_IS_EMPTY");
             return false;
         } elseif ($arTest["QUESTIONS_FROM"] == 'R') {
             $clauseAllChildsLessons = CLearnHelper::SQLClauseForAllSubLessons($arTest['QUESTIONS_FROM_ID']);
             $WHERE = " (L.ID IN(" . $clauseAllChildsLessons . ") OR (L.ID = " . ($arTest['QUESTIONS_FROM_ID'] + 0) . ")) ";
         } elseif ($arTest["QUESTIONS_FROM"] == 'S') {
             $clauseAllChildsLessons = $arTest["QUESTIONS_FROM_ID"] + 0;
             $WHERE = " (L.ID IN(" . $clauseAllChildsLessons . ") OR (L.ID = " . ($arTest['QUESTIONS_FROM_ID'] + 0) . ")) ";
         } else {
             return false;
         }
         $strSql = "INSERT INTO b_learn_test_result (ATTEMPT_ID, QUESTION_ID) " . "SELECT " . $ATTEMPT_ID . " ,Q.ID " . "FROM b_learn_lesson L " . "INNER JOIN b_learn_question Q ON L.ID = Q.LESSON_ID " . "WHERE " . $WHERE . " AND Q.ACTIVE = 'Y' " . ($arTest["INCLUDE_SELF_TEST"] != "Y" ? "AND Q.SELF = 'N' " : "") . "ORDER BY " . ($arTest["RANDOM_QUESTIONS"] == "Y" ? CTest::GetRandFunction() : "Q.SORT ") . ($arTest["QUESTIONS_AMOUNT"] > 0 ? "LIMIT " . $arTest["QUESTIONS_AMOUNT"] : "");
         //echo $strSql;exit;
         $q = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
         if (!$q || intval($q->AffectedRowsCount()) <= 0) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_IS_EMPTY"), "ERROR_TEST_IS_EMPTY");
             return false;
         }
     } elseif ($arTest["QUESTIONS_FROM"] == 'A') {
         $courseId = $arTest['COURSE_ID'] + 0;
         $courseLessonId = CCourse::CourseGetLinkedLesson($courseId);
         if ($courseLessonId === false) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_IS_EMPTY"), "ERROR_TEST_IS_EMPTY");
             return false;
         }
         $clauseAllChildsLessons = CLearnHelper::SQLClauseForAllSubLessons($courseLessonId);
         $strSql = call_user_func($arCallbackSqlFormer, $ATTEMPT_ID, $arTest, $clauseAllChildsLessons, $courseLessonId);
         //echo $strSql; exit;
         $q = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
         if (!$q || intval($q->AffectedRowsCount()) <= 0) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_IS_EMPTY"), "ERROR_TEST_IS_EMPTY");
             return false;
         }
     } else {
         return false;
     }
     $strSql = "UPDATE b_learn_attempt SET QUESTIONS = '" . CTestResult::GetCount($ATTEMPT_ID) . "' WHERE ID = " . $ATTEMPT_ID;
     $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
     return true;
 }
     }
     $sessAttemptID = null;
     $sessAttemptFinished = true;
     $sessAttemptError = GetMessage("LEARNING_TIME_LIMIT");
     LocalRedirect($arResult["REDIRECT_PAGE"]);
 } elseif ($arTest["TIME_LIMIT"] > 0) {
     $arResult["SECONDS_TO_END"] = $arTest["TIME_LIMIT"] * 60 - (time() - MakeTimeStamp($arAttempt["DATE_START"]));
     $arResult["SECONDS_TO_END_STRING"] = _TimeToStringFormat($arResult["SECONDS_TO_END"]);
 }
 //If there are no questions, finish the attempt
 if ($arTest["PASSAGE_TYPE"] < 2) {
     $arProgress = CTestResult::GetProgress($sessAttemptID);
     if ($arProgress["TODO"] == 0) {
         $rsTestAttempt = new CTestAttempt();
         $rsTestAttempt->AttemptFinished($sessAttemptID);
         $rsAtt = CTestAttempt::GetByID($sessAttemptID);
         if (($arAtt = $rsAtt->GetNext()) && $arTest["APPROVED"] == "Y") {
             $arAtt["CORRECT_COUNT"] = CTestResult::GetCorrectCount($arAtt["ID"]);
             $sessAttempt = $arAtt;
         }
         $sessAttemptID = null;
         $sessAttemptFinished = true;
         LocalRedirect($arResult["REDIRECT_PAGE"]);
     }
 }
 //Get questions
 $rsTestResult = CTestResult::GetList(array("ID" => "ASC"), array("ATTEMPT_ID" => $sessAttemptID, 'CHECK_PERMISSIONS' => 'N'));
 $rsTestResult->NavStart(10000);
 $arResult["NAV"]["PAGE_COUNT"] = $rsTestResult->SelectedRowsCount();
 //If no questions
 if ($arResult["NAV"]["PAGE_COUNT"] <= 0) {