/** * <p>Возвращает вопрос плана тестирования по идентификатору ID.</p> * * * * * @param int $ID Идентификатор вопроса в плане тестирования. * * * * @return CDBResult <p>Возвращается объект <a * href="http://dev.1c-bitrix.ru/api_help/main/reference/cdbresult/index.php">CDBResult</a>.</p> * * * <h4>Example</h4> * <pre> * <? * if (CModule::IncludeModule("learning")) * { * $TEST_RESULT_ID = 2894; * * $res = CTestResult::GetByID($TEST_RESULT_ID); * * if ($arResult = $res->GetNext()) * { * echo " Question name: ".$arResult["QUESTION_NAME"]; * echo " Answered: ".$arResult["ANSWERED"]; * echo " Point: ".$arResult["POINT"]; * } * } * ?> * </pre> * * * * <h4>See Also</h4> * <ul> <li> <a href="http://dev.1c-bitrix.ru/api_help/main/reference/cdbresult/index.php">CDBResult</a> </li> <li> <a * href="../../fields.php#test_result">Поля плана тестирования</a> </li> <li> <a * href="index.php">CTestResult</a>::<a href="getlist.php">GetList</a> </li> </ul><a name="examples"></a> * * * @static * @link http://dev.1c-bitrix.ru/api_help/learning/classes/ctestresult/getbyid.php * @author Bitrix */ public static function GetByID($ID) { return CTestResult::GetList(Array(), Array("ID"=>$ID)); }
die; } $aTabs = array(array("DIV" => "edit1", "TAB" => GetMessage("LEARNING_ADMIN_TAB1"), "ICON" => "main_user_edit", "TITLE" => GetMessage("LEARNING_ADMIN_TAB1_EX"))); $tabControl = new CAdminForm("testResultTabControl", $aTabs); if ($_SERVER["REQUEST_METHOD"] == "POST" && strlen($Update) > 0 && check_bitrix_sessid()) { if ($ANSWERED != "Y") { $ANSWERED = "N"; $RESPONSE = ""; $POINT = 0; } elseif ($CORRECT != "Y") { $CORRECT = "N"; $POINT = 0; } $arFields = array("ANSWERED" => $ANSWERED, "CORRECT" => $CORRECT, "RESPONSE" => $RESPONSE, "POINT" => $POINT); $DB->StartTransaction(); $tr = new CTestResult(); $res = $tr->Update($ID, $arFields); if (!$res) { $DB->Rollback(); if ($e = $APPLICATION->GetException()) { $message = new CAdminMessage(GetMessage("LEARNING_ERROR"), $e); } $bVarsFromForm = true; } else { $tr->OnTestResultChange($ID); $DB->Commit(); if (strlen($apply) <= 0) { if (strlen($return_url) > 0) { LocalRedirect($return_url); } else { LocalRedirect("/bitrix/admin/learn_test_result_admin.php?lang=" . LANG . "&ATTEMPT_ID=" . $ATTEMPT_ID . GetFilterParams("filter_", false));
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; }
$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) { $rsTestAttempt = new CTestAttempt(); $rsTestAttempt->AttemptFinished($sessAttemptID); $sessAttemptID = null; $sessAttemptFinished = true; LocalRedirect($arResult["REDIRECT_PAGE"]); } if ($arResult["NAV"]["PAGE_NUMBER"] > $arResult["NAV"]["PAGE_COUNT"]) { $arResult["NAV"]["PAGE_NUMBER"] = 1; $arResult["REDIRECT_PAGE"] = str_replace("#PAGE_ID#", $arResult["NAV"]["PAGE_NUMBER"] + 1, $arResult["PAGE_TEMPLATE"]); } $questionPageIndex = 1;
// list initializing $arFilterFields = array("filter_question_name", "filter_id", "filter_answered", "filter_correct"); $lAdmin->InitFilter($arFilterFields); // filter initializing $arFilter = array("ID" => $filter_id, "ANSWERED" => $filter_answered, "CORRECT" => $filter_correct, "?QUESTION_NAME" => $filter_question_name); if ($ATTEMPT_ID > 0) { $arFilter["ATTEMPT_ID"] = $ATTEMPT_ID; } if ($lAdmin->EditAction()) { foreach ($FIELDS as $ID => $arFields) { if (!$lAdmin->IsUpdated($ID)) { continue; } $DB->StartTransaction(); $ID = IntVal($ID); $ob = new CTestResult(); if (!$ob->Update($ID, $arFields)) { if ($e = $APPLICATION->GetException()) { $lAdmin->AddUpdateError(GetMessage("SAVE_ERROR") . $ID . ": " . $e->GetString(), $ID); $DB->Rollback(); } } else { $ob->OnTestResultChange($ID); } $DB->Commit(); } } // group and single actions processing if ($arID = $lAdmin->GroupAction()) { if ($_REQUEST['action_target'] == 'selected') { $rsData = CTestResult::GetList(array($by => $order), $arFilter);
function GetByID($ID) { return CTestResult::GetList(array(), array("ID" => $ID)); }