function CheckFields(&$arFields, $ID = false)
 {
     global $DB, $APPLICATION;
     if ($ID === false && !is_set($arFields, "STUDENT_ID")) {
         $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_USER_ID"), "EMPTY_STUDENT_ID");
         return false;
     } elseif (is_set($arFields, "STUDENT_ID")) {
         $dbResult = CUser::GetByID($arFields["STUDENT_ID"]);
         if (!$dbResult->Fetch()) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_USER_ID_EX"), "ERROR_NO_STUDENT_ID");
             return false;
         }
     }
     if ($ID === false && !is_set($arFields, "TEST_ID")) {
         $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_ID"), "EMPTY_TEST_ID");
         return false;
     } elseif (is_set($arFields, "TEST_ID")) {
         $r = CTest::GetByID($arFields["TEST_ID"]);
         if (!$r->Fetch()) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_TEST_ID_EX"), "ERROR_NO_TEST_ID");
             return false;
         }
     }
     if (is_set($arFields, "STUDENT_ID") && is_set($arFields, "TEST_ID")) {
         $res = CGradeBook::GetList(array(), array("STUDENT_ID" => $arFields["STUDENT_ID"], "TEST_ID" => $arFields["TEST_ID"]));
         if ($res->Fetch()) {
             $APPLICATION->ThrowException(GetMessage("LEARNING_BAD_GRADEBOOK_DUPLICATE"), "ERROR_GRADEBOOK_DUPLICATE");
             return false;
         }
     }
     if (is_set($arFields, "COMPLETED") && $arFields["COMPLETED"] != "Y") {
         $arFields["COMPLETED"] = "N";
     }
     return true;
 }
Beispiel #2
0
	public static function _CreateAttemptQuestionsSQLFormer($ATTEMPT_ID, $arTest, $clauseAllChildsLessons, $courseLessonId)
	{
		$strSql =
		"INSERT INTO b_learn_test_result (ATTEMPT_ID, QUESTION_ID)
		SELECT " . ($ATTEMPT_ID + 0) . " ,Q.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() : "Q.SORT ").
		($arTest["QUESTIONS_AMOUNT"] > 0 ? "LIMIT " . ($arTest["QUESTIONS_AMOUNT"] + 0) : "");

		return ($strSql);
	}
Beispiel #3
0
<?php

