diff --git a/controllers/solutions.php b/controllers/solutions.php index c29663f28b633f3263794cbd038675fb35a9dc87..b37b5405cccae0a70dac976b3a7fed5faf54308a 100644 --- a/controllers/solutions.php +++ b/controllers/solutions.php @@ -1553,10 +1553,10 @@ class SolutionsController extends StudipController $exercise_points = (float) $exercise_ref->points; $exercise_average = 0; $exercise_correct = 0; - $exercise_items = []; - $exercise_items_c = []; $exercise_item_count = $exercise->itemCount(); + $exercise_items = array_fill(0, $exercise_item_count, 0); + $exercise_items_c = array_fill(0, $exercise_item_count, 0); $query = "SELECT vips_solution.* FROM vips_solution LEFT JOIN seminar_user USING(user_id) @@ -1814,6 +1814,8 @@ function participants_overview_data($course_id, $param_user_id, $display = null, 'blocks' => [], 'exams' => [] ]; + $overall_points = 0; + $overall_weighting = 0; // each assignment foreach ($result as $row) { @@ -1974,11 +1976,13 @@ function participants_overview_data($course_id, $param_user_id, $display = null, 'weighting' => $weighted_percent ]; + if (!isset($participants[$member_id]['overall'])) { + $participants[$member_id]['overall'] = ['points' => 0, 'weighting' => 0]; + } + // sum up overall points and weighted percent - $participants[$member_id]['overall']['points'] += $reached_points; - $participants[$member_id]['overall']['points_tests'] += $reached_points; - $participants[$member_id]['overall']['weighting'] += $weighted_percent; - $participants[$member_id]['overall']['weighting_tests'] += $weighted_percent; + $participants[$member_id]['overall']['points'] += $reached_points; + $participants[$member_id]['overall']['weighting'] += $weighted_percent; } } } @@ -1990,16 +1994,22 @@ function participants_overview_data($course_id, $param_user_id, $display = null, if (!isset($participants[$member_id]['items']['tests_seen'][$assignment_id])) { $participants[$member_id]['items']['tests_seen'][$assignment_id] = true; + if (!isset($participants[$member_id]['items']['blocks'][$item_id])) { + $participants[$member_id]['items']['blocks'][$item_id] = ['points' => 0, 'percent' => 0, 'weighting' => 0]; + } + // store reached points, percent and weighted percent for this item, for each group member $participants[$member_id]['items']['blocks'][$item_id]['points'] += $reached_points; $participants[$member_id]['items']['blocks'][$item_id]['percent'] += $percent; $participants[$member_id]['items']['blocks'][$item_id]['weighting'] += $weighted_percent; + if (!isset($participants[$member_id]['overall'])) { + $participants[$member_id]['overall'] = ['points' => 0, 'weighting' => 0]; + } + // sum up overall points and weighted percent - $participants[$member_id]['overall']['points'] += $reached_points; - $participants[$member_id]['overall']['points_blocks'] += $reached_points; - $participants[$member_id]['overall']['weighting'] += $weighted_percent; - $participants[$member_id]['overall']['weighting_blocks'] += $weighted_percent; + $participants[$member_id]['overall']['points'] += $reached_points; + $participants[$member_id]['overall']['weighting'] += $weighted_percent; } } } @@ -2014,11 +2024,13 @@ function participants_overview_data($course_id, $param_user_id, $display = null, 'weighting' => $weighted_percent ]; + if (!isset($participants[$user_id]['overall'])) { + $participants[$user_id]['overall'] = ['points' => 0, 'weighting' => 0]; + } + // sum up overall points and weighted percent - $participants[$user_id]['overall']['points'] += $reached_points; - $participants[$user_id]['overall']['points_exams'] += $reached_points; - $participants[$user_id]['overall']['weighting'] += $weighted_percent; - $participants[$user_id]['overall']['weighting_exams'] += $weighted_percent; + $participants[$user_id]['overall']['points'] += $reached_points; + $participants[$user_id]['overall']['weighting'] += $weighted_percent; } } } @@ -2093,15 +2105,17 @@ function participants_overview_data($course_id, $param_user_id, $display = null, foreach ($participants as $user_id => $participant) { $participants[$user_id]['grade'] = '5,0'; - foreach ($settings->VIPS_COURSE_GRADES as $g) { - $grade = $g['grade']; - $percent = $g['percent']; - $comment = $g['comment']; + if (isset($participant['overall'])) { + foreach ($settings->VIPS_COURSE_GRADES as $g) { + $grade = $g['grade']; + $percent = $g['percent']; + $comment = $g['comment']; - if ($participant['overall']['weighting'] >= $percent) { - $participants[$user_id]['grade'] = $grade; - $participants[$user_id]['grade_comment'] = $comment; - break; + if ($participant['overall']['weighting'] >= $percent) { + $participants[$user_id]['grade'] = $grade; + $participants[$user_id]['grade_comment'] = $comment; + break; + } } } } diff --git a/exercises/Exercise.php b/exercises/Exercise.php index b20c7e6e6dee7772f93908bd058d90268ef91528..b7e82c6211959ff6cc704fd6bfd1816c892fab0b 100644 --- a/exercises/Exercise.php +++ b/exercises/Exercise.php @@ -418,7 +418,7 @@ abstract class Exercise extends SimpleORMap $template = VipsPlugin::$template_factory->open('exercises/' . $this->type . '/' . $view); $template->exercise = $this; $template->solution = $solution; - $template->response = $solution->response; + $template->response = $solution ? $solution->response : null; $template->evaluation_mode = $assignment->options['evaluation_mode']; return $template; diff --git a/exercises/algebraq/parser.php b/exercises/algebraq/parser.php index 93274bf87d654643d17d81aaedce0636d088fc57..142482aae6e97118a3d1c4cb2b786bfaffe186e3 100644 --- a/exercises/algebraq/parser.php +++ b/exercises/algebraq/parser.php @@ -625,7 +625,7 @@ class qtype_algebra_parser_variable extends qtype_algebra_parser_term { // Extract the remaining characters for use as the subscript $this->_subscript=substr($text,strlen($m[1])); // If the first letter of the subscript is an underscore then remove it - if($this->_subscript[0] == '_') { + if($this->_subscript != '' && $this->_subscript[0] == '_') { $this->_subscript=substr($this->_subscript,1); } // Call the base class constructor with the variable text set to the combination of the @@ -641,7 +641,7 @@ class qtype_algebra_parser_variable extends qtype_algebra_parser_term { // Now set the subscript to the remaining letters $this->_subscript=substr($text,1); // If the first letter of the subscript is an underscore then remove it - if($this->_subscript[0] == '_') { + if($this->_subscript != '' && $this->_subscript[0] == '_') { $this->_subscript=substr($this->_subscript,1); } // Call the base class constructor with the variable text set to the combination of the diff --git a/exercises/cloze_exercise.php b/exercises/cloze_exercise.php index 9843971bd2acc53c7a55a633d9b046f51b375c87..7ba11cafcaa68ee5fb15c346238ca28898a24d42 100644 --- a/exercises/cloze_exercise.php +++ b/exercises/cloze_exercise.php @@ -304,7 +304,8 @@ class cloze_exercise extends Exercise $result = []; $response = $solution->response; - $ignorecase = $this->task['compare'] === 'ignorecase'; + $ignorecase = isset($this->task['compare']) && $this->task['compare'] === 'ignorecase'; + $numeric = isset($this->task['compare']) && $this->task['compare'] === 'numeric'; foreach ($this->task['answers'] as $blank => $answer) { $student_answer = normalizeText($response[$blank], $ignorecase); @@ -313,7 +314,7 @@ class cloze_exercise extends Exercise $safe = $this->interactionType() !== 'input'; foreach ($answer as $option) { // different answer options - if ($this->task['compare'] === 'numeric' && $student_answer !== '') { + if ($numeric && $student_answer !== '') { $correct = normalizeFloat($option['text'], $correct_unit); $student = normalizeFloat($response[$blank], $student_unit); diff --git a/exercises/sc_exercise.php b/exercises/sc_exercise.php index 67eb928254fc5c8c09e0bc3474b58870d72dab58..b19a27d95583ebd5d0b13177ee1665eb2a61040b 100644 --- a/exercises/sc_exercise.php +++ b/exercises/sc_exercise.php @@ -245,7 +245,7 @@ class sc_exercise extends Exercise $template = parent::getViewTemplate($view, $solution, $assignment, $user_id); if (isset($this->options['optional']) && $this->options['optional']) { - $template->optional_answer = [-1 => ['text' => _vips('keine Antwort')]]; + $template->optional_answer = [-1 => ['text' => _vips('keine Antwort'), 'score' => 0]]; } else { $template->optional_answer = []; } diff --git a/exercises/tb_exercise.php b/exercises/tb_exercise.php index b4910989eed6d0b5871faf894c6750b0999fb90e..950c21de51f4b5a7cdaa675639ec76fe484dd7e2 100644 --- a/exercises/tb_exercise.php +++ b/exercises/tb_exercise.php @@ -117,6 +117,14 @@ class tb_exercise extends Exercise return $result; } + /** + * Return the default response when there is no existing solution. + */ + public function defaultResponse() + { + return [$this->task['template']]; + } + /** * Return the solution of the student from the request POST data. * diff --git a/views/exercises/cloze_exercise/edit.php b/views/exercises/cloze_exercise/edit.php index 38073e5cd1509365bcbf436f87e069bd0c7c9ccc..485cf97b72d5bc551628cc112c1e7ffe393bc902 100644 --- a/views/exercises/cloze_exercise/edit.php +++ b/views/exercises/cloze_exercise/edit.php @@ -63,7 +63,7 @@ <?= _vips('Erlaubte relative Abweichung vom korrekten Wert') ?> <br> <input type="text" class="size-s" style="display: inline; text-align: right;" - name="epsilon" value="<?= sprintf('%g', $exercise->task['epsilon'] * 100) ?>"> % + name="epsilon" value="<?= isset($exercise->task['epsilon']) ? sprintf('%g', $exercise->task['epsilon'] * 100) : '0' ?>"> % </label> <label> @@ -72,7 +72,7 @@ <select name="input_width" style="display: inline; width: auto;" <?= isset($exercise->task['input_width']) ? '' : 'disabled' ?>> <? foreach ([_vips('kurz'), _vips('mittel'), _vips('lang'), _vips('maximal')] as $key => $label): ?> - <option value="<?= $key ?>" <?= $exercise->task['input_width'] == $key ? 'selected' : '' ?>> + <option value="<?= $key ?>" <?= isset($exercise->task['input_width']) && $exercise->task['input_width'] == $key ? 'selected' : '' ?>> <?= htmlReady($label) ?> </option> <? endforeach ?> diff --git a/views/exercises/flexible_input.php b/views/exercises/flexible_input.php index fe70b51c802e7c2421945b8a1ca8de5b776a3636..d425a372d27a53797568108bb8a8ecea7974ad99 100644 --- a/views/exercises/flexible_input.php +++ b/views/exercises/flexible_input.php @@ -3,14 +3,17 @@ <? if ($size === 'small'): ?> <?= isset($name) ? 'name="'.$name.'"' : (isset($data_name) ? 'data-name="'.$data_name.'"' : '') ?> <? endif ?> - value="<?= htmlReady($value) ?>"> + <? if (isset($value)): ?> + value="<?= htmlReady($value) ?>" + <? endif ?> + > <div class="large_input"> <? $wysiwyg = isset($data_name) ? 'wysiwyg-hidden' : 'wysiwyg' ?> <textarea class="character_input <?= $wysiwyg ?> size-l" data-editor="removePlugins=studip-quote,studip-settings;toolbar=small" <? if ($size === 'large'): ?> <?= isset($name) ? 'name="'.$name.'"' : (isset($data_name) ? 'data-name="'.$data_name.'"' : '') ?> <? endif ?> - ><?= wysiwygReady($value) ?></textarea> + ><?= wysiwygReady(isset($value) ? $value : '') ?></textarea> </div> </div> <input type="image" class="textarea_toggle small_input" src="<?= vips_image_url('expand.svg') ?>" title="<?= _vips('Eingabefeld vergrößern') ?>"> diff --git a/views/exercises/lt_exercise/edit.php b/views/exercises/lt_exercise/edit.php index 8e85d839ed63f6086f15e6f06c7af2473d8de958..f6beb31b8110c5efe06036d3409b0031c0ffb9ab 100644 --- a/views/exercises/lt_exercise/edit.php +++ b/views/exercises/lt_exercise/edit.php @@ -94,5 +94,5 @@ <?= _vips('Erlaubte relative Abweichung vom korrekten Wert') ?> <br> <input type="text" class="size-s" style="display: inline; text-align: right;" - name="epsilon" value="<?= sprintf('%g', $exercise->task['epsilon'] * 100) ?>"> % + name="epsilon" value="<?= isset($exercise->task['epsilon']) ? sprintf('%g', $exercise->task['epsilon'] * 100) : '0' ?>"> % </label> diff --git a/views/exercises/print_exercise.php b/views/exercises/print_exercise.php index ca5c62fd149b30ce385bf70afd382924d70df4b7..555e0ef0598a9f81aa6621b7062a919e3457a22f 100644 --- a/views/exercises/print_exercise.php +++ b/views/exercises/print_exercise.php @@ -23,7 +23,7 @@ <?= $this->render_partial($exercise->getPrintTemplate($solution, $assignment, $user_id)) ?> - <? if ($solution->student_comment != '') : ?> + <? if ($solution && $solution->student_comment != '') : ?> <div class="label-text"> <?= _vips('Bemerkungen zur Lösung:') ?> </div> @@ -32,15 +32,15 @@ <? endif ?> <? if ($print_correction): ?> - <? if ($solution->corrector_comment != ''): ?> - <div class="label-text"> - <?= _vips('Anmerkung des Korrektors:') ?> - </div> + <? if ($solution): ?> + <? if ($solution->corrector_comment != ''): ?> + <div class="label-text"> + <?= _vips('Anmerkung des Korrektors:') ?> + </div> - <?= formatReady($solution->corrector_comment) ?> - <? endif ?> + <?= formatReady($solution->corrector_comment) ?> + <? endif ?> - <? if ($solution): ?> <?= $this->render_partial('solutions/feedback_files') ?> <? endif ?> diff --git a/views/solutions/assignments_list.php b/views/solutions/assignments_list.php index 174a6084c5a1f829cfc92086aa3282c62afb087e..e049b51ce359aac16583472aaf07a0bec6161c09 100644 --- a/views/solutions/assignments_list.php +++ b/views/solutions/assignments_list.php @@ -48,7 +48,7 @@ </thead> <? foreach ($blocks as $block) :?> - <? if ($block_assignments[$block->id] || $block->weight !== null): ?> + <? if (isset($block_assignments[$block->id]) || $block->weight !== null): ?> <tbody> <? if (count($blocks) > 1): ?> <tr class="header-row"> @@ -75,7 +75,7 @@ </tr> <? endif ?> - <? if ($block_assignments[$block->id]): ?> + <? if (isset($block_assignments[$block->id])): ?> <? foreach ($block_assignments[$block->id] as $ass): ?> <tr> <td> diff --git a/views/solutions/participants_overview.php b/views/solutions/participants_overview.php index 9f7b287317b5e2eb473704596323bfa6f0a87717..8d6350d4cea43eb839cfbcf443bbfc0368d4571c 100644 --- a/views/solutions/participants_overview.php +++ b/views/solutions/participants_overview.php @@ -165,33 +165,41 @@ <? foreach ($items as $category => $list) : ?> <? foreach ($list as $item) : ?> <td style="text-align: right; white-space: nowrap;"> - <? $percent = $p['items'][$category][$item['id']]['percent']; ?> - <? if ($display == 'points') : ?> - <span<? if (isset($percent)) : ?> title="<?= sprintf('%.1f %%', $percent) ?>"<? endif ?>> + <span + <? if (isset($p['items'][$category][$item['id']]['percent'])) : ?> + title="<?= sprintf(_vips('absolut: %.1f %%'), $p['items'][$category][$item['id']]['percent']) ?>" + <? endif ?>> + <? if ($display == 'points') : ?> <? if (isset($p['items'][$category][$item['id']]['points'])) : ?> <?= sprintf('%.1f', $p['items'][$category][$item['id']]['points']) ?> <? else : ?> – <? endif ?> - </span> - <? elseif ($display == 'weighting') : ?> - <span<? if (isset($percent)) : ?> title="<?= sprintf(_vips('absolut: %.1f %%'), $percent) ?>"<? endif ?>> + <? elseif ($display == 'weighting') : ?> <? if (isset($p['items'][$category][$item['id']]['weighting'])) : ?> <?= sprintf('%.1f %%', $p['items'][$category][$item['id']]['weighting']) ?> <? else : ?> – <? endif ?> - </span> - <? endif ?> + <? endif ?> + </span> </td> <? endforeach ?> <? endforeach ?> <td style="text-align: right; white-space: nowrap;"> <? if ($display == 'points') : ?> - <?= sprintf('%.1f', $p['overall']['points']) ?> + <? if (isset($p['overall']['points'])): ?> + <?= sprintf('%.1f', $p['overall']['points']) ?> + <? else: ?> + – + <? endif ?> <? elseif ($display == 'weighting') : ?> - <?= sprintf('%.1f %%', $p['overall']['weighting']) ?> + <? if (isset($p['overall']['weighting'])): ?> + <?= sprintf('%.1f %%', $p['overall']['weighting']) ?> + <? else: ?> + – + <? endif ?> <? endif ?> </td>