';
+ $showMedia = false;
+
+ $counterToShow = $counter;
+
+ if ($objQuestionTmp->parent_id != 0) {
+
+ if (!in_array($objQuestionTmp->parent_id, $media_list)) {
+ $media_list[] = $objQuestionTmp->parent_id;
+ $show_media = true;
+ }
+ if ($tempParentId == $objQuestionTmp->parent_id) {
+ $mediaCounter++;
+ } else {
+ $mediaCounter = 0;
+ }
+ $counterToShow = chr(97 + $mediaCounter);
+ $tempParentId = $objQuestionTmp->parent_id;
+ }
+
if ($show_results && $objQuestionTmp) {
$objQuestionTmp->export = $action === 'export';
// Shows question title an description
$question_content .= $objQuestionTmp->return_header(
$objExercise,
$counter,
- $score
+ $score,
+ $showMedia,
+ $mediaCounter
);
}
$counter++;
diff --git a/main/exercise/exercise_submit.php b/main/exercise/exercise_submit.php
index 5060cbb3e6d..f8ee1a9c872 100755
--- a/main/exercise/exercise_submit.php
+++ b/main/exercise/exercise_submit.php
@@ -372,6 +372,7 @@
// Fix in order to get the correct question list.
$questionListUncompressed = $objExercise->getQuestionListWithMediasUncompressed();
Session::write('question_list_uncompressed', $questionListUncompressed);
+
$clock_expired_time = null;
if (empty($exercise_stat_info)) {
$disable = api_get_configuration_value('exercises_disable_new_attempts');
@@ -379,7 +380,7 @@
api_not_allowed(true);
}
$total_weight = 0;
- $questionList = $objExercise->get_validated_question_list();
+ $questionList = $objExercise->get_question_list(true);
foreach ($questionListUncompressed as $question_id) {
$objQuestionTmp = Question::read($question_id);
$total_weight += (float) $objQuestionTmp->weighting;
@@ -614,13 +615,18 @@
//Sends the exercise form when the expired time is finished.
$htmlHeadXtra[] = $objExercise->showTimeControlJS($time_left);
}
-// in LP's is enabled the "remember question" feature?
+
+$media_questions = $objExercise->getMediaList();
+$media_question_is_active = $objExercise->mediaIsActivated($media_questions);
+
+// If the "remind question" option is enabled, in learning path
if (!isset($_SESSION['questionList'])) {
// selects the list of question ID
- $questionList = $objExercise->get_validated_question_list();
- if ($objExercise->isRandom() && !empty($exercise_stat_info['data_tracking'])) {
+ $questionList = $objExercise->get_question_list(false);
+ if ($media_is_activated == false && $objExercise->isRandom() && !empty($exercise_stat_info['data_tracking'])) {
$questionList = explode(',', $exercise_stat_info['data_tracking']);
}
+
Session::write('questionList', $questionList);
} else {
if (isset($objExercise) && isset($_SESSION['objExercise'])) {
@@ -733,6 +739,10 @@
if (!empty($questionList)) {
$question_count = count($questionList);
}
+if ($media_question_is_active) {
+ $question_count = $objExercise->get_count_questions_when_using_medias();
+}
+
if ($current_question > $question_count) {
// If time control then don't change the current question, otherwise there will be a loop.
@@ -1468,6 +1478,7 @@ function save_now(question_id, url_extra) {
$("#save_for_now_"+question_id).html(\''.$loading.'\');
$.ajax({
type:"post",
+ async: false,
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&a=save_exercise_by_now",
data: dataparam,
success: function(return_value) {
@@ -1596,6 +1607,7 @@ function save_now_all(validate) {
$.ajax({
type:"post",
+ async: false,
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&a=save_exercise_by_now",
data: requestData,
success: function(return_value) {
@@ -1651,214 +1663,216 @@ function validate_all() {
) {
$remind_list = explode(',', $exercise_stat_info['questions_to_check']);
}
+render_question_list(
+ $objExercise,
+ $questionList,
+ $current_question,
+ $exerciseResult,
+ $attempt_list,
+ $remind_list,
+ $media_questions
+);
+echo '';
-foreach ($questionList as $questionId) {
- // for sequential exercises
- if (ONE_PER_PAGE == $objExercise->type) {
- // if it is not the right question, goes to the next loop iteration
- if ($current_question != $i) {
- $i++;
- continue;
- } else {
- if (!in_array($objExercise->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
- // if the user has already answered this question
- if (isset($exerciseResult[$questionId])) {
- // construction of the Question object
- $objQuestionTmp = Question::read($questionId);
- $questionName = $objQuestionTmp->selectTitle();
- // destruction of the Question object
- unset($objQuestionTmp);
- echo Display::return_message(get_lang('AlreadyAnswered'));
- $i++;
- break;
+function render_question_list(
+ $objExercise,
+ $questionList,
+ $current_question,
+ $exerciseResult,
+ $attempt_list,
+ $remind_list,
+ $media_questions = [],
+ $exerciseInSession,
+ $learnpath_id = null,
+ $learnpath_item_id = null,
+ $learnpath_item_view_id = null,
+ $myRemindList = [],
+ $showPreviousButton = false
+) {
+ global $origin;
+
+ $i = 1;
+
+ //Normal question list render
+ foreach ($questionList as $questionId) {
+ // for sequential exercises
+ if (ONE_PER_PAGE == $objExercise->type) {
+ // if it is not the right question, goes to the next loop iteration
+ if ($current_question != $i) {
+ $i++;
+ continue;
+ } else {
+ if (!in_array($objExercise->getFeedbackType(),
+ [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
+ // if the user has already answered this question
+ if (isset($exerciseResult[$questionId])) {
+ // construction of the Question object
+ $objQuestionTmp = Question::read($questionId);
+ //$questionName = $objQuestionTmp->selectTitle();
+ // destruction of the Question object
+ unset($objQuestionTmp);
+ echo Display::return_message(get_lang('AlreadyAnswered'));
+ $i++;
+ break;
+ }
}
- }
- if (1 === $exerciseInSession->getPreventBackwards()) {
- if (isset($attempt_list[$questionId])) {
- echo Display::return_message(get_lang('AlreadyAnswered'));
- $i++;
- break;
+ if (1 === $exerciseInSession->getPreventBackwards()) {
+ if (isset($attempt_list[$questionId])) {
+ echo Display::return_message(get_lang('AlreadyAnswered'));
+ $i++;
+ break;
+ }
}
}
}
- }
- $user_choice = null;
- if (isset($attempt_list[$questionId])) {
- $user_choice = $attempt_list[$questionId];
- } elseif ($objExercise->getSaveCorrectAnswers()) {
- $correctAnswers = [];
- switch ($objExercise->getSaveCorrectAnswers()) {
- case 1:
- $correctAnswers = $objExercise->getCorrectAnswersInAllAttempts(
- $learnpath_id,
- $learnpath_item_id
- );
- break;
- case 2:
- $correctAnswers = $objExercise->getAnswersInAllAttempts(
- $learnpath_id,
- $learnpath_item_id,
- false
- );
- break;
+
+ // Media question rendering
+
+ if (isset($media_questions) && !empty($media_questions)) {
+ $media_question_list = $media_questions[$questionId];
+ $objQuestionTmp = Question::read($questionId);
+
+ $counter = 1;
+ if ($objQuestionTmp->type == MEDIA_QUESTION) {
+ echo $objQuestionTmp->show_media_content();
+ $count_of_questions_inside_media = count($media_question_list);
+
+ }
+ //Show questions that belongs to a media
+ if (!empty($media_question_list)) {
+ $letterCounter = 97;
+ foreach ($media_question_list as $my_question_id) {
+ if ($counter == $count_of_questions_inside_media) {
+ $last_question_in_media = true;
+ }
+ render_question(
+ $objExercise,
+ $my_question_id,
+ $attempt_list,
+ $remind_list,
+ chr($letterCounter),
+ $current_question,
+ true,
+ $count_of_questions_inside_media,
+ $last_question_in_media
+ );
+ $letterCounter++;
+ $counter++;
+ }
+ } else {
+ render_question($objExercise, $questionId, $attempt_list, $remind_list, $i, $current_question);
+ }
+ } else {
+ // Normal question rendering
+ render_question($objExercise, $questionId, $attempt_list, $remind_list, $i, $current_question);
}
- if (isset($correctAnswers[$questionId])) {
- $user_choice = $correctAnswers[$questionId];
+ $i++;
+ // for sequential exercises
+ if ($objExercise->type == ONE_PER_PAGE) {
+ // quits the loop
+ break;
}
}
- $remind_highlight = '';
- // Hides questions when reviewing a ALL_ON_ONE_PAGE exercise see #4542 no_remind_highlight class hide with jquery
- if ($objExercise->type == ALL_ON_ONE_PAGE &&
- isset($_GET['reminder']) && $_GET['reminder'] == 2
- ) {
+ if ($objExercise->type == ALL_ON_ONE_PAGE) {
+ $exerciseActions = $objExercise->show_button(
+ $questionId,
+ $current_question,
+ [],
+ '',
+ [],
+ true,
+ $learnpath_id,
+ $learnpath_item_id,
+ $learnpath_item_view_id
+ );
+ echo Display::div($exerciseActions, ['class' => 'exercise_actions']);
+ echo '
';
+ }
+}
+
+function render_question(
+ $objExercise,
+ $questionId,
+ $attempt_list,
+ $remind_list,
+ $i,
+ $current_question,
+ $question_in_media = [],
+ $last_question_in_media = false
+) {
+ global $origin;
+ $user_choice = $attempt_list[$questionId];
+
+ $remind_highlight = null;
+
+ //Hides questions when reviewing a ALL_ON_ONE_PAGE exercise see #4542 no_remind_highlight class hide with jquery
+ if ($objExercise->type == ALL_ON_ONE_PAGE && isset($_GET['reminder']) && $_GET['reminder'] == 2) {
$remind_highlight = 'no_remind_highlight';
}
- $exerciseActions = '';
+
+ $attributes = array('id' => 'remind_list['.$questionId.']');
+
$is_remind_on = false;
- $attributes = ['id' => 'remind_list['.$questionId.']'];
if (in_array($questionId, $remind_list)) {
$is_remind_on = true;
$attributes['checked'] = 1;
- $remind_question = true;
$remind_highlight = ' remind_highlight ';
}
- $openDescription = api_get_configuration_value('quiz_question_description_open_by_default') ? true : false;
-
- // Showing the exercise description
- if (!empty($objExercise->description)) {
- if ($objExercise->type == ONE_PER_PAGE || ($objExercise->type != ONE_PER_PAGE && $i == 1)) {
- echo Display::panelCollapse(
- '
'.get_lang('ExerciseDescriptionLabel').'',
- Security::remove_XSS($objExercise->description, COURSEMANAGERLOWSECURITY),
- 'exercise-description',
- [],
- 'description',
- 'exercise-collapse',
- $openDescription,
- true
- );
- }
- }
+ //Showing the question
- echo '
';
- $showQuestion = true;
- $exerciseResultFromSession = Session::read('exerciseResult');
- if ($objExercise->getFeedbackType() === EXERCISE_FEEDBACK_TYPE_POPUP &&
- isset($exerciseResultFromSession[$questionId])
- ) {
- $showQuestion = false;
- }
+ $exercise_actions = null;
- // Shows the question and its answers
- if ($showQuestion) {
- ExerciseLib::showQuestion(
- $objExercise,
- $questionId,
- false,
- $origin,
- $i,
- $objExercise->getHideQuestionTitle() ? false : true,
- false,
- $user_choice,
- false,
- null,
- false,
- true
- );
- } else {
- echo Display::return_message(get_lang('AlreadyAnswered'));
- }
+ echo '
';
+
+ // Shows the question + possible answers
+ showQuestion($questionId, false, $origin, $i, true, false, $user_choice, false);
- // Button save and continue
+ // Button to save and continue
switch ($objExercise->type) {
case ONE_PER_PAGE:
- $exerciseActions .= $objExercise->show_button(
- $questionId,
- $current_question,
- [],
- [],
- $myRemindList,
- $showPreviousButton,
- $learnpath_id,
- $learnpath_item_id,
- $learnpath_item_view_id
- );
+ $exercise_actions .= $objExercise->show_button($questionId, $current_question);
break;
- case ALL_ON_ONE_PAGE:
- if (api_is_allowed_to_session_edit()) {
- $button = [
- Display::button(
- 'save_now',
- get_lang('SaveForNow'),
- [
- 'type' => 'button',
- 'class' => 'btn btn-info',
- 'data-question' => $questionId,
- ]
- ),
- '
',
- ];
- $exerciseActions .= Display::div(
- implode(PHP_EOL, $button),
- ['class' => 'exercise_save_now_button']
- );
- }
+ case ALL_ON_ONE_PAGE :
+ $button = '
'.get_lang('SaveForNow').'';
+ $button .= '
';
+ $exercise_actions .= Display::div($button, array('class' => 'exercise_save_now_button'));
break;
}
- // Checkbox review answers
- if ($objExercise->review_answers) {
- $remind_question_div = Display::tag(
- 'label',
- Display::input(
- 'checkbox',
- 'remind_list['.$questionId.']',
- '',
- $attributes
- ).get_lang('ReviewQuestionLater'),
- [
- 'class' => 'checkbox',
- 'for' => 'remind_list['.$questionId.']',
- ]
- );
- $exerciseActions .= Display::div(
- $remind_question_div,
- ['class' => 'exercise_save_now_button']
- );
+ if (!empty($questions_in_media)) {
+ /*$button = '
'.get_lang('SaveForNow').'';
+ $button .= '
';
+ $exercise_actions = Display::div($button, array('class'=>'exercise_save_now_button'));
+ $exercise_actions .= $objExercise->show_button($questionId, $current_question);*/
+ $count_of_questions_inside_media = count($questions_in_media);
+ if ($count_of_questions_inside_media > 1) {
+ $button = '
'.get_lang('SaveForNow').'';
+ $button .= '
';
+ $exercise_actions = Display::div($button, array('class' => 'exercise_save_now_button'));
+ }
+
+ if ($last_question_in_media) {
+ $exercise_actions = $objExercise->show_button($questionId, $current_question, $questions_in_media);
+ }
}
- echo Display::div($exerciseActions, ['class' => 'form-actions']);
- echo '
';
- $i++;
- // for sequential exercises
- if ($objExercise->type == ONE_PER_PAGE) {
- // quits the loop
- break;
+ //Checkbox review answers
+ if ($objExercise->review_answers) {
+ $remind_question_div = Display::tag('label',
+ Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes).get_lang('ReviewQuestionLater'),
+ array('class' => 'checkbox', 'for' => 'remind_list['.$questionId.']'));
+ $exercise_actions .= Display::div($remind_question_div, array('class' => 'exercise_save_now_button'));
}
-}
-if ($objExercise->type == ALL_ON_ONE_PAGE) {
- $exerciseActions = $objExercise->show_button(
- $questionId,
- $current_question,
- [],
- '',
- [],
- true,
- $learnpath_id,
- $learnpath_item_id,
- $learnpath_item_view_id
- );
- echo Display::div($exerciseActions, ['class' => 'exercise_actions']);
- echo '
';
+ echo Display::div($exercise_actions, array('class' => 'form-actions'));
+ echo '
';
}
-echo '';
if (!in_array($origin, ['learnpath', 'embeddable', 'iframe'])) {
// So we are not in learnpath tool
diff --git a/main/exercise/fill_blanks.class.php b/main/exercise/fill_blanks.class.php
index d9d27207beb..af51ecf3474 100755
--- a/main/exercise/fill_blanks.class.php
+++ b/main/exercise/fill_blanks.class.php
@@ -512,9 +512,9 @@ function ($matches) use ($blankStartSeparator, $blankEndSeparator) {
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '
'.get_lang('Answer').' |
diff --git a/main/exercise/freeanswer.class.php b/main/exercise/freeanswer.class.php
index 093039cc909..126622146f2 100755
--- a/main/exercise/freeanswer.class.php
+++ b/main/exercise/freeanswer.class.php
@@ -54,10 +54,10 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
$score['revised'] = $this->isQuestionWaitingReview($score);
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '
'.get_lang('Answer').' |
diff --git a/main/exercise/global_multiple_answer.class.php b/main/exercise/global_multiple_answer.class.php
index 46b4092d269..75694bdd112 100755
--- a/main/exercise/global_multiple_answer.class.php
+++ b/main/exercise/global_multiple_answer.class.php
@@ -252,9 +252,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
if (!in_array($exercise->results_disabled, [RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER])) {
diff --git a/main/exercise/matching.class.php b/main/exercise/matching.class.php
index d28cba7f13f..8b80b922dd5 100755
--- a/main/exercise/matching.class.php
+++ b/main/exercise/matching.class.php
@@ -299,9 +299,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
$header .= '';
diff --git a/main/exercise/multiple_answer.class.php b/main/exercise/multiple_answer.class.php
index 3f33e6a51ba..04e4dd93225 100755
--- a/main/exercise/multiple_answer.class.php
+++ b/main/exercise/multiple_answer.class.php
@@ -276,9 +276,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
$header .= ''.get_lang('Choice').' | ';
diff --git a/main/exercise/multiple_answer_combination.class.php b/main/exercise/multiple_answer_combination.class.php
index a951b2c7bd0..4cc69f361a3 100755
--- a/main/exercise/multiple_answer_combination.class.php
+++ b/main/exercise/multiple_answer_combination.class.php
@@ -225,9 +225,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
if (!in_array($exercise->results_disabled, [
diff --git a/main/exercise/multiple_answer_true_false.class.php b/main/exercise/multiple_answer_true_false.class.php
index b971ef4d087..94a2272cfb1 100755
--- a/main/exercise/multiple_answer_true_false.class.php
+++ b/main/exercise/multiple_answer_true_false.class.php
@@ -315,9 +315,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
if (!in_array($exercise->results_disabled, [
diff --git a/main/exercise/oral_expression.class.php b/main/exercise/oral_expression.class.php
index a1166d1c1f1..d68a066c8e7 100755
--- a/main/exercise/oral_expression.class.php
+++ b/main/exercise/oral_expression.class.php
@@ -66,10 +66,10 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
$score['revised'] = $this->isQuestionWaitingReview($score);
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '
'.get_lang("Answer").' |
diff --git a/main/exercise/question.class.php b/main/exercise/question.class.php
index 6ecce2e3729..fd793020675 100755
--- a/main/exercise/question.class.php
+++ b/main/exercise/question.class.php
@@ -69,7 +69,7 @@ abstract class Question
DRAGGABLE => ['Draggable.php', 'Draggable'],
MATCHING_DRAGGABLE => ['MatchingDraggable.php', 'MatchingDraggable'],
MATCHING_DRAGGABLE_COMBINATION => ['MatchingDraggableCombination.php', 'MatchingDraggableCombination'],
- //MEDIA_QUESTION => array('media_question.class.php' , 'MediaQuestion')
+ MEDIA_QUESTION => ['media_question.class.php' , 'MediaQuestion'],
ANNOTATION => ['Annotation.php', 'Annotation'],
READING_COMPREHENSION => ['ReadingComprehension.php', 'ReadingComprehension'],
UPLOAD_ANSWER => ['UploadAnswer.php', 'UploadAnswer'],
@@ -179,6 +179,7 @@ public static function read($id, $course_info = [], $getExerciseList = true)
$objQuestion->course = $course_info;
$objQuestion->feedback = isset($object->feedback) ? $object->feedback : '';
$objQuestion->code = isset($object->code) ? $object->code : '';
+ $objQuestion->parent_id = $object->parent_id;
$categoryInfo = TestCategory::getCategoryInfoForQuestion($id, $course_id);
if (!empty($categoryInfo)) {
@@ -1022,6 +1023,7 @@ public function save($exercise)
$extra = $this->extra;
$c_id = $this->course['real_id'];
$categoryId = $this->category;
+ $parent_id = $this->parent_id;
// question already exists
if (!empty($id)) {
@@ -1034,6 +1036,7 @@ public function save($exercise)
'picture' => $picture,
'extra' => $extra,
'level' => $level,
+ 'parent_id' => $parent_id,
];
if ($exercise->questionFeedbackEnabled) {
$params['feedback'] = $this->feedback;
@@ -1088,6 +1091,7 @@ public function save($exercise)
'picture' => $picture,
'extra' => $extra,
'level' => $level,
+ 'parent_id' => $parent_id,
];
if ($exercise->questionFeedbackEnabled) {
@@ -1445,6 +1449,18 @@ public function delete(int $deleteFromEx = 0, bool $deletePicture = true): bool
$id = (int) $this->iid;
+ if ($this->type == MEDIA_QUESTION) {
+ // Removing media for attached questions
+
+ $sql = "UPDATE $TBL_QUESTIONS SET parent_id = '' WHERE parent_id = $id";
+ Database::query($sql);
+
+ $sql = "DELETE FROM $TBL_QUESTIONS WHERE c_id = $courseId AND iid= ".Database::escape_string($id);
+ Database::query($sql);
+ return true;
+ }
+
+
// if the question must be removed from all exercises
if (!$deleteFromEx) {
$courseFilter = " AND c_id = $courseId";
@@ -1568,6 +1584,7 @@ public function duplicate($courseInfo = [])
$type = $this->type;
$level = (int) $this->level;
$extra = $this->extra;
+ $parent_id = $this->parent_id;
// Using the same method used in the course copy to transform URLs
if ($this->course['id'] != $courseInfo['id']) {
@@ -1598,6 +1615,7 @@ public function duplicate($courseInfo = [])
'type' => $type,
'level' => $level,
'extra' => $extra,
+ 'parent_id' => $parent_id,
];
$newQuestionId = Database::insert($questionTable, $params);
@@ -1814,6 +1832,9 @@ public function createForm(&$form, $exercise)
$editorConfig
);
+ // hidden value
+ $form->addElement('hidden', 'myid', intval($_REQUEST['myid']));
+
if ($this->type != MEDIA_QUESTION) {
// Advanced parameters.
$form->addElement(
@@ -1831,6 +1852,16 @@ public function createForm(&$form, $exercise)
TestCategory::getCategoriesIdAndName()
);
+ // Media
+ $course_medias = Question::prepare_course_media_select(api_get_course_int_id());
+ $form->addElement(
+ 'select',
+ 'parent_id',
+ get_lang('AttachToMedia'),
+ $course_medias,
+ ['id' => 'parent_id']
+ );
+
if (EX_Q_SELECTION_CATEGORIES_ORDERED_QUESTIONS_RANDOM == $exercise->getQuestionSelectionType() &&
api_get_configuration_value('allow_mandatory_question_in_category')
) {
@@ -1934,7 +1965,7 @@ public function createForm(&$form, $exercise)
// default values
- // Came from he question pool
+ // Came from the question pool
if (isset($_GET['fromExercise'])
|| (!isset($_GET['newQuestion']) || $isContent)
) {
@@ -1986,6 +2017,7 @@ public function createForm(&$form, $exercise)
*/
public function processCreation($form, $exercise)
{
+ //$this->updateParentId($form->getSubmitValue('parent_id'));
$this->updateTitle($form->getSubmitValue('questionName'));
$this->updateDescription($form->getSubmitValue('questionDescription'));
$this->updateLevel($form->getSubmitValue('questionLevel'));
@@ -2219,7 +2251,7 @@ public static function readQuestionOption($question_id, $course_id)
*
* @return string HTML string with the header of the question (before the answers table)
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
$counterLabel = '';
if (!empty($counter)) {
@@ -2298,8 +2330,7 @@ public function return_header(Exercise $exercise, $counter = null, $score = [])
if ($exercise->display_category_name) {
$header = TestCategory::returnCategoryAndTitle($this->iid);
}
- $show_media = '';
- if ($show_media) {
+ if ($showMedia) {
$header .= $this->show_media_content();
}
@@ -2863,4 +2894,122 @@ private function resizePicture($Dimension, $Max)
return false;
}
+
+ public static function getMediaLabels() {
+ // Shows media questions
+ $courseMedias = Question::prepare_course_media_select(api_get_course_int_id());
+ $labels = null;
+ if (!empty($courseMedias)) {
+ $labels .= get_lang('MediaQuestion').' ';
+ foreach ($courseMedias as $mediaId => $media) {
+
+ $editLink = ''.Display::return_icon('edit.png',get_lang('Modify'), array(), ICON_SIZE_SMALL).'';
+ $deleteLink = ''.Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL).'';
+
+ if (!empty($mediaId)) {
+ $labels .= Display::label($media).$editLink.$deleteLink.' ';
+ }
+ }
+ }
+
+ return $labels;
+ }
+
+ static function getMediaLabel($title) {
+ return Display::label($title, 'warning');
+ }
+
+ /**
+ * @param $exerciseId
+ * @param $mediaId
+ * @return array|bool
+ */
+ public function getQuestionsPerMediaWithCategories($exerciseId, $mediaId)
+ {
+ $exerciseId = intval($exerciseId);
+ $mediaId = intval($mediaId);
+ $questionTable = Database::get_course_table(TABLE_QUIZ_QUESTION);
+ $questionRelExerciseTable = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
+
+ $sql = "SELECT * FROM $questionTable q INNER JOIN $questionRelExerciseTable r ON (q.iid = r.question_id)
+ WHERE (r.exercise_id = $exerciseId AND q.parent_id = $mediaId) ";
+
+ $result = Database::query($sql);
+ if (Database::num_rows($result)) {
+ return Database::store_result($result);
+ }
+ return false;
+ }
+ /**
+ * @param int $exerciseId
+ * @param int $mediaId
+ * @return array
+ */
+ public function getQuestionCategoriesOfMediaQuestions($exerciseId, $mediaId)
+ {
+ $questions = $this->getQuestionsPerMediaWithCategories($exerciseId, $mediaId);
+ $questionCategoryList = array();
+ if (!empty($questions)) {
+ foreach ($questions as $question) {
+ $categories = TestCategory::getCategoryForQuestionWithCategoryData($question['iid']);
+ if (!empty($categories)) {
+ foreach ($categories as $category) {
+ $questionCategoryList[$question['iid']][] = $category['iid'];
+ }
+ }
+ }
+ }
+ return $questionCategoryList;
+ }
+
+ /**
+ * @param int $exerciseId
+ * @param int $mediaId
+ * @return array
+ */
+ public function allQuestionWithMediaHaveTheSameCategory($exerciseId, $mediaId, $categoryListToCompare = array(), $ignoreQuestionId = null, $returnCategoryId = false)
+ {
+ $questions = $this->getQuestionCategoriesOfMediaQuestions($exerciseId, $mediaId);
+ $result = false;
+ $categoryId = null;
+ if (empty($questions)) {
+ $result = true;
+ } else {
+ $tempArray = array();
+ foreach ($questions as $categories) {
+ $diff = array_diff($tempArray, $categories);
+ $categoryId = $categories[0];
+ $tempArray = $categories;
+ if (empty($diff)) {
+ $result = true;
+ continue;
+ } else {
+ $result = false;
+ break;
+ }
+ }
+ }
+ if (isset($categoryListToCompare) && !empty($categoryListToCompare)) {
+ $result = false;
+ foreach ($questions as $questionId => $categories) {
+ if ($ignoreQuestionId == $questionId) {
+ continue;
+ }
+ $diff = array_diff($categoryListToCompare, $categories);
+ $categoryId = $categories[0];
+ if (empty($diff)) {
+ $result = true;
+ continue;
+ } else {
+ $result = false;
+ break;
+ }
+ }
+ }
+
+ if ($returnCategoryId) {
+ return $categoryId;
+ }
+ return $result;
+ }
}
diff --git a/main/exercise/question_admin.inc.php b/main/exercise/question_admin.inc.php
index 2560d044104..c8ab543c9d5 100755
--- a/main/exercise/question_admin.inc.php
+++ b/main/exercise/question_admin.inc.php
@@ -51,41 +51,91 @@
}
// FORM VALIDATION
+ //$result = $objQuestion->allQuestionWithMediaHaveTheSameCategory($exerciseId, 100);
+
if (isset($_POST['submitQuestion'])) {
- $validationResult = true;
- if (method_exists($objQuestion, 'validateAnswers')) {
- $validationResult = $objQuestion->validateAnswers($form);
- }
- if (is_array($validationResult) && !empty($validationResult['errors'])) {
- echo Display::return_message(implode("
", $validationResult['errors']), 'error', false);
- } elseif ($form->validate()) {
- $objQuestion->processCreation($form, $objExercise);
- $objQuestion->processAnswersCreation($form, $objExercise);
- if (in_array($objQuestion->type, [HOT_SPOT, HOT_SPOT_COMBINATION, HOT_SPOT_DELINEATION])) {
- echo '';
- } elseif (in_array($objQuestion->type, [MULTIPLE_ANSWER_DROPDOWN, MULTIPLE_ANSWER_DROPDOWN_COMBINATION])) {
- $url = 'admin.php?'.api_get_cidreq().'&'.http_build_query(['exerciseId' => $exerciseId, 'page' => $page, 'mad_admin' => $objQuestion->iid]);
- echo '';
- } else {
- if (isset($_GET['editQuestion'])) {
- if (empty($exerciseId)) {
- Display::addFlash(Display::return_message(get_lang('ItemUpdated')));
- $url = 'admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&editQuestion='.$objQuestion->iid;
- echo '';
- exit;
+ // Media is selected?
+ $parentId = $form->getSubmitValue('parent_id');
+ $categories = $form->getSubmitValue('questionCategory');
+ $process = true;
+ $message = null;
+
+ // A media question was sent
+ if (isset($parentId) && !empty($parentId)) {
+ // No allowing 2 categories if a media was selected
+ $tryAgain = Display::url(
+ get_lang('TryAgain'),
+ api_get_path(WEB_CODE_PATH).'exercise/admin.php?exerciseId='.$exerciseId.'&myid=1&editQuestion='.$objQuestion->id.'&'.api_get_cidreq(),
+ array('class' => 'btn')
+ );
+
+ if (isset($categories) && !empty($categories)) {
+
+ if (count($categories) > 1) {
+ $message = Display::display_warning_message(get_lang('WhenUsingAMediaQuestionYouCantAddMoreThanOneCategory'));
+ $message .= ' '.$tryAgain;
+
+ $process = false;
+ }
+
+ $questionCategoriesOfMediaQuestions = $objQuestion->getQuestionCategoriesOfMediaQuestions($exerciseId, $parentId);
+
+ if (!empty($questionCategoriesOfMediaQuestions)) {
+ // Check if the media sent matches other medias sent before
+ $result = $objQuestion->allQuestionWithMediaHaveTheSameCategory($exerciseId, $parentId, $categories, $objQuestion->id);
+
+ if ($result == false) {
+ $message = Display::display_warning_message(get_lang('TheSelectedCategoryDoesNotMatchWithTheOtherQuestionWithTheSameMediaQuestion'));
+ $message .= ' '.$tryAgain;
+ $process = false;
}
- echo '';
+ }
+ } else {
+ if (!empty($objQuestion->category_list)) {
+ $message = Display::display_warning_message(get_lang('YouMustProvideACategoryBecauseTheCurrentCategoryDoesNotMatchOtherMediaQuestions'));
+ $message .= ' '.$tryAgain;
+ $process = false;
+ }
+ }
+ }
+
+ if ($process) {
+
+ $validationResult = true;
+ if (method_exists($objQuestion, 'validateAnswers')) {
+ $validationResult = $objQuestion->validateAnswers($form);
+ }
+ if (is_array($validationResult) && !empty($validationResult['errors'])) {
+ echo Display::return_message(implode("
", $validationResult['errors']), 'error', false);
+ } elseif ($form->validate()) {
+ $objQuestion->processCreation($form, $objExercise);
+ $objQuestion->processAnswersCreation($form, $objExercise);
+ if (in_array($objQuestion->type, [HOT_SPOT, HOT_SPOT_COMBINATION, HOT_SPOT_DELINEATION])) {
+ echo '';
+ } elseif (in_array($objQuestion->type, [MULTIPLE_ANSWER_DROPDOWN, MULTIPLE_ANSWER_DROPDOWN_COMBINATION])) {
+ $url = 'admin.php?'.api_get_cidreq().'&'.http_build_query(['exerciseId' => $exerciseId, 'page' => $page, 'mad_admin' => $objQuestion->iid]);
+ echo '';
} else {
- // New question
- $page = 1;
- $length = api_get_configuration_value('question_pagination_length');
- if (!empty($length)) {
- $page = round($objExercise->getQuestionCount() / $length);
+ if (isset($_GET['editQuestion'])) {
+ if (empty($exerciseId)) {
+ Display::addFlash(Display::return_message(get_lang('ItemUpdated')));
+ $url = 'admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&editQuestion='.$objQuestion->iid;
+ echo '';
+ exit;
+ }
+ echo '';
+ } else {
+ // New question
+ $page = 1;
+ $length = api_get_configuration_value('question_pagination_length');
+ if (!empty($length)) {
+ $page = round($objExercise->getQuestionCount() / $length);
+ }
+ echo '';
}
- echo '';
}
+ exit();
}
- exit();
}
}
diff --git a/main/exercise/question_list_admin.inc.php b/main/exercise/question_list_admin.inc.php
index 997ebbe0590..d8a7b239e81 100755
--- a/main/exercise/question_list_admin.inc.php
+++ b/main/exercise/question_list_admin.inc.php
@@ -196,6 +196,8 @@ function loadEditor(button, questionId) {
//deletes a session when using don't know question type (ugly fix)
Session::erase('less_answer');
+echo Question::getMediaLabels();
+
// If we are in a test
$inATest = isset($exerciseId) && $exerciseId > 0;
if (!$inATest) {
@@ -379,14 +381,21 @@ function loadEditor(button, questionId) {
// Question type
$typeImg = $objQuestionTmp->getTypePicture();
$typeExpl = $objQuestionTmp->getExplanation();
- $questionType = Display::return_icon($typeImg, $typeExpl);
+
+ $question_media = null;
+ if (!empty($objQuestionTmp->parent_id)) {
+ $objQuestionMedia = Question::read($objQuestionTmp->parent_id);
+ $question_media = ' '.Question::getMediaLabel($objQuestionMedia->question);
+ }
+
+ $questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), ICON_SIZE_MEDIUM).$question_media);
// Question category
$txtQuestionCat = Security::remove_XSS(
TestCategory::getCategoryNameForQuestion($objQuestionTmp->iid)
);
if (empty($txtQuestionCat)) {
- $txtQuestionCat = '-';
+ $txtQuestionCat = '';
}
// Question level
diff --git a/main/exercise/unique_answer.class.php b/main/exercise/unique_answer.class.php
index e1864faf731..02a4c5d6f15 100755
--- a/main/exercise/unique_answer.class.php
+++ b/main/exercise/unique_answer.class.php
@@ -496,9 +496,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
$header .= ''.get_lang('Choice').' | ';
diff --git a/main/exercise/unique_answer_no_option.class.php b/main/exercise/unique_answer_no_option.class.php
index 4a583798395..365a7999522 100755
--- a/main/exercise/unique_answer_no_option.class.php
+++ b/main/exercise/unique_answer_no_option.class.php
@@ -395,9 +395,9 @@ public function processAnswersCreation($form, $exercise)
/**
* {@inheritdoc}
*/
- public function return_header(Exercise $exercise, $counter = null, $score = [])
+ public function return_header(Exercise $exercise, $counter = null, $score = [], $showMedia = false)
{
- $header = parent::return_header($exercise, $counter, $score);
+ $header = parent::return_header($exercise, $counter, $score, $showMedia);
$header .= '';
if (!in_array($exercise->results_disabled, [
diff --git a/main/inc/ajax/exercise.ajax.php b/main/inc/ajax/exercise.ajax.php
index 87381e2957a..ebdf7bda419 100755
--- a/main/inc/ajax/exercise.ajax.php
+++ b/main/inc/ajax/exercise.ajax.php
@@ -559,13 +559,6 @@
$exercise_id = $exercise_stat_info['exe_exo_id'];
$attemptList = [];
// First time here we create an attempt (getting the exe_id).
- if (!empty($exercise_stat_info)) {
- // We know the user we get the exe_id.
- $exeId = $exercise_stat_info['exe_id'];
- $total_score = $exercise_stat_info['exe_result'];
- // Getting the list of attempts
- $attemptList = Event::getAllExerciseEventByExeId($exeId);
- }
// No exe id? Can't save answer.
if (empty($exeId)) {
@@ -1266,6 +1259,29 @@ function (array $exercise) {
}
}
break;
+ case 'get_categories_by_media':
+ $questionId = $_REQUEST['questionId'];
+ $mediaId = $_REQUEST['mediaId'];
+ $exerciseId = $_REQUEST['exerciseId'];
+ $question = Question::read($questionId);
+ if (empty($mediaId)) {
+ echo 0;
+ break;
+ }
+ $categoryId = $question->allQuestionWithMediaHaveTheSameCategory($exerciseId, $mediaId, null, null, true);
+
+ if (!empty($categoryId)) {
+ $category = new Testcategory($categoryId);
+ echo json_encode(
+ array(
+ 'title' => $category->title,
+ 'value' => $category->id
+ )
+ );
+ } else {
+ echo -1;
+ }
+ break;
default:
echo '';
}
diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php
index dd0676e0ac1..fd23b172638 100644
--- a/main/inc/lib/exercise.lib.php
+++ b/main/inc/lib/exercise.lib.php
@@ -5386,12 +5386,15 @@ public static function displayQuestionListByAttempt(
}
$question_list_answers = [];
+ $mediaList = [];
$category_list = [];
$loadChoiceFromSession = false;
$fromDatabase = true;
$exerciseResult = null;
$exerciseResultCoordinates = null;
$delineationResults = null;
+ $tempParentId = null;
+ $mediaCounter = 0;
if (true === $save_user_result && in_array(
$objExercise->getFeedbackType(),
[EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP]
@@ -5581,16 +5584,38 @@ public static function displayQuestionListByAttempt(
$question_content = '';
if ($show_results) {
+ $showMedia = false;
$question_content = '';
if (false === $showQuestionScore) {
$score = [];
}
+ /*if ($objQuestionTmp->parent_id != 0 && !in_array($objQuestionTmp->parent_id, $mediaList)) {
+ $showMedia = true;
+ $mediaList[] = $objQuestionTmp->parent_id;
+ }*/
+ $counterToShow = $counter;
+
+ if ($objQuestionTmp->parent_id != 0) {
+
+ if (!in_array($objQuestionTmp->parent_id, $media_list)) {
+ $media_list[] = $objQuestionTmp->parent_id;
+ $show_media = true;
+ }
+ if ($tempParentId == $objQuestionTmp->parent_id) {
+ $mediaCounter++;
+ } else {
+ $mediaCounter = 0;
+ }
+ $counterToShow = chr(97 + $mediaCounter);
+ $tempParentId = $objQuestionTmp->parent_id;
+ }
// Shows question title an description
$question_content .= $objQuestionTmp->return_header(
$objExercise,
- $counter,
- $score
+ $counterToShow,
+ $score,
+ $showMedia
);
}
$counter++;