if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
    die;
}
if (!CModule::IncludeModule("learning")) {
    return;
}
$arCourses = array();
$courses = CCourse::GetList(array("SORT" => "ASC"));
while ($arRes = $courses->Fetch()) {
    $arCourses[$arRes["ID"]] = $arRes["NAME"];
}
$arTests = array();
if ($arCurrentValues["COURSE_ID"] && intval($arCurrentValues["COURSE_ID"]) > 0) {
    $rsTest = CTest::GetList(array("SORT" => "ASC"), array("ACTIVE" => "Y", "COURSE_ID" => $arCurrentValues["COURSE_ID"]));
    while ($arTest = $rsTest->GetNext()) {
        $arTests[$arTest["ID"]] = "[" . $arTest["ID"] . "] " . $arTest["NAME"];
    }
}
$arComponentParameters = array("PARAMETERS" => array("COURSE_ID" => array("NAME" => GetMessage("LEARNING_COURSE_ID"), "TYPE" => "LIST", "VALUES" => $arCourses, "PARENT" => "BASE", "ADDITIONAL_VALUES" => "Y", "REFRESH" => "Y", "DEFAULT" => '={$_REQUEST["COURSE_ID"]}'), "TEST_ID" => array("NAME" => GetMessage("T_LEARNING_DETAIL_ID"), "TYPE" => "LIST", "VALUES" => $arTests, "ADDITIONAL_VALUES" => "Y", "PARENT" => "BASE", "DEFAULT" => '={$_REQUEST["TEST_ID"]}'), "PAGE_NUMBER_VARIABLE" => array("NAME" => GetMessage("T_LEARNING_PAGE_NUMBER_VARIABLE"), "TYPE" => "STRING", "PARENT" => "ADDITIONAL_SETTINGS", "DEFAULT" => 'PAGE'), "GRADEBOOK_TEMPLATE" => array("NAME" => GetMessage("LEARNING_GRADEBOOK_TEMPLATE_NAME"), "TYPE" => "STRING", "PARENT" => "URL_TEMPLATES", "DEFAULT" => '../gradebook.php?TEST_ID=#TEST_ID#', "COLS" => 45), "PAGE_WINDOW" => array("NAME" => GetMessage("LEARNING_PAGE_WINDOW_NAME"), "TYPE" => "STRING", "PARENT" => "ADDITIONAL_SETTINGS", "DEFAULT" => '10'), "SHOW_TIME_LIMIT" => array("NAME" => GetMessage("LEARNING_SHOW_TIME_LIMIT"), "TYPE" => "CHECKBOX", "PARENT" => "ADDITIONAL_SETTINGS", "DEFAULT" => "Y"), "SET_TITLE" => array()));
    public function BuildList()
    {
        global $USER;
        $filterParams = GetFilterParams('filter_');
        // list's footer
        $this->oList->AddFooter(array(array('title' => GetMessage('MAIN_ADMIN_LIST_SELECTED'), 'value' => $this->rsData->SelectedRowsCount()), array('counter' => true, 'title' => GetMessage('MAIN_ADMIN_LIST_CHECKED'), 'value' => '0')));
        $oParentPath = new CLearnPath();
        if (isset($_GET['LESSON_PATH'])) {
            $oParentPath->ImportUrlencoded($_GET['LESSON_PATH']);
        }
        $arParentPath = $oParentPath->GetPathAsArray();
        // building list
        while ($arRes = $this->rsData->NavNext(false)) {
            $oCurPath = new CLearnPath();
            $oCurPath->SetPathFromArray(array_merge($arParentPath, array($arRes['LESSON_ID'])));
            $urlCurPath = $oCurPath->ExportUrlencoded();
            unset($oCurPath);
            // PUBLISH_PROHIBITED available in context of most parent course only
            if ($this->contextCourseLessonId !== false) {
                $arRes['PUBLISH_PROHIBITED'] = 'N';
                if (CLearnLesson::IsPublishProhibited($arRes['LESSON_ID'], $this->contextCourseLessonId)) {
                    $arRes['PUBLISH_PROHIBITED'] = 'Y';
                }
            }
            $arRes['SITE_ID'] = '';
            $courseId = CLearnLesson::GetLinkedCourse($arRes['LESSON_ID']);
            if ($courseId !== false) {
                $hrefPrefix = 'learn_course_edit.php?COURSE_ID=' . $courseId;
                $resCourseSites = CCourse::GetSite($courseId);
                while ($arCourseSites = $resCourseSites->Fetch()) {
                    if ($arRes['SITE_ID'] != '') {
                        $arRes['SITE_ID'] .= ' / ';
                    }
                    $arRes['SITE_ID'] .= htmlspecialcharsbx($arCourseSites['LID']);
                }
            } else {
                $hrefPrefix = 'learn_unilesson_edit.php?LESSON_ID=' . $arRes['LESSON_ID'] . '&LESSON_PATH=' . urlencode($urlCurPath);
            }
            $actionEditLesson = $hrefPrefix . '&lang=' . LANG . $filterParams;
            $rowAction = false;
            $rowTitle = '';
            if (!$this->IsSearchMode()) {
                $rowAction = 'learn_unilesson_admin.php?lang=' . LANG . '&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arRes['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurPath . '&' . $this->hrefSearchRetPoint;
                $rowTitle = GetMessage('LEARNING_TRAVERSE');
                // "Traverse list of immediate childs"
                if (!$arRes['IS_CHILDS']) {
                    $rowAction = $actionEditLesson;
                    $rowTitle = GetMessage('LEARNING_EDIT_TITLE');
                }
            }
            $row =& $this->oList->AddRow($arRes['LESSON_ID'], $arRes, $rowAction, $rowTitle);
            $arParents = $arChilds = array();
            $htmlParents = $htmlChilds = '';
            $rsParents = CLearnLesson::GetListOfImmediateParents($arRes['LESSON_ID'], array(), array('CHECK_PERMISSIONS' => 'N'));
            while ($arParent = $rsParents->Fetch()) {
                $arParents[] = $arParent['NAME'];
            }
            $arParents = array_map('htmlspecialcharsbx', $arParents);
            if (count($arParents) > 0) {
                $htmlParents = implode('<hr width="100%" size="1">', $arParents);
            } else {
                $htmlParents = '&nbsp;';
            }
            $rsChilds = CLearnLesson::GetListOfImmediateChilds($arRes['LESSON_ID'], array(), array('CHECK_PERMISSIONS' => 'N'));
            while ($arChild = $rsChilds->Fetch()) {
                $arChilds[] = $arChild['NAME'];
            }
            $arChilds = array_map('htmlspecialcharsbx', $arChilds);
            if (count($arChilds) > 0) {
                $htmlChilds = implode('<hr width="100%" size="1">', $arChilds);
            } else {
                $htmlChilds = '&nbsp;';
            }
            if (isset($arRes['LINKED_LESSON_ID']) && $arRes['LINKED_LESSON_ID'] > 0) {
                $icon = 'learning_icon_courses';
            } elseif (count($arChilds) > 0) {
                $icon = 'learning_icon_chapters';
            } else {
                $icon = 'learning_icon_lessons';
            }
            if (!$this->IsSearchMode()) {
                $row->AddViewField('NAME', '<span class="adm-list-table-icon-link"><span class="adm-submenu-item-link-icon adm-list-table-icon ' . $icon . '"></span>' . ($rowAction === false ? '<span class="adm-list-table-link">' . htmlspecialcharsbx($arRes['NAME']) . '</span>' : '<a href="' . $rowAction . '" class="adm-list-table-link">' . htmlspecialcharsbx($arRes['NAME']) . '</a>') . '</span>');
            } else {
                $actionUseLesson = "(function()\n\t\t\t\t\t{\n\t\t\t\t\t\tvar fnName = '" . str_replace(array("'", ';', ',', "\n", "\r"), '', htmlspecialcharsbx($this->search_retpoint)) . "';\n\t\t\t\t\t\tif ( ! (window.opener && window.opener[fnName]) )\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\twindow.opener[fnName]('" . (int) $arRes['LESSON_ID'] . "', '" . CUtil::JSEscape(htmlspecialcharsbx($arRes['NAME'])) . "');\n\t\t\t\t\t\twindow.close();\n\t\t\t\t\t})();\n\t\t\t\t\t";
                $row->AddViewField('NAME', '<a href="javascript:void(0);" class="adm-list-table-icon-link" onclick="' . $actionUseLesson . '"><span class="adm-submenu-item-link-icon adm-list-table-icon ' . $icon . '"></span><span class="adm-list-table-link">' . htmlspecialcharsbx($arRes['NAME']) . '</span></a>');
            }
            $row->AddViewField('PARENTS', $htmlParents);
            $row->AddEditField('PARENTS', '&nbsp;');
            $row->AddViewField('CHILDS', $htmlChilds);
            $row->AddEditField('CHILDS', '&nbsp;');
            // this is very heavy statistic, so will be a good idea to add settings to the module, which turn off this statistics
            $oLearnTree = CLearnLesson::GetTree($arRes['LESSON_ID']);
            $arTree = $oLearnTree->GetTreeAsList();
            $depth = -1;
            $chapterCount = 0;
            $lessonsCount = 0;
            $questionsCount = CLQuestion::GetCount(array('LESSON_ID' => (int) $arRes['LESSON_ID']));
            foreach ($arTree as $arLessonData) {
                if ($arLessonData['IS_CHILDS']) {
                    ++$chapterCount;
                } else {
                    ++$lessonsCount;
                }
                if ((int) $arLessonData['#DEPTH_IN_TREE'] > $depth) {
                    $depth = (int) $arLessonData['#DEPTH_IN_TREE'];
                }
                $questionsCount += CLQuestion::GetCount(array('LESSON_ID' => (int) $arLessonData['LESSON_ID']));
            }
            // PUBLISH_PROHIBITED available in context of most parent course only
            if ($this->contextCourseLessonId !== false) {
                if ($this->IsLessonUpdateAccess($arRes['LESSON_ID']) === true) {
                    $row->AddInputField('PUBLISH_PROHIBITED', array('size' => '35'));
                    $row->AddCheckField('PUBLISH_PROHIBITED');
                } else {
                    $row->AddCheckField('PUBLISH_PROHIBITED', true);
                }
            }
            // Render CARDINALITY fields
            $htmlDepth = (int) ($depth + 1);
            $htmlChapters = (string) (int) $chapterCount . '&nbsp;[<a href="learn_unilesson_edit.php?lang=' . LANG . '&PROPOSE_RETURN_LESSON_PATH=' . $urlCurPath . '" title="' . GetMessage('LEARNING_UNILESSON_ADD') . '"' . '>+</a>]';
            $htmlLessons = (string) (int) $lessonsCount . '&nbsp;[<a href="learn_unilesson_edit.php?lang=' . LANG . '&PROPOSE_RETURN_LESSON_PATH=' . $urlCurPath . '" title="' . GetMessage('LEARNING_UNILESSON_ADD') . '"' . '>+</a>]';
            $htmlQuestions = '<a href="learn_question_admin.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arRes['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurPath . '" title="' . GetMessage('LEARNING_QUESTION_ALT') . '">' . (int) $questionsCount . '</a>' . '&nbsp;[' . '<a href="learn_question_edit.php?lang=' . LANG . '&LESSON_PATH=' . $urlCurPath . '&QUESTION_TYPE=S' . '&filter=Y&set_filter=Y' . '&from=learn_menu"' . ' title="' . GetMessage('LEARNING_QUESTION_ADD') . '">+</a>' . ']';
            $row->AddViewField('CARDINALITY_DEPTH', $htmlDepth);
            $row->AddViewField('CARDINALITY_CHAPTERS', $htmlChapters);
            $row->AddViewField('CARDINALITY_LESSONS', $htmlLessons);
            $row->AddViewField('CARDINALITY_QUESTIONS', $htmlQuestions);
            if ($courseId !== false) {
                $testsCount = (int) CTest::GetCount(array('COURSE_ID' => $courseId));
                $htmlTests = '<a href="learn_test_admin.php?lang=' . LANG . '&COURSE_ID=' . $courseId . '&PARENT_LESSON_ID=' . (int) $arRes['LESSON_ID'] . '&LESSON_PATH=' . $urlCurPath . '&filter=Y&set_filter=Y"' . '>' . $testsCount . '</a>' . '&nbsp;[<a href="learn_test_edit.php?lang=' . LANG . '&COURSE_ID=' . $courseId . '&PARENT_LESSON_ID=' . (int) $arRes['LESSON_ID'] . '&LESSON_PATH=' . $urlCurPath . '&filter=Y&set_filter=Y"
					title="' . GetMessage('LEARNING_QUESTION_ADD') . '"' . '>+</a>]';
                $row->AddViewField('CARDINALITY_TESTS', $htmlTests);
            }
            if (!$this->IsSearchMode() && $this->IsLessonUpdateAccess($arRes['LESSON_ID']) === true) {
                $row->AddInputField('NAME', array('size' => '35'));
                // SORT field editing possibly only for courses and for lessons in relation to parent lesson
                if ($this->IsListChildLessonsMode() || $this->IsListAnyCoursesMode()) {
                    $row->AddInputField('SORT', array('size' => '3'));
                }
                $row->AddCheckField('ACTIVE');
                $row->AddInputField('CODE');
            } else {
                $row->AddCheckField('ACTIVE', false);
            }
            $row->AddViewField('CREATED_USER_NAME', $arRes['CREATED_USER_NAME']);
            $arActions = array();
            if (!$this->IsSearchMode()) {
                if ($this->IsLessonUpdateAccess($arRes['LESSON_ID']) === true) {
                    $editTxt = GetMessage('MAIN_ADMIN_MENU_EDIT');
                } else {
                    $editTxt = GetMessage('MAIN_ADMIN_MENU_OPEN');
                }
                // Actions
                $arActions[] = array('ICON' => 'edit', 'TEXT' => $editTxt, 'ACTION' => $this->oList->ActionRedirect($actionEditLesson));
                $arActions[] = array("SEPARATOR" => true);
                $arActions[] = array('ICON' => 'list', 'TEXT' => GetMessage('LEARNING_QUESTION_ALT') . ' (' . ($questionsCount + 0) . ')', 'ACTION' => $this->oList->ActionRedirect('learn_question_admin.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arRes['LESSON_ID'] + 0) . '&LESSON_PATH=' . urlencode($urlCurPath)));
                /*
                $arActions[] = array(
                	"ICON"=>"copy",
                	"TEXT"=>GetMessage("MAIN_ADMIN_ADD_COPY"),
                	"ACTION"=>$this->oList->ActionRedirect("learn_course_edit.php?COPY_ID=".$f_ID));
                */
                $isDeleteCmdDisabled = true;
                $isDisbandCmdDisabled = true;
                $deleteMSG = '';
                $disbandMSG = '';
                $actionDisband = '';
                $action = '';
                if ($arRes['CHILDS_CNT'] > 0) {
                    $deleteMSG = GetMessage('LEARNING_ADMIN_MENU_DELETE_RECURSIVE') . ' (' . (string) (int) $arRes['CHILDS_CNT'] . ')';
                } else {
                    $deleteMSG = GetMessage("MAIN_ADMIN_MENU_DELETE");
                }
                $disbandMSG = GetMessage('LEARNING_ADMIN_MENU_DISBAND');
                $isEnoughRightsForDisbandLesson = false;
                try {
                    $this->EnsureLessonDisbandAccess($arRes['LESSON_ID']);
                    $isEnoughRightsForDisbandLesson = true;
                } catch (CLearnRenderAdminUnilessonListException $e) {
                    if ($e->GetCode() & CLearnRenderAdminUnilessonListException::C_ACCESS_DENIED) {
                    } else {
                        // bubble exception
                        throw new CLearnRenderAdminUnilessonListException($e->GetMessage(), $e->GetCode());
                    }
                }
                // If we can unlink all neighbours and remove lesson
                if ($isEnoughRightsForDisbandLesson) {
                    $arOPathes = CLearnLesson::GetListOfParentPathes($arRes['LESSON_ID']);
                    $parentPathesCnt = count($arOPathes);
                    // prepare "Disband" command
                    $isDisbandCmdDisabled = false;
                    $actionDisband = $this->oList->ActionDoGroup($arRes['LESSON_ID'], 'disband', 'PARENT_LESSON_ID=' . ($this->requestedParentLessonId + 0));
                    if ($parentPathesCnt >= 1) {
                        $actionDisband = "if(confirm('" . str_replace('#CNT#', $parentPathesCnt, GetMessageJS('LEARNING_CONFIRM_DISBAND_LESSON_WITH_PARENT_PATHES')) . "')) " . '{ ' . $actionDisband . ' }';
                    }
                    $actionDisband = "if(confirm('" . GetMessageJS('LEARNING_ADMIN_MENU_DISBAND_QUESTION') . "')) " . '{ ' . $actionDisband . ' }';
                    // prepare "Remove" command
                    $isDeleteCmdDisabled = false;
                    if ($arRes['CHILDS_CNT'] > 0) {
                        $action = $this->oList->ActionDoGroup($arRes['LESSON_ID'], 'recursive_delete', 'PARENT_LESSON_ID=' . ($this->requestedParentLessonId + 0));
                    } else {
                        // If no childs => "delete" is equal to "disband"
                        $action = $this->oList->ActionDoGroup($arRes['LESSON_ID'], 'disband', 'PARENT_LESSON_ID=' . ($this->requestedParentLessonId + 0));
                    }
                    if ($parentPathesCnt >= 1) {
                        $deleteMSG .= ' [' . $parentPathesCnt . ']';
                        $action = "if(confirm('" . str_replace('#CNT#', $parentPathesCnt, GetMessageJS("LEARNING_CONFIRM_DEL_LESSON_WITH_PARENT_PATHES")) . "')) " . $action;
                    } else {
                        $action = "if(confirm('" . GetMessageJS('LEARNING_CONFIRM_DEL_MESSAGE') . "')) " . $action;
                    }
                }
                // We can "disband" only lessons, that contains childs
                $arActions[] = array("SEPARATOR" => true);
                if ($arRes['CHILDS_CNT'] > 0) {
                    $arActions[] = array('ICON' => 'delete', 'TEXT' => $disbandMSG, 'ACTION' => $actionDisband, 'DISABLED' => $isDisbandCmdDisabled, 'TITLE' => GetMessage('LEARNING_ADMIN_MENU_DISBAND_TITLE'));
                }
                $arActions[] = array('ICON' => 'delete', 'TEXT' => $deleteMSG, 'ACTION' => $action, 'DISABLED' => $isDeleteCmdDisabled);
            } else {
                $arActions[] = array('ICON' => 'list', 'TEXT' => GetMessage('LEARNING_SELECT'), 'ACTION' => $actionUseLesson);
            }
            $row->AddActions($arActions);
        }
        return $this;
    }
Beispiel #5
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;
 }
