Skip to content
Permalink
Browse files

Add course setting quiz_question_limit_per_day - refs BT#15234

If set to greater than 0, this option will prevent the learner from entering a test that has more than what remains for the daily allowance. For example, is the limit is 50 and the learner has already taken 2 tests of 20 questions, it will not let the learner enter another 20 questions test (20+20+20=60 > 50). However, it will let the learner enter a 10 questions test (20+20+10=50).
  • Loading branch information...
AngelFQC committed Mar 21, 2019
1 parent 6fac3f1 commit ed0cba3cf4d9dbf769c497cbf3f1ae5d532d2cbc
@@ -723,29 +723,30 @@ function is_settings_editable()
$form->addHtml('</div>');
// Exercise
if (api_get_configuration_value('allow_exercise_auto_launch')) {
$form->addHtml('<div class="panel panel-default">');
$form->addHtml('
$form->addHtml('<div class="panel panel-default">');
$form->addHtml('
<div class="panel-heading" role="tab" id="heading-exercise">
<h4 class="panel-title">
<a class="collapsed"
role="button" data-toggle="collapse"
data-parent="#accordion"
href="#collapse-exercise" aria-expanded="false" aria-controls="collapse-exercise">
');
$form->addHtml(
Display::return_icon('quiz.png', get_lang('Exercise')).' '.get_lang('Exercise')
);
$form->addHtml('
$form->addHtml(
Display::return_icon('quiz.png', get_lang('Exercises')).' '.get_lang('Exercises')
);
$form->addHtml('
</a>
</h4>
</div>
');
$form->addHtml('
$form->addHtml('
<div id="collapse-exercise" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-exercise">
<div class="panel-body">
');
if (api_get_configuration_value('allow_exercise_auto_launch')) {
// Auto launch exercise
$group = [];
$group[] = $form->createElement(
@@ -764,22 +765,30 @@ function is_settings_editable()
);
$group[] = $form->createElement('radio', 'enable_exercise_auto_launch', null, get_lang('Deactivate'), 0);
$form->addGroup($group, '', [get_lang('ExerciseAutoLaunch')]);
}
if (is_settings_editable()) {
$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
} else {
// Is it allowed to edit the course settings?
if (!is_settings_editable()) {
$disabled_output = "disabled";
}
$form->freeze();
$form->addElement(
'number',
'quiz_question_limit_per_day',
[get_lang('QuizQuestionsLimitPerDay'), get_lang('QuizQuestionsLimitPerDayComment')],
['step' => 1, 'min' => 0]
);
if (is_settings_editable()) {
$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
} else {
// Is it allowed to edit the course settings?
if (!is_settings_editable()) {
$disabled_output = "disabled";
}
$form->addHtml('
$form->freeze();
}
$form->addHtml('
</div>
</div>
');
$form->addHtml('</div>');
}
$form->addHtml('</div>');
// THEMATIC ADVANCE SETTINGS
$group = [];
@@ -1,6 +1,7 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
use Chamilo\CoreBundle\Entity\TrackEHotspot;
use ChamiloSession as Session;
@@ -6258,9 +6259,9 @@ public function is_visible(
}
// 4. We check if the student have attempts
$exerciseAttempts = $this->selectAttempts();
if ($isVisible) {
$exerciseAttempts = $this->selectAttempts();
if ($exerciseAttempts > 0) {
$attemptCount = Event::get_attempt_count_not_finished(
api_get_user_id(),
@@ -6278,6 +6279,19 @@ public function is_visible(
);
$isVisible = false;
}
} else {
$isLimitReached = ExerciseLib::isQuestionsLimitPerDayReached(
api_get_user_id(),
$this->selectNbrQuestions(),
api_get_course_int_id(),
api_get_session_id()
);
if ($isLimitReached) {
$maxQuestionsAnswered = (int) api_get_course_setting('quiz_question_limit_per_day');
$message = sprintf(get_lang('QuizQuestionsLimitPerDayXReached'), $maxQuestionsAnswered);
$isVisible = false;
}
}
}
@@ -39,6 +39,7 @@
$origin = api_get_origin();
$is_allowedToEdit = api_is_allowed_to_edit(null, true);
$courseId = api_get_course_int_id();
$sessionId = api_get_session_id();
$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
$showGlossary = in_array($glossaryExtraTools, ['true', 'exercise', 'exercise_and_lp']);
@@ -244,6 +245,35 @@
);
if (!empty($exercise_stat_info)) {
$isQuestionsLimitReached = ExerciseLib::isQuestionsLimitPerDayReached(
$user_id,
$objExercise->selectNbrQuestions(),
$courseId,
$sessionId
);
if ($isQuestionsLimitReached) {
$maxQuestionsAnswered = (int) api_get_course_setting('quiz_question_limit_per_day');
Display::addFlash(
Display::return_message(
sprintf(get_lang('QuizQuestionsLimitPerDayXReached'), $maxQuestionsAnswered),
'warning',
false
)
);
if ($origin == 'learnpath') {
Display::display_reduced_header();
Display::display_reduced_footer();
} else {
Display::display_header(get_lang('Exercises'));
Display::display_footer();
}
exit;
}
$max_exe_id = max(array_keys($exercise_stat_info));
$last_attempt_info = $exercise_stat_info[$max_exe_id];
$attempt_html .= Display::div(
@@ -5618,6 +5618,7 @@ public static function getCourseSettingVariables(AppPlugin $appPlugin)
'email_to_teachers_on_new_work_feedback',
'student_delete_own_publication',
'hide_forum_notifications',
'quiz_question_limit_per_day',
];
$courseModels = ExerciseLib::getScoreModels();
@@ -1,6 +1,7 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
use Chamilo\CoreBundle\Entity\TrackEExercises;
use ChamiloSession as Session;
@@ -5255,4 +5256,62 @@ public static function getAdditionalTeacherActions($exerciseId, $iconSize = ICON
return implode(PHP_EOL, $actions);
}
/**
* @param DateTime $time
* @param int $userId
* @param int $courseId
* @param int $sessionId
*
* @throws \Doctrine\ORM\Query\QueryException
*
* @return int
*/
public static function countAnsweredQuestionsByUserAfterTime(DateTime $time, $userId, $courseId, $sessionId)
{
$em = Database::getManager();
$time = api_get_utc_datetime($time->format('Y-m-d H:i:s'), false, true);
$result = $em
->createQuery('
SELECT COUNT(ea) FROM ChamiloCoreBundle:TrackEAttempt ea
WHERE ea.userId = :user AND ea.cId = :course AND ea.sessionId = :session
AND ea.tms > :time
GROUP BY ea.questionId
')
->setParameters(['user' => $userId, 'course' => $courseId, 'session' => $sessionId, 'time' => $time])
->getResult();
return count($result);
}
/**
* @param int $userId
* @param int $numberOfQuestions
* @param int $courseId
* @param int $sessionId
*
* @return bool
* @throws \Doctrine\ORM\Query\QueryException
*/
public static function isQuestionsLimitPerDayReached($userId, $numberOfQuestions, $courseId, $sessionId)
{
$questionsLimitPerDay = (int) api_get_course_setting('quiz_question_limit_per_day');
if ($questionsLimitPerDay <= 0) {
return false;
}
$midnightTime = ChamiloApi::getServerMidnightTime();
$answeredQuestionsCount = ExerciseLib::countAnsweredQuestionsByUserAfterTime(
$midnightTime,
$userId,
$courseId,
$sessionId
);
return ($answeredQuestionsCount + $numberOfQuestions) > $questionsLimitPerDay;
}
}
@@ -334,4 +334,25 @@ public static function getColorPalette(
return $palette;
}
/**
* Get the local time for the midnight
*
* @param string|null $utcTime Optional. The time to ve converted.
* See api_get_local_time.
*
* @throws \Exception
*
* @return \DateTime
*/
public static function getServerMidnightTime($utcTime = null)
{
$localTime = api_get_local_time($utcTime);
$localTimeZone = api_get_timezone();
$localMidnight = new \DateTime($localTime, new \DateTimeZone($localTimeZone));
$localMidnight->modify('midnight');
return $localMidnight;
}
}

0 comments on commit ed0cba3

Please sign in to comment.
You can’t perform that action at this time.