В битриксе есть очень полезный модуль – обучение. Благодаря ему можно легко обучать новичков и контролировать уровень знаний опытных сотрудников. По результатам обучения сотрудники проходят тесты и получают баллы.
Задача
В целях повышения мотивации к безошибочному прохождению теста создать страницу, на которой будет выводиться список лучших результатов теста.
Поиск решения
Т.к. ничего похожего в стандартном модуле нет, кастомизирование шаблонов сразу отпадает.
Сначала я решил, что всё просто. И сделать нужную выборку можно простой настройкой фильтра метода CTestAttempt::GetList(), но не тут то было.
Оказывается, в битриксе нет понятия номера попытки прохождения теста. Если просто отсортировать попытки по полученным баллам, то в выборке будут участвовать как самые худшие, так и самые лучшие попытки.
В итоге те? кто сдал тест с первого раза плохо будут в списке лузеров, и они же могут быть в списке лучших, т.к. пройти тест второй раз никто не мешает.
Найденное решение
Сначала я всё-таки сделал общий топ по всем попыткам. Но пользователи очень сильно возбубнили и пришлось делать два отдельных топа – по первой попытке и по лучшей попытке от каждого пользователя.
В итоге получился вот такой вот код для первых попыток:
- <?$testList = CTest::GetList(
- );//получаем список тестов
- while ($arTest = $testList->GetNext()){?>
- <div id="testList">
- <h2><?=$arTest[‘NAME’]?></h2>
- <table class="testList-table">
- <tr>
- <td class="testList-best-top"><span>Лучшие результаты</span></td>
- <td class="testList-bad-top"><span>Худшие результаты</span></td>
- </tr>
- <tr class="testList-result">
- <td class="testList-result-best">
- <table class="testList-result-table">
- <thead>
- <td class="testList-position">Место
- </td>
- <td class="testList-user-name">Имя
- </td>
- <td class="testList-score">Балл
- </td>
- </thead>
- <tbody>
- <?$attemptListByDate = CTestAttempt::GetList(
- );//получаем список попыток по дате
- while ($arAttemptByDate = $attemptListByDate->GetNext()){
- if(($arAttemptByDate[‘SCORE’] != "") && ($arAttemptByDate[‘SCORE’] != "0")){
- $arUsers[] = $arAttemptByDate[‘USER_NAME’];
- $arAttemptScore[] = $arAttemptByDate[‘SCORE’];
- }
- }
- }//создаём массив первых попыток
- $attemptCount = 0;
- while (($element = current($arAttemptScore)) && ($attemptCount != 5)){//проходим по 5ти первым элементам массива
- <tr>
- </td>
- <td class="testList-user-name"><?=$f_USER_NAME[1]?>
- </td>
- <td class="testList-user-score"><?=$arAttemptScore[$key]?>
- </td>
- </tr>
- <?$attemptCount++;
- }?>
- </tbody>
- </table>
- <td class="testList-result-bad">
- <table class="testList-result-table">
- <thead>
- <td class="testList-score">Балл
- </td>
- <td class="testList-user-name">Имя
- </td>
- <td class="testList-position">Место
- </td>
- </thead>
- <tbody>
- $attemptCount = 0;?>
- <?while (($element = current($arAttemptScore)) && ($attemptCount != 5)){//проходим по 5ти первым элементам массива
- <tr>
- <td class="testList-user-score"><?=$arAttemptScore[$key]?>
- </td>
- <td class="testList-user-name"><?=$f_USER_NAME[1]?>
- </td>
- </td>
- </tr>
- <?$attemptCount++;
- }?>
- </tbody>
- </table>
- </td>
- </tr>
- <tr>
- <td class="testList-bottom-best"> </span></td>
- <td class="testList-bottom-bad"> </td>
- </tr>
- </table>
- </div>
И для лучших попыток:
- <?$testList = CTest::GetList(
- );//получаем список тестов
- while ($arTest = $testList->GetNext()){?>
- <div id="testList">
- <h2><?=$arTest[‘NAME’]?></h2>
- <table class="testList-table">
- <tr>
- <td class="testList-best-top"><span>Лучшие результаты</span></td>
- <td class="testList-bad-top"><span>Худшие результаты</span></td>
- </tr>
- <tr class="testList-result">
- <td class="testList-result-best">
- <table class="testList-result-table">
- <thead>
- <td class="testList-position">Место
- </td>
- <td class="testList-user-name">Имя
- </td>
- <td class="testList-score">Балл
- </td>
- </thead>
- <tbody>
- <?$attemptListByDate = CTestAttempt::GetList(
- );//получаем список попыток по дате
- while ($arAttemptByDate = $attemptListByDate->GetNext()){
- if(($arAttemptByDate[‘SCORE’] != "") && ($arAttemptByDate[‘SCORE’] != "0")){
- $arUsers[] = $arAttemptByDate[‘USER_NAME’];
- $arAttemptScore[] = $arAttemptByDate[‘SCORE’];
- }
- }
- }//создаём массив попыток
- $attemptCount = 0;
- while (($element = current($arAttemptScore)) && ($attemptCount != 5)){//проходим по 5ти первым элементам массива
- <tr>
- </td>
- <td class="testList-user-name"><?=$f_USER_NAME[1]?>
- </td>
- <td class="testList-user-score"><?=$arAttemptScore[$key]?>
- </td>
- </tr>
- <?$attemptCount++;
- }?>
- </tbody>
- </table>
- <td class="testList-result-bad">
- <table class="testList-result-table">
- <thead>
- <td class="testList-score">Балл
- </td>
- <td class="testList-user-name">Имя
- </td>
- <td class="testList-position">Место
- </td>
- </thead>
- <tbody>
- $attemptCount = 0;?>
- <?while (($element = current($arAttemptScore)) && ($attemptCount != 5)){//проходим по 5ти первым элементам массива
- <tr>
- <td class="testList-user-score"><?=$arAttemptScore[$key]?>
- </td>
- <td class="testList-user-name"><?=$f_USER_NAME[1]?>
- </td>
- </td>
- </tr>
- <?$attemptCount++;
- }?>
- </tbody>
- </table>
- </td>
- </tr>
- <tr>
- <td class="testList-bottom-best"> </span></td>
- <td class="testList-bottom-bad"> </td>
- </tr>
- </table>
- </div>
Внешне это выглядит вот так (все фамилии вымышлены совпадения случайны)
Такая табличка выводится на каждый тест, к которому имеет доступ пользователь.
Итог
В результате получилась классная пузомерка, хорошо мотивирующая сотрудников искать правильные ответы на тесты.
За попытки отвечает класс CTestAttempt у которого есть метод GetList.
Ему нужно передать идентификатор студента, который можно получить воспользовавшись методом GetList класса CStudent. USER_ID текущего пользователя у вас в профиле есть.
Если вы не продумаете как скрыть эту информацию, то она будет доступна всем =)
P.S. не смотрите на код, который написан выше, так писать не стоит =)
Ответить