Beispiel #6
0
 function GetList($arOrder = array(), $arFilter = array())
 {
     global $DB, $USER;
     if (!is_array($arFilter)) {
         $arFilter = array();
     }
     $oPermParser = new CLearnParsePermissionsFromFilter($arFilter);
     $arSqlSearch = CTest::GetFilter($arFilter);
     $strSqlSearch = "";
     for ($i = 0; $i < count($arSqlSearch); $i++) {
         if (strlen($arSqlSearch[$i]) > 0) {
             $strSqlSearch .= " AND " . $arSqlSearch[$i] . " ";
         }
     }
     $strSql = "SELECT DISTINCT T.*, " . $DB->DateToCharFunction("T.TIMESTAMP_X") . " as TIMESTAMP_X " . "FROM b_learn_test T " . "INNER JOIN b_learn_course C ON T.COURSE_ID = C.ID " . "WHERE 1=1 ";
     if ($oPermParser->IsNeedCheckPerm()) {
         $strSql .= " AND C.LINKED_LESSON_ID IN (" . $oPermParser->SQLForAccessibleLessons() . ") ";
     }
     $strSql .= $strSqlSearch;
     /* was:
     		$bCheckPerm = ($APPLICATION->GetUserRight("learning") < "W" && !$USER->IsAdmin() && $arFilter["CHECK_PERMISSIONS"] != "N");
     
     		$userID = $USER->GetID() ? $USER->GetID() : 0;
     		$strSql =
     			"SELECT DISTINCT T.*, ".
     			$DB->DateToCharFunction("T.TIMESTAMP_X")." as TIMESTAMP_X ".
     			"FROM b_learn_test T ".
     			"INNER JOIN b_learn_course C ON T.COURSE_ID = C.ID ".
     			($bCheckPerm ?
     			"LEFT JOIN b_learn_course_permission CP ON CP.COURSE_ID = C.ID "
     			: "").
     			"WHERE 1=1 ".
     			($bCheckPerm ?
     			"AND CP.USER_GROUP_ID IN (".$USER->GetGroups().") ".
     			"AND CP.PERMISSION >= '".(strlen($arFilter["MIN_PERMISSION"])==1 ? $arFilter["MIN_PERMISSION"] : "R")."' ".
     			"AND (CP.PERMISSION='X' OR C.ACTIVE='Y') "
     			:"").
     			$strSqlSearch;
     		*/
     if (!is_array($arOrder)) {
         $arOrder = array();
     }
     foreach ($arOrder as $by => $order) {
         $by = strtolower($by);
         $order = strtolower($order);
         if ($order != "asc") {
             $order = "desc";
         }
         if ($by == "id") {
             $arSqlOrder[] = " T.ID " . $order . " ";
         } elseif ($by == "name") {
             $arSqlOrder[] = " T.NAME " . $order . " ";
         } elseif ($by == "active") {
             $arSqlOrder[] = " T.ACTIVE " . $order . " ";
         } elseif ($by == "sort") {
             $arSqlOrder[] = " T.SORT " . $order . " ";
         } else {
             $arSqlOrder[] = " T.TIMESTAMP_X " . $order . " ";
             $by = "timestamp_x";
         }
     }
     $strSqlOrder = "";
     DelDuplicateSort($arSqlOrder);
     for ($i = 0; $i < count($arSqlOrder); $i++) {
         if ($i == 0) {
             $strSqlOrder = " ORDER BY ";
         } else {
             $strSqlOrder .= ",";
         }
         $strSqlOrder .= $arSqlOrder[$i];
     }
     $strSql .= $strSqlOrder;
     //echo $strSql;
     return $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
 }
