Exercises: Add new Ranking mode #2788

pull/2818/head
Angel Fernando Quiroz Campos 6 years ago
parent 6f7a16f934
commit a5784b4ffd
  1. 8
      main/exercise/exercise.class.php
  2. 22
      main/exercise/exercise.php
  3. 3
      main/exercise/overview.php
  4. 2
      main/inc/lib/api.lib.php
  5. 128
      main/inc/lib/exercise.lib.php

@ -1951,6 +1951,14 @@ class Exercise
'5',
['id' => 'result_disabled_5', 'onclick' => 'check_results_disabled()']
);
$radios_results_disabled[] = $form->createElement(
'radio',
'results_disabled',
null,
get_lang('ExerciseRankingMode'),
'6',
['id' => 'result_disabled_6']
);
$form->addGroup(
$radios_results_disabled,

@ -1044,7 +1044,16 @@ if (!empty($exerciseList)) {
// Exam is ready to be taken
if ($is_actived_time) {
// Show results 697 $attempt_text = get_lang('LatestAttempt').' : ';
if ($my_result_disabled == 0 || $my_result_disabled == 2) {
if (
in_array(
$my_result_disabled,
[
RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS,
RESULT_DISABLE_SHOW_SCORE_ONLY,
RESULT_DISABLE_RANKING,
]
)
) {
//More than one attempt
if ($num > 0) {
$row_track = Database :: fetch_array($qryres);
@ -1099,7 +1108,16 @@ if (!empty($exerciseList)) {
} else {
// Normal behaviour.
// Show results.
if ($my_result_disabled == 0 || $my_result_disabled == 2) {
if (
in_array(
$my_result_disabled,
[
RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS,
RESULT_DISABLE_SHOW_SCORE_ONLY,
RESULT_DISABLE_RANKING,
]
)
) {
if ($num > 0) {
$row_track = Database :: fetch_array($qryres);
$attempt_text = get_lang('LatestAttempt').' : ';

@ -255,6 +255,7 @@ if (!empty($attempts)) {
RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
RESULT_DISABLE_RANKING,
]
)) {
$row['result'] = $score;
@ -267,6 +268,7 @@ if (!empty($attempts)) {
RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
RESULT_DISABLE_RANKING,
]
) || (
$objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY &&
@ -324,6 +326,7 @@ if (!empty($attempts)) {
break;
case RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS:
case RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES:
case RESULT_DISABLE_RANKING:
$header_names = [
get_lang('Attempt'),
get_lang('StartDate'),

@ -469,6 +469,8 @@ define('RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS', 1); //Do not show score n
define('RESULT_DISABLE_SHOW_SCORE_ONLY', 2); //Show score only
define('RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES', 3); //Show final score only with categories
define('RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT', 4);
define('RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK', 5);
define('RESULT_DISABLE_RANKING', 6);
// 4: Show final score only with categories and show expected answers only on the last attempt
define('EXERCISE_MAX_NAME_SIZE', 80);

@ -2,6 +2,7 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CoreBundle\Entity\TrackEExercises;
use ChamiloSession as Session;
/**
@ -4437,6 +4438,7 @@ EOT;
[
RESULT_DISABLE_SHOW_SCORE_ONLY,
RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES,
RESULT_DISABLE_RANKING,
]
)
) {
@ -4832,6 +4834,132 @@ EOT;
);
}
}
if (RESULT_DISABLE_RANKING == $objExercise->selectResultsDisabled()) {
echo Display::page_header(get_lang('Ranking'), null, 'h4');
echo self::displayResultsInRanking(
$objExercise->iId,
api_get_user_id(),
api_get_course_int_id(),
api_get_session_id()
);
}
}
/**
* Display the ranking of results in a exercise
*
* @param int $exerciseId
* @param int $currentUserId
* @param int $courseId
* @param int $sessionId
*
* @return string
*/
public static function displayResultsInRanking($exerciseId, $currentUserId, $courseId, $sessionId = 0)
{
$data = self::exerciseResultsInRanking($exerciseId, $courseId, $sessionId);
$table = new HTML_Table(['class' => 'table table-hover table-bordered']);
$table->setHeaderContents(0, 0, get_lang('Position'), ['class' => 'text-right']);
$table->setHeaderContents(0, 1, get_lang('Username'));
$table->setHeaderContents(0, 2, get_lang('Score'), ['class' => 'text-right']);
$table->setHeaderContents(0, 3, get_lang('Date'), ['class' => 'text-center']);
foreach ($data as $r => $item) {
$selected = $item[1]->getId() == $currentUserId;
foreach ($item as $c => $value) {
$table->setCellContents($r + 1, $c, $value);
$attrClass = '';
if (in_array($c, [0, 2])) {
$attrClass = 'text-right';
} elseif (3 == $c) {
$attrClass = 'text-center';
}
if ($selected) {
$attrClass .= ' warning';
}
$table->setCellAttributes($r + 1, $c, ['class' => $attrClass]);
}
}
return $table->toHtml();
}
/**
* Get the ranking for results in a exercise.
* Function used internally by ExerciseLib::displayResultsInRanking
*
* @param int $exerciseId
* @param int $courseId
* @param int $sessionId
*
* @return array
*/
public static function exerciseResultsInRanking($exerciseId, $courseId, $sessionId = 0)
{
$em = Database::getManager();
$dql = 'SELECT DISTINCT te.exeUserId FROM ChamiloCoreBundle:TrackEExercises te WHERE te.exeExoId = :id AND te.cId = :cId';
$dql .= api_get_session_condition($sessionId, true, false, 'te.sessionId');
$result = $em
->createQuery($dql)
->setParameters(['id' => $exerciseId, 'cId' => $courseId])
->getScalarResult();
$data = [];
/** @var TrackEExercises $item */
foreach ($result as $item) {
$bestAttemp = self::get_best_attempt_by_user($item['exeUserId'], $exerciseId, $courseId, $sessionId = 0);
$data[] = $bestAttemp;
}
usort(
$data,
function ($a, $b) {
if ($a['exe_result'] != $b['exe_result']) {
return $a['exe_result'] > $b['exe_result'] ? -1 : 1;
}
if ($a['exe_date'] != $b['exe_date']) {
return $a['exe_date'] > $b['exe_date'] ? -1 : 1;
}
return 0;
}
);
// flags to display the same position in case of tie
$lastScore = $data[0]['exe_result'];
$position = 1;
$data = array_map(
function ($item) use (&$lastScore, &$position) {
if ($item['exe_result'] < $lastScore) {
++$position;
}
$lastScore = $item['exe_result'];
return [
$position,
api_get_user_entity($item['exe_user_id']),
self::show_score($item['exe_result'], $item['exe_weighting'], true, true, true),
api_convert_and_format_date($item['exe_date'], DATE_TIME_FORMAT_SHORT),
];
},
$data
);
return $data;
}
/**

Loading…
Cancel
Save