• Модуль: learning
  • Путь к файлу: ~/bitrix/modules/learning/classes/general/attempt.php
  • Класс: CAllTestAttempt
  • Вызов: CAllTestAttempt::CreateAttemptQuestions
static function CreateAttemptQuestions($ATTEMPT_ID)
{
	global $APPLICATION, $DB;

	$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__."
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") // X questions from every lessons from every chapter in the course { $strSql = "SELECT Q.ID as QUESTION_ID, TLEUP.SOURCE_NODE as FROM_ID FROM b_learn_lesson L INNER JOIN b_learn_question Q ON L.ID = Q.LESSON_ID INNER JOIN b_learn_lesson_edges TLEUP ON L.ID = TLEUP.TARGET_NODE LEFT OUTER JOIN b_learn_lesson_edges TLEDOWN ON L.ID = TLEDOWN.SOURCE_NODE " . "WHERE L.ID IN (" . $clauseAllChildsLessons . ") n" // only lessons from COURSE_ID = $arTest['COURSE_ID'] . " AND TLEDOWN.SOURCE_NODE IS NULL n" // exclude lessons, contains other lessons ("chapters") // include lessons in current course tree context only (and exclude immediate childs of course) . " AND TLEUP.SOURCE_NODE IN (" . $clauseAllChildsLessons . ") n" . " AND Q.ACTIVE = 'Y' " // active questions only . ($arTest["INCLUDE_SELF_TEST"] != "Y" ? "AND Q.SELF = 'N' " : "") . "ORDER BY ".($arTest["RANDOM_QUESTIONS"] == "Y" ? CTest::GetRandFunction() : "L.SORT, Q.SORT, L.ID"); } else // 'L' X questions from every lesson in course { $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, L.ID"); } if (!$res = $DB->Query($strSql, false, "File: ".__FILE__."
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__."
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') // all questions from the tree with root at selected lesson (include questions of selected lesson) in the course (unilesson_id in QUESTIONS_FROM_ID) { $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') // 'S' - all questions from the selected lesson (unilesson_id in QUESTIONS_FROM_ID) { $clauseAllChildsLessons = $arTest["QUESTIONS_FROM_ID"] + 0; $WHERE = " (L.ID IN(" . $clauseAllChildsLessons . ") OR (L.ID = " . ($arTest['QUESTIONS_FROM_ID'] + 0) . ")) "; } else { return (false); } $strSql = "SELECT Q.ID AS QUESTION_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() : "L.SORT, Q.SORT, L.ID "). ($arTest["QUESTIONS_AMOUNT"] > 0 ? "LIMIT ".$arTest["QUESTIONS_AMOUNT"] :""); $success = false; $rsQuestions = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); $strSql = ''; if ($rsQuestions) { $arSqlSubstrings = array(); while ($arQuestion = $rsQuestions->fetch()) $arSqlSubstrings[] = "(" . $ATTEMPT_ID . ", " . $arQuestion['QUESTION_ID'] . ")"; if ( ! empty($arSqlSubstrings) ) $strSql = "INSERT INTO b_learn_test_result (ATTEMPT_ID, QUESTION_ID) VALUES " . implode(",n", $arSqlSubstrings); if ($strSql !== '') { $rc = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); if ($rc && intval($rc->AffectedRowsCount()) > 0) $success = true; } } if ( ! $success ) { $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 = "SELECT Q.ID AS QUESTION_ID FROM b_learn_lesson L INNER JOIN b_learn_question Q ON L.ID = Q.LESSON_ID WHERE (L.ID IN (" . $clauseAllChildsLessons . ") OR (L.ID = " . ($courseLessonId + 0) . ") ) 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, L.ID "). ($arTest["QUESTIONS_AMOUNT"] > 0 ? "LIMIT " . ($arTest["QUESTIONS_AMOUNT"] + 0) : ""); $success = false; $rsQuestions = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); $strSql = ''; if ($rsQuestions) { $arSqlSubstrings = array(); while ($arQuestion = $rsQuestions->fetch()) $arSqlSubstrings[] = "(" . $ATTEMPT_ID . ", " . $arQuestion['QUESTION_ID'] . ")"; if ( ! empty($arSqlSubstrings) ) $strSql = "INSERT INTO b_learn_test_result (ATTEMPT_ID, QUESTION_ID) VALUES " . implode(",n", $arSqlSubstrings); if ($strSql !== '') { $rc = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); if ($rc && intval($rc->AffectedRowsCount()) > 0) $success = true; } } if ( ! $success ) { $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__."
Line: ".__LINE__); return true; }