Beispiel #7
0
        $arContent["SELECTED"] = _IsItemSelected(array($itemURL, $selftestURL));
        $lessonCount++;
    }
    if ($arContent["SELECTED"]) {
        $lessonCurrent = $lessonCount;
    }
    $arResult["ITEMS"][] = $arContent;
}
//Page Properties
$APPLICATION->SetPageProperty("learning_course_name", $arResult["COURSE"]["NAME"]);
$APPLICATION->SetPageProperty("learning_lesson_count", $lessonCount);
$APPLICATION->SetPageProperty("learning_lesson_current", $lessonCurrent);
//Test list item
$url = CComponentEngine::MakePathFromTemplate($arParams["TESTS_LIST_TEMPLATE"], array("COURSE_ID" => $arParams["COURSE_ID"]));
$arSelectedItems = array($url);
$rsTest = CTest::GetList(array(), array("COURSE_ID" => $arParams["COURSE_ID"], "ACTIVE" => "Y"));
$rsTest->NavStart(100);
while ($arTest = $rsTest->Fetch()) {
    $arSelectedItems[] = CComponentEngine::MakePathFromTemplate($arParams["TEST_DETAIL_TEMPLATE"], array("TEST_ID" => $arTest["ID"], "COURSE_ID" => $arParams["COURSE_ID"]));
}
$arResult["ITEMS"][] = array("NAME" => GetMessage('LEARNING_TEST_LIST') . "&nbsp;(" . $rsTest->SelectedRowsCount() . ")", "URL" => $url, "TYPE" => "TL", "SELECTED" => _IsItemSelected($arSelectedItems), "DEPTH_LEVEL" => 1);
unset($arContent);
unset($rsContent);
//Open chapters from Cookies
$arOpenChapters = array();
if (array_key_exists("LEARN_MENU_" . $arParams["COURSE_ID"], $_COOKIE)) {
    $arOpenChapters = split(",", $_COOKIE["LEARN_MENU_" . $arParams["COURSE_ID"]]);
}
//Chapter open if child selected
for ($itemIndex = 0, $size = count($arResult["ITEMS"]); $itemIndex < $size; $itemIndex++) {
    if ($arResult["ITEMS"][$itemIndex]["TYPE"] != "CH" || $arResult["ITEMS"][$itemIndex]["SELECTED"] === true) {
Beispiel #8
0
	/**
	 * <p>Возвращает количество тестов по заданному фильтру.</p>
	 *
	 *
	 *
	 *
	 * @param array $arrayarFilter = Array() Массив вида <i> array("фильтруемое поле"=&gt;"значение фильтра" [, ...])</i>.
	 * Описание фильтра см. в <a
	 * href="http://dev.1c-bitrix.ru/api_help/learning/classes/ctest/getlist.php">CTest::GetList</a>.<br> По
	 * умолчанию тесты не фильтруются.
	 *
	 *
	 *
	 * @return int <p>Число - количество тестов.</p>
	 *
	 *
	 * <h4>Example</h4> 
	 * <pre>
	 * &lt;?
	 * if (CModule::IncludeModule("learning"))
	 * {
	 *     $COURSE_ID = 97;
	 *     
	 *     $cnt = CTest::GetCount(Array("ACTIVE" =&gt; "Y", "COURSE_ID" =&gt; $COURSE_ID));
	 * 
	 *     echo "Number of tests: ".$cnt;
	 * }
	 * 
	 * ?&gt;
	 * 
	 * &lt;?
	 * if (CModule::IncludeModule("learning"))
	 * {
	 *     $COURSE_ID = 97;
	 *     
	 *     $cnt = CTest::GetCount(Array("CHECK_PERMISSIONS" =&gt; "N", "COURSE_ID" =&gt; $COURSE_ID));
	 * 
	 *     echo "Number of tests: ".$cnt;
	 * }
	 * 
	 * ?&gt;
	 * </pre>
	 *
	 *
	 *
	 * <h4>See Also</h4> 
	 * <ul> <li> <a href="http://dev.1c-bitrix.ru/api_help/learning/classes/ctest/index.php">CTest</a>::<a
	 * href="http://dev.1c-bitrix.ru/api_help/learning/classes/ctest/getlist.php">GetList</a> </li> </ul><a
	 * name="examples"></a>
	 *
	 *
	 * @static
	 * @link http://dev.1c-bitrix.ru/api_help/learning/classes/ctest/getcount.php
	 * @author Bitrix
	 */
	public static function GetCount($arFilter = Array())
	{
		global $DB, $USER, $APPLICATION;

		if (!is_array($arFilter))
			$arFilter = Array();

		$oPermParser = new CLearnParsePermissionsFromFilter ($arFilter);

		$arSqlSearch = CTest::GetFilter($arFilter);

		$strSqlSearch = "";
		for($i=0; $i<count($arSqlSearch); $i++)
			if(strlen($arSqlSearch[$i])>0)
				$strSqlSearch .= " AND ".$arSqlSearch[$i]." ";


		$strSql = 
			"SELECT COUNT(*) as CNT 
			FROM b_learn_test T 
			INNER JOIN b_learn_course C 
				ON T.COURSE_ID = C.ID
			WHERE 1=1";

		if ($oPermParser->IsNeedCheckPerm())
			$strSql .= " AND C.LINKED_LESSON_ID IN (" . $oPermParser->SQLForAccessibleLessons() . ") ";

		$strSql .= $strSqlSearch;

		/* was:

		$strSql = "SELECT COUNT(*) as CNT ".
					"FROM b_learn_test T ".
					"INNER JOIN b_learn_course C ON T.COURSE_ID = C.ID ".
					($bCheckPerm ? "LEFT JOIN b_learn_course_permission CP ON CP.COURSE_ID = C.ID " : "").
					"WHERE 1=1 ".
					($bCheckPerm ?
						"AND CP.USER_GROUP_ID IN (".$USER->GetGroups().") ".
						"AND CP.PERMISSION >= '".(strlen($arFilter["MIN_PERMISSION"])==1 ? $arFilter["MIN_PERMISSION"] : "R")."' ".
						"AND (CP.PERMISSION='X' OR C.ACTIVE='Y')"
					:"").
					$strSqlSearch;
		*/

		$res = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);

		if ($ar = $res->Fetch())
			return intval($ar["CNT"]);
		else
			return 0;

	}
Beispiel #9
0
if (!CModule::IncludeModule("learning")) {
    ShowError(GetMessage("LEARNING_MODULE_NOT_FOUND"));
    return;
}
$arParams["COURSE_ID"] = isset($arParams["COURSE_ID"]) && intval($arParams["COURSE_ID"]) > 0 ? intval($arParams["COURSE_ID"]) : intval($_REQUEST["COURSE_ID"]);
$arParams["TEST_DETAIL_TEMPLATE"] = strlen($arParams["TEST_DETAIL_TEMPLATE"]) > 0 ? htmlspecialchars($arParams["TEST_DETAIL_TEMPLATE"]) : 'test.php?TEST_ID=#TEST#';
$arParams["CHECK_PERMISSIONS"] = isset($arParams["CHECK_PERMISSIONS"]) && $arParams["CHECK_PERMISSIONS"] == "N" ? "N" : "Y";
$arParams["TESTS_PER_PAGE"] = intval($arParams["TESTS_PER_PAGE"]) > 0 ? intval($arParams["TESTS_PER_PAGE"]) : 20;
//Title
$arParams["SET_TITLE"] = $arParams["SET_TITLE"] == "N" ? "N" : "Y";
if ($arParams["SET_TITLE"] == "Y") {
    $APPLICATION->SetTitle(GetMessage("LEARNING_TESTS_LIST"));
}
//arResult
$arResult = array("TESTS" => array(), "TESTS_COUNT" => 0, "ERROR_MESSAGE" => "", "NAV_SRTING" => "", "NAV_RESULT" => null);
$rsTest = CTest::GetList(array("SORT" => "ASC"), array("COURSE_ID" => $arParams["COURSE_ID"], "ACTIVE" => "Y", "CHECK_PERMISSIONS" => $arParams["CHECK_PERMISSIONS"]));
CPageOption::SetOptionString("main", "nav_page_in_session", "N");
$rsTest->NavStart($arParams["TESTS_PER_PAGE"]);
$arResult["NAV_STRING"] = $rsTest->GetPageNavString(GetMessage("LEARNING_TESTS_NAV"));
$arResult["NAV_RESULT"] = $rsTest;
while ($arTest = $rsTest->GetNext()) {
    //Test URL
    $arTest["TEST_DETAIL_URL"] = CComponentEngine::MakePathFromTemplate($arParams["TEST_DETAIL_TEMPLATE"], array("TEST_ID" => $arTest["ID"], "COURSE_ID" => $arTest["COURSE_ID"]));
    if ($_SERVER['REDIRECT_STATUS'] == '404' || isset($_REQUEST["SEF_APPLICATION_CUR_PAGE_URL"])) {
        $arTest["TEST_DETAIL_URL"] = "/bitrix/urlrewrite.php?SEF_APPLICATION_CUR_PAGE_URL=" . urlencode($arTest["TEST_DETAIL_URL"]);
    }
    //Unfinished attempt exists?
    $arTest["ATTEMPT"] = false;
    if ($USER->IsAuthorized()) {
        $rsAttempt = CTestAttempt::GetList(array(), array("TEST_ID" => $arTest["ID"], "STATUS" => "B", "STUDENT_ID" => intval($USER->GetID())));
        $arTest["ATTEMPT"] = $rsAttempt->GetNext();
Beispiel #10
0
 protected function _MakeItems($TITLE, $TYPE, $RES_ID, $PARENT_ID)
 {
     global $APPLICATION;
     if ($PARENT_ID === 0) {
         $linkToParentLessonId = CCourse::CourseGetLinkedLesson($this->COURSE_ID);
     } else {
         $linkToParentLessonId = (int) $PARENT_ID;
     }
     $createUnilesson = false;
     if ($TYPE == "LES") {
         $arFields = array('NAME' => $TITLE);
         $createUnilesson = true;
     } elseif ($TYPE == "CHA") {
         $arFields = array('NAME' => $TITLE);
         $createUnilesson = true;
     } elseif ($TYPE == "QUE") {
         $arFields = array("NAME" => $TITLE, "LESSON_ID" => $linkToParentLessonId);
         $cl = new CLQuestion();
     } elseif ($TYPE == "TES") {
         $arFields = array("NAME" => $TITLE, "COURSE_ID" => $this->COURSE_ID);
         $cl = new CTest();
     } elseif ($TYPE === 'TMK') {
         $arFields = array();
         $cl = new CLTestMark();
     } else {
         return $PARENT_ID;
     }
     $r = new CDataXML();
     if (!$r->Load($this->package_dir . "/" . strtolower($RES_ID) . ".xml")) {
         $r = false;
     }
     if ($r !== false) {
         if ($TYPE == "QUE") {
             if (($data = $r->SelectNodes("/questestinterop/item/presentation/")) && ($resp = $r->SelectNodes("/questestinterop/item/resprocessing/"))) {
                 $arQ = array();
                 $arData = $data->__toArray();
                 $arResp = $resp->__toArray();
                 if (is_set($arData["#"]["material"][0]["#"], "mattext")) {
                     $arQ["NAME"] = $arData["#"]["material"][0]["#"]["mattext"][0]["#"];
                 }
                 if (is_set($arData["#"]["material"][0]["#"], "matimage")) {
                     $imageDescription = '';
                     if (is_set($arData["#"]["material"][0]["#"], 'image_description')) {
                         $imageDescription = $arData["#"]["material"][0]["#"]['image_description'][0]['#'];
                     }
                     $arQ["FILE_ID"] = array("MODULE_ID" => "learning", "name" => basename($arData["#"]["material"][0]["#"]["matimage"][0]["@"]["uri"]), "tmp_name" => $this->package_dir . "/" . $arData["#"]["material"][0]["#"]["matimage"][0]["@"]["uri"], "size" => @filesize($this->package_dir . "/" . $arData["#"]["material"][0]["#"]["matimage"][0]["@"]["uri"]), "type" => $arData["#"]["material"][0]["#"]["matimage"][0]["@"]["imagtype"], 'description' => $imageDescription);
                 }
                 if (is_set($arData["#"]["response_lid"][0]["@"], "rcardinality")) {
                     switch ($arData["#"]["response_lid"][0]["@"]["rcardinality"]) {
                         case "Multiple":
                             $arQ["QUESTION_TYPE"] = 'M';
                             break;
                         case "Text":
                             $arQ["QUESTION_TYPE"] = 'T';
                             break;
                         case "Sort":
                             $arQ["QUESTION_TYPE"] = 'R';
                             break;
                         default:
                             $arQ["QUESTION_TYPE"] = 'S';
                             break;
                     }
                 }
                 if (is_set($arResp["#"]["respcondition"][0]["#"], "setvar")) {
                     $arQ["POINT"] = $arResp["#"]["respcondition"][0]["#"]["setvar"][0]['#'];
                 }
                 //Additional
                 if ($bx = $r->SelectNodes("/questestinterop/item/bitrix/")) {
                     $arQ = array_merge($arQ, $this->_MakeFields($bx->__toArray(), $TYPE));
                     unset($bx);
                 }
                 $arFields = array_merge($arFields, $arQ);
                 $cl = new CLQuestion();
                 $ID = $cl->Add($arFields);
                 if ($ID > 0) {
                     $PARENT_ID = $ID;
                     $arCorrect = array();
                     if (is_set($arResp["#"]["respcondition"][0]["#"], "conditionvar") && is_set($arResp["#"]["respcondition"][0]["#"]["conditionvar"][0]["#"], "varequal")) {
                         foreach ($arResp["#"]["respcondition"][0]["#"]["conditionvar"][0]["#"]["varequal"] as $ar) {
                             $arCorrect[] = $ar["#"];
                         }
                     }
                     if (is_set($arData["#"]["response_lid"][0]["#"], "render_choice") && is_set($arData["#"]["response_lid"][0]["#"]["render_choice"][0]["#"], "response_label")) {
                         $i = 0;
                         foreach ($arData["#"]["response_lid"][0]["#"]["render_choice"][0]["#"]["response_label"] as $ar) {
                             $i += 10;
                             $cl = new CLAnswer();
                             $arFields = array("QUESTION_ID" => $PARENT_ID, "SORT" => $i, "CORRECT" => in_array($ar["@"]["ident"], $arCorrect) ? "Y" : "N", "ANSWER" => $ar["#"]["material"][0]["#"]["mattext"][0]["#"]);
                             $AswerID = $cl->Add($arFields);
                             $res = $AswerID > 0;
                             if (!$res) {
                                 if ($e = $APPLICATION->GetException()) {
                                     $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString());
                                 }
                             }
                         }
                     }
                 } else {
                     if ($e = $APPLICATION->GetException()) {
                         $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString());
                     }
                 }
                 unset($cl);
                 unset($data);
                 unset($arQ);
                 unset($resp);
                 unset($arData);
                 unset($arResp);
                 return $PARENT_ID;
             }
         } else {
             if ($data = $r->SelectNodes("/content/")) {
                 $ar = $data->__toArray();
                 $arFields = array_merge($arFields, $this->_MakeFields($ar, $TYPE));
                 if ($TYPE === 'TMK') {
                     $arFields['TEST_ID'] = (int) $PARENT_ID;
                 }
                 if (is_set($arFields, "COMPLETED_SCORE") && intval($arFields["COMPLETED_SCORE"]) <= 0) {
                     unset($arFields["COMPLETED_SCORE"]);
                 }
                 if (is_set($arFields, "PREVIOUS_TEST_ID") && intval($arFields["PREVIOUS_TEST_ID"]) <= 0 || !CTest::GetByID($arFields["PREVIOUS_TEST_ID"])->Fetch()) {
                     unset($arFields["PREVIOUS_TEST_ID"], $arFields["PREVIOUS_TEST_SCORE"]);
                 }
             }
         }
     }
     if ($createUnilesson === false) {
         $ID = $cl->Add($arFields);
         unset($cl);
     } else {
         $bProhibitPublish = false;
         // properties (in context of parent) by default
         $arProperties = array('SORT' => 500);
         // Lesson's sort order in context of parent
         if (isset($arFields['EDGE_SORT'])) {
             $arFields['SORT'] = (int) $arFields['EDGE_SORT'];
             unset($arFields['EDGE_SORT']);
         }
         if (isset($arFields['SORT'])) {
             $arProperties['SORT'] = (int) $arFields['SORT'];
             // Lessons doesn't have more SORT field
             unset($arFields['SORT']);
         }
         if (isset($arFields['META_PUBLISH_PROHIBITED'])) {
             if ($arFields['META_PUBLISH_PROHIBITED'] === 'Y') {
                 $bProhibitPublish = true;
             }
             unset($arFields['META_PUBLISH_PROHIBITED']);
         }
         // unset fields, that are absent in unilesson
         $arUnilessonFields = $arFields;
         $arFieldsNames = array_keys($arUnilessonFields);
         foreach ($arFieldsNames as $fieldName) {
             if (!in_array(strtoupper($fieldName), $this->arLessonWritableFields)) {
                 unset($arUnilessonFields[$fieldName]);
             }
         }
         $ID = CLearnLesson::Add($arUnilessonFields, false, $linkToParentLessonId, $arProperties);
         if ($bProhibitPublish && $ID > 0) {
             CLearnLesson::PublishProhibitionSetTo($ID, $linkToParentLessonId, $bProhibitPublish);
         }
     }
     if ($ID > 0) {
         return $ID;
     } else {
         if ($e = $APPLICATION->GetException()) {
             $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString());
         }
     }
 }
Beispiel #11
0
 function GetList($arOrder = array(), $arFilter = array())
 {
     global $DB, $USER;
     $arSqlSearch = CLTestMark::GetFilter($arFilter);
     $strSqlSearch = "";
     for ($i = 0; $i < count($arSqlSearch); $i++) {
         if (strlen($arSqlSearch[$i]) > 0) {
             $strSqlSearch .= " AND " . $arSqlSearch[$i] . " ";
         }
     }
     $strSql = "SELECT TM.* " . "FROM b_learn_test_mark TM " . "WHERE 1=1 " . $strSqlSearch;
     if (!is_array($arOrder)) {
         $arOrder = array();
     }
     foreach ($arOrder as $by => $order) {
         $by = strtolower($by);
         $order = strtolower($order);
         if ($order != "asc") {
             $order = "desc";
         }
         if ($by == "id") {
             $arSqlOrder[] = " TM.ID " . $order . " ";
         } elseif ($by == "mark") {
             $arSqlOrder[] = " TM.MARK " . $order . " ";
         } elseif ($by == "score") {
             $arSqlOrder[] = " TM.SCORE " . $order . " ";
         } elseif ($by == "rand") {
             $arSqlOrder[] = CTest::GetRandFunction();
         } else {
             $arSqlOrder[] = " TM.ID " . $order . " ";
             $by = "id";
         }
     }
     $strSqlOrder = "";
     DelDuplicateSort($arSqlOrder);
     for ($i = 0; $i < count($arSqlOrder); $i++) {
         if ($i == 0) {
             $strSqlOrder = " ORDER BY ";
         } else {
             $strSqlOrder .= ",";
         }
         $strSqlOrder .= $arSqlOrder[$i];
     }
     $strSql .= $strSqlOrder;
     //echo $strSql;
     return $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
 }
