Skip to content

Commit 7e1a483

Browse files
Merge pull request #6549 from christianbeeznest/GH-2939
Exercise: Implement Page Break question type and AJAX navigation - refs #2939
2 parents ad7a1f2 + edf18c2 commit 7e1a483

File tree

16 files changed

+721
-237
lines changed

16 files changed

+721
-237
lines changed

assets/css/app.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,12 @@ img.course-tool__icon {
912912
.chosen { outline: 2px solid #ddd; }
913913
.dragging { outline: 2px solid var(--support-5, #f60); }
914914

915+
.media-group { border:2px solid #337ab7; background:#f5fafd; padding:1rem; margin:2rem 0; border-radius:4px; }
916+
.media-content { margin-bottom:1rem; }
917+
.media-description { font-style:italic; margin-bottom:1rem; }
918+
.media-children { margin-left:1rem; }
919+
.media-group h4 { margin-top:0; color:#23527c; }
920+
915921
@import "~@fancyapps/fancybox/dist/jquery.fancybox.css";
916922
@import "~timepicker/jquery.timepicker.min.css";
917923
@import "~qtip2/dist/jquery.qtip.min.css";

public/img/icons/22/media.png

5.09 KB
Loading

public/img/icons/22/page_break.png

5.01 KB
Loading

public/img/icons/64/media.png

6.27 KB
Loading

public/img/icons/64/page_break.png

6.01 KB
Loading
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
/* For licensing terms, see /license.txt */
3+
4+
class MediaQuestion extends Question
5+
{
6+
/**
7+
* Icon shown in the question-type menu.
8+
*/
9+
public $typePicture = 'media.png';
10+
public $explanationLangVar = 'MediaQuestion';
11+
12+
public function __construct()
13+
{
14+
parent::__construct();
15+
$this->type = MEDIA_QUESTION;
16+
// Mark as content so it’s not counted towards score
17+
$this->isContent = 1;
18+
}
19+
20+
/**
21+
* Form to create / edit a Media item.
22+
*/
23+
public function createForm(&$form, $exercise)
24+
{
25+
// Title for the media block
26+
$form->addText(
27+
'questionName',
28+
get_lang('Media Title'),
29+
false,
30+
['maxlength' => 255]
31+
);
32+
33+
// WYSIWYG for the media content (could be text, embed code, etc.)
34+
$editorConfig = [
35+
'ToolbarSet' => 'TestQuestionDescription',
36+
'Height' => '150'
37+
];
38+
$form->addHtmlEditor(
39+
'questionDescription',
40+
get_lang('Media Content'),
41+
false,
42+
false,
43+
$editorConfig
44+
);
45+
46+
global $text;
47+
$form->addButtonSave($text, 'submitQuestion');
48+
49+
// Populate defaults if editing
50+
$defaults = [
51+
'questionName' => $this->question,
52+
'questionDescription' => $this->description
53+
];
54+
$form->setDefaults($defaults);
55+
}
56+
57+
/**
58+
* No answers to configure for media.
59+
*/
60+
public function createAnswersForm($form) {}
61+
62+
public function processAnswersCreation($form, $exercise) {}
63+
64+
/**
65+
* On save, treat like any other question: persist and attach to the exercise.
66+
*/
67+
public function processCreation(FormValidator $form, Exercise $exercise)
68+
{
69+
$this->updateTitle($form->getSubmitValue('questionName'));
70+
$this->updateDescription($form->getSubmitValue('questionDescription'));
71+
$this->save($exercise);
72+
$exercise->addToList($this->id);
73+
}
74+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/* For licensing terms, see /license.txt */
3+
4+
class PageBreakQuestion extends Question
5+
{
6+
public $typePicture = 'page_break.png';
7+
public $explanationLangVar = 'PageBreak';
8+
9+
public function __construct()
10+
{
11+
parent::__construct();
12+
$this->type = PAGE_BREAK;
13+
$this->isContent = 1;
14+
}
15+
16+
public function createForm(&$form, $exercise)
17+
{
18+
$form->addText(
19+
'questionName',
20+
get_lang('Page Title'),
21+
false,
22+
['maxlength' => 255]
23+
);
24+
$editorConfig = [
25+
'ToolbarSet' => 'TestQuestionDescription',
26+
'Height' => '100'
27+
];
28+
$form->addHtmlEditor(
29+
'questionDescription',
30+
get_lang('Page Introduction'),
31+
false,
32+
false,
33+
$editorConfig
34+
);
35+
36+
global $text;
37+
$form->addButtonSave($text, 'submitQuestion');
38+
39+
$defaults = [
40+
'questionName' => $this->question,
41+
'questionDescription' => $this->description
42+
];
43+
$form->setDefaults($defaults);
44+
}
45+
46+
public function createAnswersForm($form) {}
47+
48+
public function processAnswersCreation($form, $exercise) {}
49+
50+
public function processCreation(FormValidator $form, Exercise $exercise)
51+
{
52+
$this->updateTitle($form->getSubmitValue('questionName'));
53+
$this->updateDescription($form->getSubmitValue('questionDescription'));
54+
$this->save($exercise);
55+
$exercise->addToList($this->id);
56+
}
57+
}

public/main/exercise/exercise.class.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,6 +3143,19 @@ public function save_stat_track_exercise_info(
31433143
$clock_expired_time = null;
31443144
}
31453145

3146+
$questionList = array_filter(
3147+
$questionList,
3148+
function (int $qid) {
3149+
$q = Question::read($qid);
3150+
return $q
3151+
&& !in_array(
3152+
$q->type,
3153+
[PAGE_BREAK, MEDIA_QUESTION],
3154+
true
3155+
);
3156+
}
3157+
);
3158+
31463159
$questionList = array_map('intval', $questionList);
31473160
$em = Database::getManager();
31483161

@@ -5885,6 +5898,13 @@ public function manage_answer(
58855898
// Store results directly in the database
58865899
// For all in one page exercises, the results will be
58875900
// stored by exercise_results.php (using the session)
5901+
if (in_array(
5902+
$objQuestionTmp->type,
5903+
[PAGE_BREAK, MEDIA_QUESTION],
5904+
true
5905+
)) {
5906+
$save_results = false;
5907+
}
58885908
if ($save_results) {
58895909
if ($debug) {
58905910
error_log("Save question results $save_results");

public/main/exercise/exercise_show.php

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ function getFCK(vals, marksid) {
404404
$marksid = '';
405405

406406
$countPendingQuestions = 0;
407+
$panelsByParent = [];
407408
foreach ($questionList as $questionId) {
408409
$choice = isset($exerciseResult[$questionId]) ? $exerciseResult[$questionId] : '';
409410
// destruction of the Question object
@@ -419,6 +420,11 @@ function getFCK(vals, marksid) {
419420
$questionWeighting = $objQuestionTmp->selectWeighting();
420421
$answerType = $objQuestionTmp->selectType();
421422

423+
$objQ = Question::read($questionId, $objExercise->course);
424+
if (!$objQ || $objQ->type === MEDIA_QUESTION) {
425+
continue;
426+
}
427+
422428
// Start buffer
423429
ob_start();
424430
if (MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE == $answerType) {
@@ -882,7 +888,10 @@ class="exercise_mark_select"
882888
$counter++;
883889
$questionContent .= $contents;
884890
$questionContent .= '</div>';
885-
$exercise_content .= Display::panel($questionContent);
891+
//$exercise_content .= Display::panel($questionContent);
892+
$panelHtml = Display::panel($questionContent);
893+
$parentId = (int) $objQ->parent_id;
894+
$panelsByParent[$parentId][] = $panelHtml;
886895
} // end of large foreach on questions
887896

888897
// Display the text when finished message if we are on a LP #4227
@@ -966,7 +975,44 @@ class="exercise_mark_select"
966975
}
967976

968977
echo $totalScoreText;
969-
echo $exercise_content;
978+
//echo $exercise_content;
979+
foreach ($panelsByParent as $pid => $panels) {
980+
if ($pid !== 0) {
981+
$mediaQ = Question::read($pid, $objExercise->course);
982+
echo '<div class="media-group">';
983+
echo '<div class="media-content">';
984+
ob_start();
985+
$objExercise->manage_answer(
986+
$id,
987+
$pid,
988+
null,
989+
'exercise_show',
990+
[],
991+
false,
992+
true,
993+
$show_results,
994+
$objExercise->selectPropagateNeg()
995+
);
996+
echo ob_get_clean();
997+
echo '</div>';
998+
999+
if (!empty($mediaQ->question)) {
1000+
echo '<div class="media-description">';
1001+
echo $mediaQ->description;
1002+
echo '</div>';
1003+
}
1004+
1005+
echo '<div class="media-children">';
1006+
}
1007+
1008+
foreach ($panels as $panelHtml) {
1009+
echo $panelHtml;
1010+
}
1011+
1012+
if ($pid !== 0) {
1013+
echo '</div></div>';
1014+
}
1015+
}
9701016

9711017
// only show "score" in bottom of page if there's exercise content
9721018
if ($show_results) {

0 commit comments

Comments
 (0)