Add setting "score_grade_model" see BT#12898

Allow to convert a score into a text/color label
using a model if score is inside those values.

WIP: This change only affects exercises.
pull/2487/head
jmontoyaa 8 years ago
parent 88f07d8b36
commit 33debc5659
  1. 11
      main/course_info/infocours.php
  2. 40
      main/exercise/exercise_show.php
  3. 10
      main/exercise/question.class.php
  4. 4
      main/inc/lib/course.lib.php
  5. 114
      main/inc/lib/exercise.lib.php
  6. 49
      main/install/configuration.dist.php

@ -167,6 +167,16 @@ if (api_get_setting('allow_course_theme') == 'true') {
}
$form->addElement('label', get_lang('DocumentQuota'), format_file_size(DocumentManager::get_course_quota()));
if (!empty(ExerciseLib::getScoreModels())) {
$models = ExerciseLib::getScoreModels();
$options = ['' => get_lang('None')];
foreach ($models['models'] as $item) {
$options[$item['id']] = get_lang($item['name']);
}
$form->addSelect('score_model_id', get_lang('ScoreModel'), $options);
}
$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
$form->addHtml('
</div>
@ -636,6 +646,7 @@ $values['legal'] = $all_course_information['legal'];
$values['activate_legal'] = $all_course_information['activate_legal'];
$courseSettings = CourseManager::getCourseSettingVariables($appPlugin);
foreach ($courseSettings as $setting) {
$result = api_get_course_setting($setting);
if ($result != '-1') {

@ -140,7 +140,7 @@ if (isset($_SESSION['gradebook'])) {
}
$allowRecordAudio = api_get_setting('enable_record_audio') === 'true';
$allowTeacherComentAudio = api_get_configuration_value('allow_teacher_comment_audio') === true;
$allowTeacherCommentAudio = api_get_configuration_value('allow_teacher_comment_audio') === true;
if (!empty($gradebook) && $gradebook == 'view') {
$interbreadcrumb[] = array(
@ -162,7 +162,7 @@ $htmlHeadXtra[] = '<link rel="stylesheet" href="'.api_get_path(WEB_LIBRARY_JS_PA
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'hotspot/js/hotspot.js"></script>';
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'annotation/js/annotation.js"></script>';
if ($allowRecordAudio && $allowTeacherComentAudio) {
if ($allowRecordAudio && $allowTeacherCommentAudio) {
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'rtc/RecordRTC.js"></script>';
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'wami-recorder/recorder.js"></script>';
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'wami-recorder/gui.js"></script>';
@ -202,7 +202,7 @@ if ($origin != 'learnpath') {
oHidn.type = "hidden";
var selname = oHidn.name = "marks_" + m_id[i];
var selid = document.forms['marksform_' + m_id[i]].marks.selectedIndex;
oHidn.value = document.forms['marksform_' + m_id[i]].marks.options[selid].text;
oHidn.value = document.forms['marksform_' + m_id[i]].marks.options[selid].value;
f.appendChild(oHidn);
}
@ -721,7 +721,7 @@ foreach ($questionList as $questionId) {
echo '</p>';
echo '<div id="feedback_'.$name.'" class="show">';
$comnt = trim(Event::get_comments($id, $questionId));
$comnt = Event::get_comments($id, $questionId);
if (!empty($comnt)) {
echo ExerciseLib::getFeedbackText($comnt);
echo ExerciseLib::getOralFeedbackAudio($id, $questionId, $student_id);
@ -729,7 +729,7 @@ foreach ($questionList as $questionId) {
echo '</div>';
echo '<div id="'.$name.'" class="row hidden">';
echo '<div class="col-sm-'.($allowTeacherComentAudio ? 7 : 12).'">';
echo '<div class="col-sm-'.($allowTeacherCommentAudio ? 7 : 12).'">';
$arrid[] = $questionId;
$feedback_form = new FormValidator('frmcomments'.$questionId);
@ -759,7 +759,7 @@ foreach ($questionList as $questionId) {
echo '</div>';
if ($allowRecordAudio && $allowTeacherComentAudio) {
if ($allowRecordAudio && $allowTeacherCommentAudio) {
echo '<div class="col-sm-5">';
echo ExerciseLib::getOralFeedbackForm($id, $questionId, $student_id);
echo '</div>';
@ -780,13 +780,31 @@ foreach ($questionList as $questionId) {
if ($is_allowedToEdit && $isFeedbackAllowed) {
if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION, ANNOTATION))) {
$marksname = "marksName".$questionId;
$arrmarks[] = $questionId;
echo '<div id="'.$marksname.'" class="hidden">';
// @todo use FormValidator
/*$formMark = new FormValidator("marksform_'.$questionId.'", 'post');
$options = [
1,
2
];
$formMark->addSelect('marks', get_lang('AssignMarks'), $options);
$formMark->display();*/
echo '<form name="marksform_'.$questionId.'" method="post" action="">';
$arrmarks[] = $questionId;
echo get_lang("AssignMarks");
echo "&nbsp;<select name='marks' id='marks'>";
for ($i = 0; $i <= $questionWeighting; $i++) {
echo '<option '.(($i == $questionScore) ? "selected='selected'" : '').'>'.$i.'</option>';
echo "&nbsp;<select class='selectpicker' name='marks' id='marks'>";
$model = ExerciseLib::getCourseScoreModel();
if (empty($model)) {
for ($i = 0; $i <= $questionWeighting; $i++) {
echo '<option value="'.$i.'" '.(($i == $questionScore) ? "selected='selected'" : '').'>'.$i.'</option>';
}
} else {
foreach ($model['score_list'] as $item) {
$i = api_number_format($item['score_to_qualify']/100 * $questionWeighting, 2);
$model = ExerciseLib::getModelStyle($item, $i);
echo '<option value="'.$i.'" '.(($i == $questionScore) ? "selected='selected'" : '').'>'.$model.'</option>';
}
}
echo '</select>';
echo '</form><br /></div>';
@ -801,7 +819,7 @@ foreach ($questionList as $questionId) {
<div id="'.$marksname.'" class="hidden">
<form name="marksform_'.$questionId.'" method="post" action="">
<select name="marks" id="marks" style="display:none;">
<option>'.$questionScore.'</option>
<option value="'.$questionScore.'" >'.$questionScore.'</option>
</select>
</form>
<br/>

@ -1945,6 +1945,10 @@ abstract class Question
$class = 'warning';
$weight = float_format($score['weight'], 1);
$score['result'] = " ? / ".$weight;
$model = ExerciseLib::getCourseScoreModel();
if (!empty($model)) {
$score['result'] = " ? ";
}
}
}
@ -2219,8 +2223,10 @@ abstract class Question
public function isQuestionWaitingReview($score)
{
$isReview = false;
if (!empty($score['comments']) || $score['score'] > 0) {
$isReview = true;
if (!empty($score)) {
if (!empty($score['comments']) || $score['score'] > 0) {
$isReview = true;
}
}
return $isReview;

@ -5379,6 +5379,10 @@ class CourseManager
'show_course_in_user_language'
);
if (!empty(ExerciseLib::getScoreModels())) {
$courseSettings[] = 'score_model_id';
}
$allowLPReturnLink = api_get_setting('allow_lp_return_link');
if ($allowLPReturnLink === 'true') {
$courseSettings[] = 'lp_return_link';

@ -2285,17 +2285,17 @@ HOTSPOT;
return '-';
}
$max_note = api_get_setting('exercise_max_score');
$min_note = api_get_setting('exercise_min_score');
$maxNote = api_get_setting('exercise_max_score');
$minNote = api_get_setting('exercise_min_score');
if ($use_platform_settings) {
if ($max_note != '' && $min_note != '') {
if ($maxNote != '' && $minNote != '') {
if (!empty($weight) && intval($weight) != 0) {
$score = $min_note + ($max_note - $min_note) * $score / $weight;
$score = $minNote + ($maxNote - $minNote) * $score / $weight;
} else {
$score = $min_note;
$score = $minNote;
}
$weight = $max_note;
$weight = $maxNote;
}
}
$percentage = (100 * $score) / ($weight != 0 ? $weight : 1);
@ -2305,7 +2305,7 @@ HOTSPOT;
$score = float_format($score, 1);
$weight = float_format($weight, 1);
$html = null;
$html = '';
if ($show_percentage) {
$parent = '('.$score.' / '.$weight.')';
$html = $percentage."% $parent";
@ -2315,11 +2315,91 @@ HOTSPOT;
} else {
$html = $score.' / '.$weight;
}
$html = Display::span($html, array('class' => 'score_exercise'));
// Over write score
$scoreBasedInModel = self::convertScoreToModel($percentage);
if (!empty($scoreBasedInModel)) {
$html = $scoreBasedInModel;
}
$html = Display::span($html, ['class' => 'score_exercise']);
return $html;
}
/**
* @param array $model
* @param float $percentage
* @return string
*/
public static function getModelStyle($model, $percentage)
{
$modelWithStyle = get_lang($model['name']);
$modelWithStyle .= ' - <span class="'.$model['css_class'].'">'.$model['css_class'].' </span> - ';
$modelWithStyle .= $percentage;
return $modelWithStyle;
}
/**
* @param float $percentage value between 0 and 100
* @return string
*/
public static function convertScoreToModel($percentage)
{
$model = self::getCourseScoreModel();
if (!empty($model)) {
$scoreWithGrade = [];
foreach ($model['score_list'] as $item) {
if ($percentage >= $item['min'] && $percentage <= $item['max']) {
$scoreWithGrade = $item;
break;
}
}
if (!empty($scoreWithGrade)) {
return self::getModelStyle($scoreWithGrade, $percentage);
}
}
return '';
}
/**
* @return array
*/
public static function getCourseScoreModel()
{
$modelList = self::getScoreModels();
if (empty($modelList)) {
return [];
}
$courseInfo = api_get_course_info();
if (!empty($courseInfo)) {
$scoreModelId = api_get_course_setting('score_model_id');
if ($scoreModelId != -1) {
$modelIdList = array_column($modelList['models'], 'id');
if (in_array($scoreModelId, $modelIdList)) {
foreach ($modelList['models'] as $item) {
if ($item['id'] == $scoreModelId) {
return $item;
}
}
}
}
}
return [];
}
/**
* @return array
*/
public static function getScoreModels()
{
return api_get_configuration_value('score_grade_model');
}
/**
* @param float $score
* @param float $weight
@ -2421,15 +2501,15 @@ HOTSPOT;
*/
public static function convert_score($score, $weight)
{
$max_note = api_get_setting('exercise_max_score');
$min_note = api_get_setting('exercise_min_score');
$maxNote = api_get_setting('exercise_max_score');
$minNote = api_get_setting('exercise_min_score');
if ($score != '' && $weight != '') {
if ($max_note != '' && $min_note != '') {
if ($maxNote != '' && $minNote != '') {
if (!empty($weight)) {
$score = $min_note + ($max_note - $min_note) * $score / $weight;
$score = $minNote + ($maxNote - $minNote) * $score / $weight;
} else {
$score = $min_note;
$score = $minNote;
}
}
}
@ -3859,7 +3939,11 @@ HOTSPOT;
$comnt = null;
if ($show_results) {
$comnt = Event::get_comments($exe_id, $questionId);
$teacherAudio = ExerciseLib::getOralFeedbackAudio($exe_id, $questionId, api_get_user_id());;
$teacherAudio = ExerciseLib::getOralFeedbackAudio(
$exe_id,
$questionId,
api_get_user_id()
);;
if (!empty($comnt) || $teacherAudio) {
echo '<b>'.get_lang('Feedback').'</b>';
@ -3914,8 +3998,8 @@ HOTSPOT;
if ($show_results) {
$question_content .= '</div>';
}
$exercise_content .= Display::panel($question_content);
} // end foreach() block that loops over all questions
}

@ -500,7 +500,8 @@ $_configuration['send_all_emails_to'] = [
]
];*/
//
// ------ Exercises configuration settings
// Exercises configuration settings
// Send only quiz answer notifications to course coaches and not general coach
//$_configuration['block_quiz_mail_notification_general_coach'] = false;
// Show question feedback (requires DB change: "ALTER TABLE c_quiz_question ADD COLUMN feedback text;")
@ -510,10 +511,52 @@ $_configuration['send_all_emails_to'] = [
//$_configuration['allow_quiz_show_previous_button_setting'] = false;
// Allow to teachers review exercises question with audio notes
//$_configuration["allow_teacher_comment_audio"] = false;
// ------
// Hide search form in session list
//$_configuration['hide_search_form_in_session_list'] = false;
// Allow exchange of messages from teachers/bosses about a user.
//$_configuration['private_messages_about_user'] = false;
// Score model
// Allow to convert a score into a text/color label
// using a model if score is inside those values. See BT#12898
/*
$_configuration['score_grade_model'] = [
'models' => [
[
'id' => 1,
'name' => 'ThisIsMyModel', // Value will be translated using get_lang
'score_list' => [
[
'name' => 'VeryBad', // Value will be translated using get_lang
'css_class' => 'btn-danger',
'min' => 0,
'max' => 20,
'score_to_qualify' => 0
],
[
'name' => 'Bad',
'css_class' => 'btn-danger',
'min' => 21,
'max' => 50,
'score_to_qualify' => 25
],
[
'name' => 'Good',
'css_class' => 'btn-warning',
'min' => 51,
'max' => 70,
'score_to_qualify' => 60
],
[
'name' => 'VeryGood',
'css_class' => 'btn-success',
'min' => 71,
'max' => 100,
'score_to_qualify' => 100
]
]
]
]
];
*/

Loading…
Cancel
Save