Beispiel #12
0
 /**
  * <p>Возвращает список вопросов плана тестирования по фильтру <b>arFilter</b>, отсортированный в порядке <b>arOrder</b>.</p>
  *
  *
  * @param array $arrayarOrder = Array("ID"=>"DESC") Массив для сортировки результата. Массив вида <i>array("поле
  * сортировки"=&gt;"направление сортировки" [, ...])</i>.<br>Поле для
  * сортировки может принимать значения: <ul> <li> <b>ID</b> - идентификатор
  * вопроса в плане тестирования; </li> <li> <b>ATTEMPT_ID</b> - идентификатор
  * попытки; </li> <li> <b>QUESTION_ID</b> - идентификатор вопроса; </li> <li> <b>POINT</b> -
  * количество баллов; </li> <li> <b>ANSWERED</b> - вопрос отвечен (Y|N); </li> <li>
  * <b>CORRECT</b> - вопрос правильно отвечен (Y|N); </li> <li> <b>QUESTION_NAME</b> -
  * название вопроса; </li> <li> <b>RAND</b> - случайный порядок. </li>
  * </ul>Направление сортировки может принимать значения: <ul> <li> <b>asc</b> -
  * по возрастанию; </li> <li> <b>desc</b> - по убыванию; </li> </ul>Необязательный.
  * По умолчанию сортируется по убыванию идентификатора вопроса в
  * плане тестирования.
  *
  * @param array $arrayarFilter = Array() Массив вида <i>array("фильтруемое поле"=&gt;"значение фильтра" [, ...])</i>.
  * Фильтруемое поле может принимать значения: <ul> <li> <b>ID</b> -
  * идентификатор вопроса в плане тестирования; </li> <li> <b>ATTEMPT_ID</b> -
  * идентификатор попытки; </li> <li> <b>QUESTION_ID</b> - идентификатор вопроса;
  * </li> <li> <b>POINT</b> - количество баллов; </li> <li> <b>RESPONSE</b> - ответ учащегося
  * (можно искать по шаблону [%_]); </li> <li> <b>QUESTION_NAME</b> - название вопроса
  * (можно искать по шаблону [%_]); </li> <li> <b>ANSWERED</b> - вопрос отвечен (Y|N);
  * </li> <li> <b>CORRECT</b> - вопрос правильно отвечен (Y|N). </li> </ul>Перед
  * названием фильтруемого поля может указать тип фильтрации: <ul> <li>"!"
  * - не равно </li> <li>"&lt;" - меньше </li> <li>"&lt;=" - меньше либо равно </li> <li>"&gt;"
  * - больше </li> <li>"&gt;=" - больше либо равно </li> </ul> <br>"<i>значения
  * фильтра</i>" - одиночное значение или массив.<br><br>Необязательный. По
  * умолчанию записи не фильтруются.
  *
  * @return CDBResult <p>Возвращается объект <a
  * href="http://dev.1c-bitrix.ru/api_help/main/reference/cdbresult/index.php">CDBResult</a>.</p> </h
  *
  * <h4>Example</h4> 
  * <pre>
  * &lt;?
  * if (CModule::IncludeModule("learning"))
  * {
  *     $ATTEMPT_ID = 590;
  *     $res = CTestResult::GetList(
  *         Array("ID" =&gt; "ASC"), 
  *         Array("ANSWERED" =&gt; "N", "ATTEMPT_ID" =&gt; $ATTEMPT_ID)
  *     );
  * 
  *     while ($arQuestionPlan = $res-&gt;GetNext())
  *     {
  *         echo "Question ID: ".$arQuestionPlan["QUESTION_ID"].<br>             "; Correct answer: ".$arQuestionPlan["CORRECT"].<br>             "; Question name:".$arQuestionPlan["QUESTION_NAME"]."&lt;b
  * </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="index.php">CTestResult</a>::<a href="getbyid.php">GetByID</a> </li> <li><a
  * href="../../fields.php#test_result">Поля плана тестирования</a></li> </ul> <a name="examples"></a>
  *
  *
  * @static
  * @link http://dev.1c-bitrix.ru/api_help/learning/classes/ctestresult/getlist.php
  * @author Bitrix
  */
 public static function GetList($arOrder = array(), $arFilter = array(), $arNavParams = array())
 {
     global $DB, $USER, $APPLICATION;
     if (!is_array($arFilter)) {
         $arFilter = array();
     }
     $oPermParser = new CLearnParsePermissionsFromFilter($arFilter);
     $arSqlSearch = CTestResult::GetFilter($arFilter);
     // Remove empty strings from array
     $arSqlSearch = array_filter($arSqlSearch);
     if ($oPermParser->IsNeedCheckPerm()) {
         $arSqlSearch[] = " L.ID IN (" . $oPermParser->SQLForAccessibleLessons() . ") ";
     }
     $strSqlSearch = ' ';
     if (!empty($arSqlSearch)) {
         $strSqlSearch = ' WHERE ';
         $strSqlSearch .= implode(' AND ', $arSqlSearch);
     }
     $strSqlFrom = "FROM b_learn_test_result TR \n\t\t\tINNER JOIN b_learn_question Q ON TR.QUESTION_ID = Q.ID \n\t\t\tINNER JOIN b_learn_lesson L ON Q.LESSON_ID = L.ID " . $strSqlSearch;
     $strSql = "SELECT TR.*, Q.QUESTION_TYPE, Q.NAME as QUESTION_NAME, \n\t\t\tQ.POINT as QUESTION_POINT, Q.LESSON_ID " . $strSqlFrom;
     if (!is_array($arOrder)) {
         $arOrder = array();
     }
     foreach ($arOrder as $by => $order) {
         $by = strtolower($by);
         $order = strtolower($order);
         if ($order != "asc") {
             $order = "desc";
         }
         if ($by == "id") {
             $arSqlOrder[] = " TR.ID " . $order . " ";
         } elseif ($by == "attempt_id") {
             $arSqlOrder[] = " TR.ATTEMPT_ID " . $order . " ";
         } elseif ($by == "question_id") {
             $arSqlOrder[] = " TR.QUESTION_ID " . $order . " ";
         } elseif ($by == "point") {
             $arSqlOrder[] = " TR.POINT " . $order . " ";
         } elseif ($by == "correct") {
             $arSqlOrder[] = " TR.CORRECT " . $order . " ";
         } elseif ($by == "answered") {
             $arSqlOrder[] = " TR.ANSWERED " . $order . " ";
         } elseif ($by == "question_name") {
             $arSqlOrder[] = " QUESTION_NAME " . $order . " ";
         } elseif ($by == "rand") {
             $arSqlOrder[] = CTest::GetRandFunction();
         } else {
             $arSqlOrder[] = " TR.ID " . $order . " ";
             $by = "id";
         }
     }
     $strSqlOrder = "";
     DelDuplicateSort($arSqlOrder);
     $arSqlOrderCnt = count($arSqlOrder);
     for ($i = 0; $i < $arSqlOrderCnt; $i++) {
         if ($i == 0) {
             $strSqlOrder = " ORDER BY ";
         } else {
             $strSqlOrder .= ",";
         }
         $strSqlOrder .= $arSqlOrder[$i];
     }
     $strSql .= $strSqlOrder;
     if (is_array($arNavParams) && !empty($arNavParams)) {
         if (isset($arNavParams['nTopCount']) && (int) $arNavParams['nTopCount'] > 0) {
             $strSql = $DB->TopSql($strSql, (int) $arNavParams['nTopCount']);
             $res = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
         } else {
             $res_cnt = $DB->Query("SELECT COUNT(TR.ID) as C " . $strSqlFrom);
             $res_cnt = $res_cnt->fetch();
             $res = new CDBResult();
             $res->NavQuery($strSql, $res_cnt['C'], $arNavParams);
         }
     } else {
         $res = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
     }
     return $res;
 }
Beispiel #13
0
        $rsPrevTest = CTest::GetList(array(), array("ID" => $arTest["PREVIOUS_TEST_ID"], 'CHECK_PERMISSIONS' => 'N'));
        if ($arPrevTest = $rsPrevTest->GetNext()) {
            if ($parent = $this->GetParent()) {
                $testUrlTemplate = CComponentEngine::MakePathFromTemplate($parent->arResult["URL_TEMPLATES"]["test"], array("TEST_ID" => $arPrevTest["ID"], "COURSE_ID" => $arPrevTest["COURSE_ID"]));
                $arTest["PREVIOUS_TEST_LINK"] = "<a href=\"" . $testUrlTemplate . "\">" . $arPrevTest["NAME"] . "</a>";
            }
        }
    }
}
if ($USER->GetID()) {
    $arTest["ATTEMPT_LIMIT"] += CGradeBook::GetExtraAttempts($USER->GetID(), $arParams["TEST_ID"]);
}
$oAccess = CLearnAccess::GetInstance($USER->GetID());
$isRelativelyHighAccessLevel = $oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_CREATE | CLearnAccess::OP_LESSON_READ | CLearnAccess::OP_LESSON_WRITE | CLearnAccess::OP_LESSON_REMOVE);
$bCheckPerm = !$isRelativelyHighAccessLevel && !$USER->IsAdmin();
if ($bCheckPerm && $arTest["PREVIOUS_TEST_ID"] > 0 && $arTest["PREVIOUS_TEST_SCORE"] > 0 && !CTest::isPrevPassed($arTest["PREVIOUS_TEST_ID"], $arTest["PREVIOUS_TEST_SCORE"])) {
    if ($arTest["PREVIOUS_TEST_LINK"]) {
        $errors[] = str_replace("#TEST_LINK#", "\"" . $arTest["PREVIOUS_TEST_LINK"] . "\"", GetMessage("LEARNING_TEST_DENIED_PREVIOUS"));
    }
}
//Session variables
$userID = $USER->GetID() ? $USER->GetID() : 0;
$sessAttemptID =& $_SESSION["LEARN_" . $arParams["TEST_ID"] . "_ATTEMPT_ID_" . $userID];
$sessAttemptFinished =& $_SESSION["LEARN_" . $arParams["TEST_ID"] . "_FINISHED_" . $userID];
$sessAttemptError =& $_SESSION["LEARN_" . $arParams["TEST_ID"] . "_ERROR_" . $userID];
$sessAttempt =& $_SESSION["LEARN_" . $arParams["TEST_ID"] . "_COMPLETED_" . $userID];
$sessIncorrectMessage =& $_SESSION["LEARN_" . $arParams["TEST_ID"] . "_INCORRECT_MESSAGE_" . $userID];
//Page url template
$currentPage = GetPagePath(false, false);
$queryString = htmlspecialcharsbx(DeleteParam(array($arParams["PAGE_NUMBER_VARIABLE"], "SEF_APPLICATION_CUR_PAGE_URL")));
$pageTemplate = $queryString == "" ? $currentPage . "?" . $arParams["PAGE_NUMBER_VARIABLE"] . "=#PAGE_ID#" : $currentPage . "?" . $queryString . "&amp;" . $arParams["PAGE_NUMBER_VARIABLE"] . "=#PAGE_ID#";
Beispiel #14
0
//Set Title
$arParams["SET_TITLE"] = $arParams["SET_TITLE"] == "N" ? "N" : "Y";
if ($arParams["SET_TITLE"] == "Y") {
    $APPLICATION->SetTitle(GetMessage("LEARNING_PROFILE_TITLE"));
}
$currentPage = GetPagePath(false, false);
$queryString = htmlspecialcharsbx(DeleteParam(array($arParams["TEST_ID_VARIABLE"])));
$arResult = array("RECORDS" => array(), "ATTEMPTS" => array(), "CURRENT_PAGE" => $currentPage . ($queryString == "" ? "" : "?") . $queryString);
//GradeBook
$rsGradebook = CGradeBook::GetList(array("ID" => "DESC"), array("STUDENT_ID" => intval($USER->GetID()), "SITE_ID" => LANG, "TEST_ID" => array_key_exists($arParams["TEST_ID_VARIABLE"], $_REQUEST) ? intval($_REQUEST[$arParams["TEST_ID_VARIABLE"]]) : ""));
// Collection of tests' ids
$arTestsIds = array();
while ($arGradebook = $rsGradebook->GetNext()) {
    //Test Url
    $arGradebook["TEST_DETAIL_URL"] = CComponentEngine::MakePathFromTemplate($arParams["TEST_DETAIL_TEMPLATE"], array("TEST_ID" => $arGradebook["TEST_ID"], "COURSE_ID" => $arGradebook["COURSE_ID"]));
    $rsTest = CTest::GetByID($arGradebook["TEST_ID"]);
    $arTest = $rsTest->Fetch();
    $arGradebook['APPROVED'] = $arTest['APPROVED'];
    //Course Url
    $arGradebook["COURSE_DETAIL_URL"] = CComponentEngine::MakePathFromTemplate($arParams["COURSE_DETAIL_TEMPLATE"], array("COURSE_ID" => $arGradebook["COURSE_ID"]));
    $arGradebook["ATTEMPT_DETAIL_URL"] = $arResult["CURRENT_PAGE"] . ($queryString == "" ? "?" : "&") . $arParams["TEST_ID_VARIABLE"] . "=" . $arGradebook["TEST_ID"];
    $arResult["RECORDS"][] = $arGradebook;
    // collect tests' ids
    if (!in_array($arGradebook['TEST_ID'], $arTestsIds)) {
        $arTestsIds[] = $arGradebook['TEST_ID'];
    }
}
// Add info about last tests' attempts for each test
$arResult['LAST_TEST_INFO'] = array();
foreach ($arTestsIds as $key => $testId) {
    $arAttempt = false;
Beispiel #15
0
    if (isset($arTest['DESCRIPTION'])) {
        $arTest['DESCRIPTION'] = CLearnHelper::PatchLessonContentLinks($arTest['DESCRIPTION'], $arParams['COURSE_ID']);
    }
    //Test URL
    $arTest["TEST_DETAIL_URL"] = CComponentEngine::MakePathFromTemplate($arParams["TEST_DETAIL_TEMPLATE"], array("TEST_ID" => $arTest["ID"], "COURSE_ID" => $arTest["COURSE_ID"]));
    if ($_SERVER['REDIRECT_STATUS'] == '404' || isset($_REQUEST["SEF_APPLICATION_CUR_PAGE_URL"])) {
        $arTest["TEST_DETAIL_URL"] = "/bitrix/urlrewrite.php?SEF_APPLICATION_CUR_PAGE_URL=" . urlencode($arTest["TEST_DETAIL_URL"]);
    }
    //Unfinished attempt exists?
    $arTest["ATTEMPT"] = false;
    if ($USER->IsAuthorized()) {
        $rsAttempt = CTestAttempt::GetList(array(), array("TEST_ID" => $arTest["ID"], "STATUS" => "B", "STUDENT_ID" => intval($USER->GetID()), "CHECK_PERMISSIONS" => $arParams["CHECK_PERMISSIONS"]));
        $arTest["ATTEMPT"] = $rsAttempt->GetNext();
    }
    if ($arTest["PREVIOUS_TEST_ID"] > 0 && $arTest["PREVIOUS_TEST_SCORE"] > 0) {
        $rsPrevTest = CTest::GetList(array(), array("ID" => $arTest["PREVIOUS_TEST_ID"], 'CHECK_PERMISSIONS' => 'N'));
        if ($arPrevTest = $rsPrevTest->GetNext()) {
            if ($parent = $this->GetParent()) {
                $testUrlTemplate = CComponentEngine::MakePathFromTemplate($parent->arResult["URL_TEMPLATES"]["test"], array("TEST_ID" => $arPrevTest["ID"], "COURSE_ID" => $arPrevTest["COURSE_ID"]));
                $arTest["PREVIOUS_TEST_LINK"] = "<a href=\"" . $testUrlTemplate . "\">" . $arPrevTest["NAME"] . "</a>";
            }
        }
    }
    $arResult["TESTS"][] = $arTest;
}
$arResult["TESTS_COUNT"] = count($arResult["TESTS"]);
if ($arResult["TESTS_COUNT"] <= 0) {
    $arResult["ERROR_MESSAGE"] = GetMessage("LEARNING_BAD_TEST_LIST");
}
unset($rsTest);
unset($arTest);
Beispiel #16
0
 public static function GetList($arOrder = array(), $arFilter = array(), $arNavParams = array())
 {
     global $DB, $USER;
     if (!is_array($arFilter)) {
         $arFilter = array();
     }
     $oPermParser = new CLearnParsePermissionsFromFilter($arFilter);
     $arSqlSearch = CTest::GetFilter($arFilter);
     // Remove empty strings from array
     $arSqlSearch = array_filter($arSqlSearch);
     if ($oPermParser->IsNeedCheckPerm()) {
         $arSqlSearch[] = " C.LINKED_LESSON_ID IN (" . $oPermParser->SQLForAccessibleLessons() . ") ";
     }
     $strSqlSearch = ' ';
     if (!empty($arSqlSearch)) {
         $strSqlSearch = ' WHERE ';
         $strSqlSearch .= implode(' AND ', $arSqlSearch);
     }
     $strSqlFrom = "FROM b_learn_test LT " . "INNER JOIN b_learn_course C ON LT.COURSE_ID = C.ID " . $strSqlSearch;
     $strSql = "SELECT LT.ID, LT.COURSE_ID, LT.SORT, LT.ACTIVE, LT.NAME, \n\t\t\t\tLT.DESCRIPTION, LT.DESCRIPTION_TYPE, LT.ATTEMPT_LIMIT, \n\t\t\t\tLT.TIME_LIMIT, LT.COMPLETED_SCORE, LT.QUESTIONS_FROM, \n\t\t\t\tLT.QUESTIONS_FROM_ID, LT.QUESTIONS_AMOUNT, LT.RANDOM_QUESTIONS, \n\t\t\t\tLT.RANDOM_ANSWERS, LT.APPROVED, LT.INCLUDE_SELF_TEST, \n\t\t\t\tLT.PASSAGE_TYPE, LT.PREVIOUS_TEST_ID, LT.PREVIOUS_TEST_SCORE, \n\t\t\t\tLT.INCORRECT_CONTROL, LT.CURRENT_INDICATION, \n\t\t\t\tLT.FINAL_INDICATION, LT.MIN_TIME_BETWEEN_ATTEMPTS, \n\t\t\t\tLT.SHOW_ERRORS, LT.NEXT_QUESTION_ON_ERROR, " . $DB->DateToCharFunction("LT.TIMESTAMP_X") . " as TIMESTAMP_X " . $strSqlFrom;
     if (!is_array($arOrder)) {
         $arOrder = array();
     }
     foreach ($arOrder as $by => $order) {
         $by = strtolower($by);
         $order = strtolower($order);
         if ($order != "asc") {
             $order = "desc";
         }
         if ($by == "id") {
             $arSqlOrder[] = " LT.ID " . $order . " ";
         } elseif ($by == "name") {
             $arSqlOrder[] = " LT.NAME " . $order . " ";
         } elseif ($by == "active") {
             $arSqlOrder[] = " LT.ACTIVE " . $order . " ";
         } elseif ($by == "sort") {
             $arSqlOrder[] = " LT.SORT " . $order . " ";
         } else {
             $arSqlOrder[] = " LT.TIMESTAMP_X " . $order . " ";
             $by = "timestamp_x";
         }
     }
     $strSqlOrder = "";
     DelDuplicateSort($arSqlOrder);
     if (!empty($arSqlOrder)) {
         $strSqlOrder .= ' ORDER BY ' . implode(', ', $arSqlOrder) . ' ';
     }
     $strSql .= $strSqlOrder;
     if (is_array($arNavParams) && !empty($arNavParams)) {
         if (isset($arNavParams['nTopCount']) && (int) $arNavParams['nTopCount'] > 0) {
             $strSql = $DB->TopSql($strSql, (int) $arNavParams['nTopCount']);
             $res = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
         } else {
             $res_cnt = $DB->Query("SELECT COUNT(LT.ID) as C " . $strSqlFrom);
             $res_cnt = $res_cnt->fetch();
             $res = new CDBResult();
             $res->NavQuery($strSql, $res_cnt['C'], $arNavParams);
         }
     } else {
         $res = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
     }
     return $res;
 }
Beispiel #17
0
        }
        $itemURL .= 'LESSON_PATH=' . $arContent['~#LESSON_PATH'];
    }
    $arContent["URL"] = htmlspecialcharsbx($itemURL);
    if ($arContent["SELECTED"]) {
        $lessonCurrent = $lessonCount;
    }
    $arResult["ITEMS"][] = $arContent;
}
//Page Properties
$APPLICATION->SetPageProperty("learning_course_name", $arResult["COURSE"]["NAME"]);
$APPLICATION->SetPageProperty("learning_lesson_count", $lessonCount);
$APPLICATION->SetPageProperty("learning_lesson_current", $lessonCurrent);
//Test list item
$url = CComponentEngine::MakePathFromTemplate($arParams["TESTS_LIST_TEMPLATE"], array("COURSE_ID" => $arParams["COURSE_ID"]));
$testsCount = CTest::GetCount(array("COURSE_ID" => $arParams["COURSE_ID"], "ACTIVE" => "Y", 'CHECK_PERMISSIONS' => 'N'));
if ($testsCount > 0) {
    $arResult['ITEMS'][] = array('NAME' => GetMessage('LEARNING_TEST_LIST') . '&nbsp;(' . $testsCount . ')', 'URL' => $url, 'TYPE' => 'TL', 'SELECTED' => $parent->arResult['VARIABLES']['TEST_LIST'] == 'Y', 'DEPTH_LEVEL' => 1);
}
unset($arContent);
unset($rsContent);
//Open chapters from Cookies
$arOpenChapters = array();
if (array_key_exists("LEARN_MENU_" . $arParams["COURSE_ID"], $_COOKIE)) {
    $arOpenChapters = explode(",", $_COOKIE["LEARN_MENU_" . $arParams["COURSE_ID"]]);
}
//Chapter open if child selected
for ($itemIndex = 0, $size = count($arResult["ITEMS"]); $itemIndex < $size; $itemIndex++) {
    if ($arResult["ITEMS"][$itemIndex]["TYPE"] != "CH" || $arResult["ITEMS"][$itemIndex]["SELECTED"] === true) {
        continue;
    }
Beispiel #18
0
        $itemURL .= 'LESSON_PATH=' . $arContent['~#LESSON_PATH'];
    }
    $arContent["URL"] = htmlspecialcharsbx($itemURL);
    if ($arContent["SELECTED"]) {
        $lessonCurrent = $lessonCount;
    }
    $arResult["ITEMS"][] = $arContent;
}
//Page Properties
$APPLICATION->SetPageProperty("learning_course_name", $arResult["COURSE"]["NAME"]);
$APPLICATION->SetPageProperty("learning_lesson_count", $lessonCount);
$APPLICATION->SetPageProperty("learning_lesson_current", $lessonCurrent);
//Test list item
$url = CComponentEngine::MakePathFromTemplate($arParams["TESTS_LIST_TEMPLATE"], array("COURSE_ID" => $arParams["COURSE_ID"]));
$arSelectedItems = array($url);
$rsTest = CTest::GetList(array(), array("COURSE_ID" => $arParams["COURSE_ID"], "ACTIVE" => "Y", 'CHECK_PERMISSIONS' => 'N'));
$rsTest->NavStart(100);
while ($arTest = $rsTest->Fetch()) {
    $arSelectedItems[] = CComponentEngine::MakePathFromTemplate($arParams["TEST_DETAIL_TEMPLATE"], array("TEST_ID" => $arTest["ID"], "COURSE_ID" => $arParams["COURSE_ID"]));
}
if ($rsTest->SelectedRowsCount() > 0) {
    $arResult["ITEMS"][] = array("NAME" => GetMessage('LEARNING_TEST_LIST') . "&nbsp;(" . $rsTest->SelectedRowsCount() . ")", "URL" => $url, "TYPE" => "TL", "SELECTED" => $parent->arResult["VARIABLES"]["TEST_LIST"] == "Y", "DEPTH_LEVEL" => 1);
}
unset($arContent);
unset($rsContent);
//Open chapters from Cookies
$arOpenChapters = array();
if (array_key_exists("LEARN_MENU_" . $arParams["COURSE_ID"], $_COOKIE)) {
    $arOpenChapters = explode(",", $_COOKIE["LEARN_MENU_" . $arParams["COURSE_ID"]]);
}
//Chapter open if child selected
Beispiel #19
0
$str_FINAL_RESPONSE = "Y";
$str_PASSAGE_TYPE = "0";
$str_PREVIOUS_TEST_ID = "0";
$str_PREVIOUS_TEST_SCORE = "95";
$str_INCORRECT_CONTROL = "N";
$str_CURRENT_INDICATION_PERCENT = "N";
$str_CURRENT_INDICATION_MARK = "N";
$str_CURRENT_INDICATION = "N";
$str_FINAL_INDICATION_CORRECT_COUNT = "N";
$str_FINAL_INDICATION_SCORE = "N";
$str_FINAL_INDICATION_MARK = "N";
$str_FINAL_INDICATION_MESSAGE = "N";
$str_FINAL_INDICATION = "N";
$str_SHOW_ERRORS = "N";
$str_NEXT_QUESTION_ON_ERROR = "Y";
$test = new CTest();
$res = $test->GetByID($ID);
if (!$res->ExtractFields("str_")) {
    $ID = 0;
} else {
    if ($str_CURRENT_INDICATION > 0) {
        $str_CURRENT_INDICATION_PERCENT = $str_CURRENT_INDICATION & 1 ? "Y" : "N";
        $str_CURRENT_INDICATION_MARK = ($str_CURRENT_INDICATION & 2) >> 1 ? "Y" : "N";
        $str_CURRENT_INDICATION = "Y";
    }
    if ($str_FINAL_INDICATION > 0) {
        $str_FINAL_INDICATION_CORRECT_COUNT = $str_FINAL_INDICATION & 1 ? "Y" : "N";
        $str_FINAL_INDICATION_SCORE = ($str_FINAL_INDICATION & 2) >> 1 ? "Y" : "N";
        $str_FINAL_INDICATION_MARK = ($str_FINAL_INDICATION & 4) >> 2 ? "Y" : "N";
        $str_FINAL_INDICATION_MESSAGE = ($str_FINAL_INDICATION & 8) >> 3 ? "Y" : "N";
        $str_FINAL_INDICATION = "Y";
Beispiel #20
0
	/**
	 * <p>Возвращает список вопросов плана тестирования по фильтру <b>arFilter</b>, отсортированный в порядке <b>arOrder</b>.</p>
	 *
	 *
	 *
	 *
	 * @param array $arrayarOrder = Array("ID"=>"DESC") Массив для сортировки результата. Массив вида <i>array("поле
	 * сортировки"=&gt;"направление сортировки" [, ...])</i>.<br>Поле для
	 * сортировки может принимать значения: <ul> <li> <b>ID</b> - идентификатор
	 * вопроса в плане тестирования; </li> <li> <b>ATTEMPT_ID</b> - идентификатор
	 * попытки; </li> <li> <b>QUESTION_ID</b> - идентификатор вопроса; </li> <li> <b>POINT</b> -
	 * количество баллов; </li> <li> <b>ANSWERED</b> - вопрос отвечен (Y|N); </li> <li>
	 * <b>CORRECT</b> - вопрос правильно отвечен (Y|N); </li> <li> <b>QUESTION_NAME</b> -
	 * название вопроса; </li> <li> <b>RAND</b> - случайный порядок. </li>
	 * </ul>Направление сортировки может принимать значения: <ul> <li> <b>asc</b> -
	 * по возрастанию; </li> <li> <b>desc</b> - по убыванию; </li> </ul>Необязательный.
	 * По умолчанию фильтруется по убыванию идентификатора вопроса в
	 * плане тестирования.
	 *
	 *
	 *
	 * @param array $arrayarFilter = Array() Массив вида <i>array("фильтруемое поле"=&gt;"значение фильтра" [, ...])</i>.
	 * Фильтруемое поле может принимать значения: <ul> <li> <b>ID</b> -
	 * идентификатор вопроса в плане тестирования; </li> <li> <b>ATTEMPT_ID</b> -
	 * идентификатор попытки; </li> <li> <b>QUESTION_ID</b> - идентификатор вопроса;
	 * </li> <li> <b>POINT</b> - количество баллов; </li> <li> <b>RESPONSE</b> - ответ учащегося
	 * (можно искать по шаблону [%_]); </li> <li> <b>QUESTION_NAME</b> - название вопроса
	 * (можно искать по шаблону [%_]); </li> <li> <b>ANSWERED</b> - вопрос отвечен (Y|N);
	 * </li> <li> <b>CORRECT</b> - вопрос правильно отвечен (Y|N). </li> </ul>Перед
	 * названием фильтруемого поля может указать тип фильтрации: <ul> <li>"!"
	 * - не равно </li> <li>"&lt;" - меньше </li> <li>"&lt;=" - меньше либо равно </li> <li>"&gt;"
	 * - больше </li> <li>"&gt;=" - больше либо равно </li> </ul> <br>"<i>значения
	 * фильтра</i>" - одиночное значение или массив.<br><br>Необязательный. По
	 * умолчанию записи не фильтруются.
	 *
	 *
	 *
	 * @return CDBResult <p>Возвращается объект <a
	 * href="http://dev.1c-bitrix.ru/api_help/main/reference/cdbresult/index.php">CDBResult</a>.</p>
	 *
	 *
	 * <h4>Example</h4> 
	 * <pre>
	 * &lt;?
	 * if (CModule::IncludeModule("learning"))
	 * {
	 *     $ATTEMPT_ID = 590;
	 *     $res = CTestResult::GetList(
	 *         Array("ID" =&gt; "ASC"), 
	 *         Array("ANSWERED" =&gt; "N", "ATTEMPT_ID" =&gt; $ATTEMPT_ID)
	 *     );
	 * 
	 *     while ($arQuestionPlan = $res-&gt;GetNext())
	 *     {
	 *         echo "Question ID: ".$arQuestionPlan["QUESTION_ID"].<br>             "; Correct answer: ".$arQuestionPlan["CORRECT"].<br>             "; Question name:".$arQuestionPlan["QUESTION_NAME"]."&lt;br&gt;";
	 *     }
	 * }
	 * ?&gt;
	 * </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="index.php">CTestResult</a>::<a href="getbyid.php">GetByID</a> </li> <li><a
	 * href="../../fields.php#test_result">Поля плана тестирования</a></li> </ul><a name="examples"></a>
	 *
	 *
	 * @static
	 * @link http://dev.1c-bitrix.ru/api_help/learning/classes/ctestresult/getlist.php
	 * @author Bitrix
	 */
	public static function GetList($arOrder=array(), $arFilter=array())
	{
		global $DB, $USER, $APPLICATION;

		if (!is_array($arFilter))
			$arFilter = Array();

		$oPermParser = new CLearnParsePermissionsFromFilter ($arFilter);
		$arSqlSearch = CTestResult::GetFilter($arFilter);

		$strSqlSearch = "";
		$arSqlSearchCnt = count($arSqlSearch);
		for($i=0; $i<$arSqlSearchCnt; $i++)
			if(strlen($arSqlSearch[$i])>0)
				$strSqlSearch .= " AND ".$arSqlSearch[$i]." ";

		$strSql =
		"SELECT TR.*, Q.QUESTION_TYPE, Q.NAME as QUESTION_NAME, Q.POINT as QUESTION_POINT, Q.LESSON_ID
		FROM b_learn_test_result TR 
		INNER JOIN b_learn_question Q ON TR.QUESTION_ID = Q.ID 
		INNER JOIN b_learn_lesson L ON Q.LESSON_ID = L.ID 
		WHERE 1=1 ";

		if ($oPermParser->IsNeedCheckPerm())
			$strSql .= " AND L.ID IN (" . $oPermParser->SQLForAccessibleLessons() . ") ";
		
		$strSql .= $strSqlSearch;

		/* was:
		$bCheckPerm = ($APPLICATION->GetUserRight("learning") < "W" && !$USER->IsAdmin() && $arFilter["CHECK_PERMISSIONS"] != "N");

		$strSql =
		"SELECT TR.*, Q.QUESTION_TYPE, Q.NAME as QUESTION_NAME, Q.POINT as QUESTION_POINT, Q.LESSON_ID
		FROM b_learn_test_result TR 
		INNER JOIN b_learn_question Q ON TR.QUESTION_ID = Q.ID 
		INNER JOIN b_learn_lesson L ON Q.LESSON_ID = L.ID "
		"INNER JOIN b_learn_course C ON L.COURSE_ID = C.ID ".
		. "WHERE 1=1 "
		. ($bCheckPerm ?
		"AND EXISTS (SELECT * FROM b_learn_course_permission CP WHERE ".
		"CP.USER_GROUP_ID IN (".$USER->GetGroups().") ".
		"AND CP.PERMISSION >= '".(strlen($arFilter["MIN_PERMISSION"])==1 ? $arFilter["MIN_PERMISSION"] : "R")."' ".
		"AND (CP.PERMISSION='X' OR C.ACTIVE='Y'))"
		:"")
		. $strSqlSearch;
		*/

		if (!is_array($arOrder))
			$arOrder = Array();

		foreach($arOrder as $by=>$order)
		{
			$by = strtolower($by);
			$order = strtolower($order);
			if ($order!="asc")
				$order = "desc";

			if ($by == "id") $arSqlOrder[] = " TR.ID ".$order." ";
			elseif ($by == "attempt_id") $arSqlOrder[] = " TR.ATTEMPT_ID ".$order." ";
			elseif ($by == "question_id") $arSqlOrder[] = " TR.QUESTION_ID ".$order." ";
			elseif ($by == "point") $arSqlOrder[] = " TR.POINT ".$order." ";
			elseif ($by == "correct") $arSqlOrder[] = " TR.CORRECT ".$order." ";
			elseif ($by == "answered") $arSqlOrder[] = " TR.ANSWERED ".$order." ";
			elseif ($by == "question_name") $arSqlOrder[] = " QUESTION_NAME ".$order." ";
			elseif ($by == "rand") $arSqlOrder[] = CTest::GetRandFunction();
			else
			{
				$arSqlOrder[] = " TR.ID ".$order." ";
				$by = "id";
			}
		}

		$strSqlOrder = "";
		DelDuplicateSort($arSqlOrder);
		$arSqlOrderCnt = count($arSqlOrder);
		for ($i=0; $i<$arSqlOrderCnt; $i++)
		{
			if($i==0)
				$strSqlOrder = " ORDER BY ";
			else
				$strSqlOrder .= ",";

			$strSqlOrder .= $arSqlOrder[$i];
		}

		$strSql .= $strSqlOrder;

		//echo $strSql;

		return $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
	}
" size="47"></td>
	</tr>

	<tr>
		<td><?php 
echo GetMessage("LEARNING_ADMIN_TEST");
?>
:</td>
		<td>
			<select name="filter_test_id">
				<option value=""><?php 
echo GetMessage("LEARNING_ALL");
?>
</option>
			<?php 
$l = CTest::GetList(array(), array());
while ($l->ExtractFields("l_")) {
    ?>
<option value="<?php 
    echo $l_ID;
    ?>
"<?php 
    if ($filter_test_id == $l_ID) {
        echo " selected";
    }
    ?>
><?php 
    echo $l_NAME;
    ?>
</option><?php 
}
Beispiel #22
0
 /**
  * WARNING: don't use this method, it's for internal use only
  * 
  * Convert course to non-course lesson (course will be removed,
  * but lesson will stay exists)
  * 
  * WARNING: this method terminates (by die()/exit()) current execution flow
  * when SQL server error occured. It's due to bug in CDatabase::Update() in main
  * module (version info:
  *    define("SM_VERSION","11.0.12");
  *    define("SM_VERSION_DATE","2012-02-21 17:00:00"); // YYYY-MM-DD HH:MI:SS
  * )
  *
  * @param int $courseId (returned by GetLinkedCourse($lessonId) )
  * 
  * @access private
  */
 protected static function CourseBecomeLesson($courseId)
 {
     global $DB;
     self::_EnsureArgsStrictlyCastableToIntegers($courseId);
     $linkedLessonId = CCourse::CourseGetLinkedLesson($courseId);
     if ($linkedLessonId === false) {
         return false;
     }
     // Check certificates (if exists => forbid removing course)
     $certificate = CCertification::GetList(array(), array("COURSE_ID" => $courseId, 'CHECK_PERMISSIONS' => 'N'));
     if ($certificate === false || $certificate->GetNext()) {
         return false;
     }
     // Remove tests
     $tests = CTest::GetList(array(), array("COURSE_ID" => $courseId));
     if ($tests === false) {
         return false;
     }
     while ($arTest = $tests->Fetch()) {
         if (!CTest::Delete($arTest["ID"])) {
             return false;
         }
     }
     // Remove all prohibitions for lessons in context of course to be removed
     // and remove prohibitions for course to be removed in context of all other courses
     self::PublishProhibitionPurge($linkedLessonId, self::PUBLISH_PROHIBITION_PURGE_ALL_LESSONS_IN_COURSE_CONTEXT | self::PUBLISH_PROHIBITION_PURGE_LESSON_IN_ALL_COURSE_CONTEXT);
     $rc = $DB->Query("DELETE FROM b_learn_course\n\t\t\tWHERE ID=" . (string) (int) $courseId, true);
     // reload cache of LINKED_LESSON_ID -> COURSE_ID
     self::GetCourseToLessonMap_ReloadCache();
     CLearnCacheOfLessonTreeComponent::MarkAsDirty();
     /**
      * This code will be useful after bug in CDatabase::Update()
      * and CDatabase::Insert() will be solved and $ignore_errors setted
      * to true in Insert()/Update() call above.
      */
     if ($rc === false) {
         throw new LearnException('EA_SQLERROR', LearnException::EXC_ERR_ALL_GIVEUP);
     }
     // If data not updated
     if ($rc === 0) {
         throw new LearnException('EA_OTHER: data not updated', LearnException::EXC_ERR_ALL_GIVEUP);
     }
 }
Beispiel #23
0
 function GetList($arOrder = array(), $arFilter = array())
 {
     global $DB, $USER;
     $arSqlSearch = CLAnswer::GetFilter($arFilter);
     $strSqlSearch = "";
     for ($i = 0; $i < count($arSqlSearch); $i++) {
         if (strlen($arSqlSearch[$i]) > 0) {
             $strSqlSearch .= " AND " . $arSqlSearch[$i] . " ";
         }
     }
     $strSql = "SELECT CA.*, CQ.ID AS QUESTION_ID, CQ.NAME AS QUESTION_NAME " . "FROM b_learn_answer CA " . "INNER JOIN b_learn_question CQ ON CA.QUESTION_ID = CQ.ID " . "WHERE 1=1 " . $strSqlSearch;
     if (!is_array($arOrder)) {
         $arOrder = array();
     }
     foreach ($arOrder as $by => $order) {
         $by = strtolower($by);
         $order = strtolower($order);
         if ($order != "asc") {
             $order = "desc";
         }
         if ($by == "id") {
             $arSqlOrder[] = " CA.ID " . $order . " ";
         } elseif ($by == "sort") {
             $arSqlOrder[] = " CA.SORT " . $order . " ";
         } elseif ($by == "correct") {
             $arSqlOrder[] = " CA.CORRECT " . $order . " ";
         } elseif ($by == "answer") {
             $arSqlOrder[] = " CA.ANSWER " . $order . " ";
         } elseif ($by == "rand") {
             $arSqlOrder[] = CTest::GetRandFunction();
         } else {
             $arSqlOrder[] = " CA.ID " . $order . " ";
             $by = "id";
         }
     }
     $strSqlOrder = "";
     DelDuplicateSort($arSqlOrder);
     for ($i = 0; $i < count($arSqlOrder); $i++) {
         if ($i == 0) {
             $strSqlOrder = " ORDER BY ";
         } else {
             $strSqlOrder .= ",";
         }
         $strSqlOrder .= $arSqlOrder[$i];
     }
     $strSql .= $strSqlOrder;
     //echo $strSql;
     return $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
 }
Beispiel #24
0
        }
        $ID = IntVal($ID);
        switch ($_REQUEST['action']) {
            case "delete":
                @set_time_limit(0);
                $DB->StartTransaction();
                $ch = new CTest();
                if (!$ch->Delete($ID)) {
                    $DB->Rollback();
                    $lAdmin->AddGroupError(GetMessage("LEARNING_DELETE_ERROR"), $ID);
                }
                $DB->Commit();
                break;
            case "activate":
            case "deactivate":
                $ch = new CTest();
                $arFields = array("ACTIVE" => $_REQUEST['action'] == "activate" ? "Y" : "N");
                if (!$ch->Update($ID, $arFields)) {
                    if ($e = $APPLICATION->GetException()) {
                        $lAdmin->AddGroupError(GetMessage("SAVE_ERROR") . $ID . ": " . $e->GetString(), $ID);
                    }
                }
                break;
        }
    }
    if (isset($return_url) && strlen($return_url) > 0 && check_bitrix_sessid()) {
        LocalRedirect($return_url);
    }
}
// fetch data
$rsData = CTest::GetList(array($by => $order), $arFilter);
Beispiel #25
0
if ($USER->GetID())
{
	$arTest["ATTEMPT_LIMIT"] += CGradeBook::GetExtraAttempts($USER->GetID(), $arParams["TEST_ID"]);
}
$oAccess = CLearnAccess::GetInstance($USER->GetID());
$isRelativelyHighAccessLevel = $oAccess->IsBaseAccess(
	CLearnAccess::OP_LESSON_CREATE 
	| CLearnAccess::OP_LESSON_READ 
	| CLearnAccess::OP_LESSON_WRITE 
	| CLearnAccess::OP_LESSON_REMOVE);
$bCheckPerm = (!$isRelativelyHighAccessLevel && !$USER->IsAdmin());
if ($bCheckPerm 
	&& $arTest["PREVIOUS_TEST_ID"] > 0 
	&& $arTest["PREVIOUS_TEST_SCORE"] > 0 
	&& !CTest::isPrevPassed($arTest["PREVIOUS_TEST_ID"], $arTest["PREVIOUS_TEST_SCORE"]))
{
	if ($arTest["PREVIOUS_TEST_LINK"])
	{
		$errors[] = str_replace("#TEST_LINK#", "\"".$arTest["PREVIOUS_TEST_LINK"]."\"", GetMessage("LEARNING_TEST_DENIED_PREVIOUS"));
	}
}

//Session variables
$userID = $USER->GetID() ? $USER->GetID() : 0;
$sessAttemptID =& $_SESSION["LEARN_".$arParams["TEST_ID"]."_ATTEMPT_ID_".$userID];
$sessAttemptFinished =& $_SESSION["LEARN_".$arParams["TEST_ID"]."_FINISHED_".$userID];
$sessAttemptError =& $_SESSION["LEARN_".$arParams["TEST_ID"]."_ERROR_".$userID];
$sessAttempt =& $_SESSION["LEARN_".$arParams["TEST_ID"]."_COMPLETED_".$userID];
$sessIncorrectMessage =& $_SESSION["LEARN_".$arParams["TEST_ID"]."_INCORRECT_MESSAGE_".$userID];