Minor - upgrade from 1.11.x

pull/3006/head
Julio Montoya 6 years ago
parent 3af017dd5e
commit 447a4c70f2
  1. 2
      main/admin/access_url_edit_usergroup_to_url.php
  2. 28
      main/badge/assign.php
  3. 4
      main/exercise/Draggable.php
  4. 4
      main/exercise/MatchingDraggable.php
  5. 21
      main/exercise/MultipleAnswerTrueFalseDegreeCertainty.php
  6. 34
      main/exercise/TestCategory.php
  7. 79
      main/exercise/UniqueAnswerImage.php
  8. 2
      main/exercise/admin.php
  9. 4
      main/exercise/calculated_answer.class.php
  10. 550
      main/exercise/exercise.class.php
  11. 7
      main/exercise/exercise_admin.php
  12. 10
      main/exercise/exercise_result.php
  13. 4
      main/exercise/exercise_show.php
  14. 30
      main/exercise/exercise_submit.php
  15. 181
      main/exercise/exercise_submit_modal.php
  16. 10
      main/exercise/global_multiple_answer.class.php
  17. 53
      main/exercise/hotspot_admin.inc.php
  18. 8
      main/exercise/matching.class.php
  19. 7
      main/exercise/multiple_answer.class.php
  20. 7
      main/exercise/multiple_answer_combination.class.php
  21. 13
      main/exercise/multiple_answer_true_false.class.php
  22. 4
      main/exercise/overview.php
  23. 12
      main/exercise/question.class.php
  24. 3
      main/exercise/question_list_admin.inc.php
  25. 5
      main/exercise/question_pool.php
  26. 131
      main/exercise/unique_answer.class.php
  27. 9
      main/exercise/unique_answer_no_option.class.php
  28. 17
      main/gradebook/gradebook_flatview.php
  29. 16
      main/gradebook/index.php
  30. 1
      main/gradebook/lib/be/category.class.php
  31. 88
      main/gradebook/lib/be/exerciselink.class.php
  32. 28
      main/gradebook/lib/be/studentpublicationlink.class.php
  33. 135
      main/gradebook/lib/fe/exportgradebook.php
  34. 21
      main/gradebook/lib/fe/gradebooktable.class.php
  35. 4
      main/gradebook/lib/flatview_data_generator.class.php
  36. 2
      main/inc/lib/template.lib.php

@ -109,7 +109,7 @@ echo '</div>';
api_display_tool_title($tool_name);
$noUserGroupList = $userGroupList = [];
$ajax_search = $add_type == 'unique' ? true : false;
$ajax_search = $add_type === 'unique' ? true : false;
if ($ajax_search) {
$userGroups = UrlManager::get_url_rel_usergroup_data($access_url_id);

@ -2,7 +2,6 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Skill;
use Chamilo\CoreBundle\Entity\SkillRelUser;
use Chamilo\UserBundle\Entity\User;
use Skill as SkillManager;
@ -289,22 +288,13 @@ if ($form->validate()) {
exit;
}
$skillUser = new SkillRelUser();
$skillUser->setUser($user);
$skillUser->setSkill($skill);
if ($showLevels) {
$level = $skillLevelRepo->find($values['acquired_level']);
$skillUser->setAcquiredLevel($level);
}
$skillUser->setArgumentation($values['argumentation']);
$skillUser->setArgumentationAuthorId(api_get_user_id());
$skillUser->setAcquiredSkillAt(new DateTime());
$skillUser->setAssignedBy(0);
$entityManager->persist($skillUser);
$entityManager->flush();
$skillUser = $skillManager->addSkillToUserBadge(
$user,
$skill,
$values['acquired_level'],
$values['argumentation'],
api_get_user_id()
);
// Send email depending of children_auto_threshold
$skillRelSkill = new SkillRelSkill();
@ -334,9 +324,9 @@ if ($form->validate()) {
Display::addFlash(Display::return_message(get_lang('MessageSent')));
$url = api_get_path(WEB_CODE_PATH).'badge/assign.php?user='.$userId.'&id='.$parentId;
$link = Display::url($url, $url);
$subject = get_lang("StudentHadEnoughSkills");
$subject = get_lang('StudentHadEnoughSkills');
$message = sprintf(
get_lang("StudentXHadEnoughSkillsToGetSkillXToAssignClickHereX"),
get_lang('StudentXHadEnoughSkillsToGetSkillXToAssignClickHereX'),
UserManager::formatUserFullName($user),
$parentData['name'],
$link

@ -217,7 +217,9 @@ class Draggable extends Question
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('YourChoice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
} else {
$header .= '<th>'.get_lang('ElementList').'</th>';
}

@ -274,7 +274,9 @@ class MatchingDraggable extends Question
}
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
$header .= '<th>'.get_lang('Status').'</th>';
} else {
$header .= '<th>'.get_lang('CorrespondsTo').'</th>';

@ -77,7 +77,7 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question
.'</th>';
// show column comment when feedback is enable
if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objEx->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$html .= '<th>'.get_lang('Comment').'</th>';
}
$html .= '</tr>';
@ -173,7 +173,7 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question
$form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
// show comment when feedback is enable
if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objEx->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$form->addElement(
'html_editor',
'comment['.$i.']',
@ -306,19 +306,20 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question
public function return_header(Exercise $exercise, $counter = null, $score = [])
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'
.$this->question_table_class
.'"><tr><th>'
.get_lang('Choice')
.'</th><th>'
.get_lang('ExpectedChoice')
.'</th><th>'
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
$header .='<th>'
.get_lang('Answer')
.'</th><th colspan="2" style="text-align:center;">'
.get_lang('YourDegreeOfCertainty')
.'</th>'
;
if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($exercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$header .= '<th>'.get_lang('Comment').'</th>';
} else {
$header .= '<th>&nbsp;</th>';

@ -714,40 +714,6 @@ class TestCategory
return $tabResult;
}
/**
* return total score for test exe_id for all question in the category $in_cat_id for user
* If no question for this category, return "".
*/
public static function getCatScoreForExeidForUserid($in_cat_id, $in_exe_id, $in_user_id)
{
$tbl_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$tbl_question_rel_category = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$in_cat_id = (int) $in_cat_id;
$in_exe_id = (int) $in_exe_id;
$in_user_id = (int) $in_user_id;
$query = "SELECT DISTINCT
marks,
exe_id,
user_id,
ta.question_id,
category_id
FROM $tbl_track_attempt ta
INNER JOIN $tbl_question_rel_category qrc
ON (ta.question_id = qrc.question_id)
WHERE
qrc.category_id = $in_cat_id AND
exe_id = $in_exe_id AND
user_id = $in_user_id";
$res = Database::query($query);
$score = '';
while ($data = Database::fetch_array($res)) {
$score += $data['marks'];
}
return $score;
}
/**
* Return the number max of question in a category
* count the number of questions in all categories, and return the max.

@ -43,13 +43,18 @@ class UniqueAnswerImage extends UniqueAnswer
$numberAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
$feedbackTitle = '';
if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
//Scenario
$commentTitle = '<th>'.get_lang('Comment').'</th>';
$feedbackTitle = '<th>'.get_lang('Scenario').'</th>';
} else {
$commentTitle = '<th >'.get_lang('Comment').'</th>';
switch ($objExercise->getFeedbackType()) {
case EXERCISE_FEEDBACK_TYPE_DIRECT:
// Scenario
$commentTitle = '<th width="20%">'.get_lang('Comment').'</th>';
$feedbackTitle = '<th width="20%">'.get_lang('Scenario').'</th>';
break;
case EXERCISE_FEEDBACK_TYPE_POPUP:
$commentTitle = '<th width="20%">'.get_lang('Comment').'</th>';
break;
default:
$commentTitle = '<th width="40%">'.get_lang('Comment').'</th>';
break;
}
$html = '<div class="alert alert-success" role="alert">'.
@ -196,49 +201,17 @@ class UniqueAnswerImage extends UniqueAnswer
$form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
$form->addHtmlEditor(
'comment['.$i.']',
null,
null,
false,
$editorConfig
);
// Direct feedback
// Adding extra feedback fields
$group = [];
$group['try'.$i] = $form->createElement('checkbox', 'try'.$i, null, get_lang('TryAgain'));
$group['lp'.$i] = $form->createElement(
'select',
'lp'.$i,
get_lang('SeeTheory').': ',
$selectLpId
);
$group['destination'.$i] = $form->createElement(
'select',
'destination'.$i,
get_lang('GoToQuestion').': ',
$selectQuestion
);
$group['url'.$i] = $form->createElement(
'text',
'url'.$i,
get_lang('Other').': ',
[
'class' => 'col-md-2',
'placeholder' => get_lang('Other'),
]
);
$form->addGroup($group, 'scenario');
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}',
'scenario'
);
} else {
$form->addHtmlEditor('comment['.$i.']', null, null, false, $editorConfig);
switch ($objExercise->getFeedbackType()) {
case EXERCISE_FEEDBACK_TYPE_DIRECT:
$this->setDirectOptions($i, $form, $renderer, $selectLpId, $selectQuestion);
break;
case EXERCISE_FEEDBACK_TYPE_POPUP:
default:
$form->addHtmlEditor('comment['.$i.']', null, null, false, $editorConfig);
break;
}
$form->addText('weighting['.$i.']', null, null, ['class' => "col-md-1", 'value' => '0']);
$form->addText('weighting['.$i.']', null, null, ['class' => 'col-md-1', 'value' => '0']);
$form->addHtml('</tr>');
}
@ -378,9 +351,11 @@ class UniqueAnswerImage extends UniqueAnswer
if ($exercise->showExpectedChoice()) {
$header = '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang('Choice').'</th>
<th>'.get_lang('ExpectedChoice').'</th>
<th>'.get_lang('Answer').'</th>';
<th>'.get_lang('Choice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
$header .= '<th>'.get_lang('Answer').'</th>';
$header .= '<th>'.get_lang('Status').'</th>';
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';

@ -453,7 +453,7 @@ if (!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspot
// if we are in question authoring, display warning to user is feedback not shown at the end of the test -ref #6619
// this test to display only message in the question authoring page and not in the question list page too
if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM) {
echo Display::return_message(get_lang('TestFeedbackNotShown'), 'normal');
}

@ -252,7 +252,9 @@ class CalculatedAnswer extends Question
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('YourChoice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '</tr>';

@ -1,8 +1,10 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\GradebookLink;
use Chamilo\CoreBundle\Entity\TrackEHotspot;
use ChamiloSession as Session;
use Doctrine\DBAL\Types\Type;
/**
* Class Exercise.
@ -84,6 +86,7 @@ class Exercise
public $export = false;
public $autolaunch;
public $exerciseCategoryId;
public $pageResultConfiguration;
/**
* Constructor of the class.
@ -123,6 +126,7 @@ class Exercise
$this->globalCategoryId = null;
$this->notifications = [];
$this->exerciseCategoryId = 0;
$this->pageResultConfiguration;
if (!empty($courseId)) {
$courseInfo = api_get_course_info_by_id($courseId);
@ -201,6 +205,10 @@ class Exercise
$this->notifications = explode(',', $object->notifications);
}
if (!empty($object->page_result_configuration)) {
$this->pageResultConfiguration = $object->page_result_configuration;
}
if (isset($object->show_previous_button)) {
$this->showPreviousButton = $object->show_previous_button == 1 ? true : false;
}
@ -219,7 +227,6 @@ class Exercise
}
$this->force_edit_exercise_in_lp = api_get_setting('lp.show_invisible_exercise_in_lp_toc') === 'true';
$this->edit_exercise_in_lp = true;
if ($this->exercise_was_added_in_lp) {
$this->edit_exercise_in_lp = $this->force_edit_exercise_in_lp == true;
@ -309,14 +316,15 @@ class Exercise
return $this->attempts;
}
/** returns the number of FeedbackType *
* 0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback.
/**
* Returns the number of FeedbackType
* 0: Feedback , 1: DirectFeedback, 2: NoFeedback.
*
* @return int - exercise attempts
*/
public function selectFeedbackType()
public function getFeedbackType()
{
return $this->feedback_type;
return (int) $this->feedback_type;
}
/**
@ -416,7 +424,7 @@ class Exercise
*
* @return string html text : the text to display ay the end of the test
*/
public function selectTextWhenFinished()
public function getTextWhenFinished()
{
return $this->text_when_finished;
}
@ -644,10 +652,10 @@ class Exercise
ON (e.question_id = q.id AND e.c_id = ".$this->course_id." )
WHERE e.exercice_id = '".$this->id."' ";
$orderCondition = "ORDER BY question_order";
$orderCondition = ' ORDER BY question_order ';
if (!empty($sidx) && !empty($sord)) {
if ($sidx == 'question') {
if ($sidx === 'question') {
if (in_array(strtolower($sord), ['desc', 'asc'])) {
$orderCondition = " ORDER BY q.$sidx $sord";
}
@ -657,8 +665,8 @@ class Exercise
$sql .= $orderCondition;
$limitCondition = null;
if (isset($start) && isset($limit)) {
$start = intval($start);
$limit = intval($limit);
$start = (int) $start;
$limit = (int) $limit;
$limitCondition = " LIMIT $start, $limit";
}
$sql .= $limitCondition;
@ -677,7 +685,7 @@ class Exercise
);
if (empty($category_labels)) {
$category_labels = "-";
$category_labels = '-';
}
// Question type
@ -1088,7 +1096,7 @@ class Exercise
/**
* @return int
*/
public function selectSaveCorrectAnswers()
public function getSaveCorrectAnswers()
{
return $this->saveCorrectAnswers;
}
@ -1257,7 +1265,7 @@ class Exercise
*/
public function updateSaveCorrectAnswers($value)
{
$this->saveCorrectAnswers = $value;
$this->saveCorrectAnswers = (int) $value;
}
/**
@ -1502,7 +1510,7 @@ class Exercise
$random_answers = $this->random_answers;
$active = $this->active;
$propagate_neg = (int) $this->propagate_neg;
$saveCorrectAnswers = isset($this->saveCorrectAnswers) && $this->saveCorrectAnswers ? 1 : 0;
$saveCorrectAnswers = isset($this->saveCorrectAnswers) ? (int) $this->saveCorrectAnswers : 0;
$review_answers = isset($this->review_answers) && $this->review_answers ? 1 : 0;
$randomByCat = (int) $this->randomByCat;
$text_when_finished = $this->text_when_finished;
@ -1512,7 +1520,7 @@ class Exercise
// If direct we do not show results
$results_disabled = (int) $this->results_disabled;
if ($feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (in_array($feedback_type, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
$results_disabled = 0;
}
$expired_time = (int) $this->expired_time;
@ -1576,6 +1584,10 @@ class Exercise
$notifications = implode(',', $notifications);
$paramsExtra['notifications'] = $notifications;
}
if (!empty($this->pageResultConfiguration)) {
$paramsExtra['page_result_configuration'] = $this->pageResultConfiguration;
}
}
$params = array_merge($params, $paramsExtra);
@ -1636,7 +1648,7 @@ class Exercise
'text_when_finished' => $text_when_finished,
'display_category_name' => $display_category_name,
'pass_percentage' => $pass_percentage,
'save_correct_answers' => (int) $saveCorrectAnswers,
'save_correct_answers' => $saveCorrectAnswers,
'propagate_neg' => $propagate_neg,
'hide_question_title' => $this->getHideQuestionTitle(),
];
@ -1661,6 +1673,10 @@ class Exercise
}
}
if (!empty($this->pageResultConfiguration)) {
$params['page_result_configuration'] = $this->pageResultConfiguration;
}
$this->id = $this->iId = Database::insert($TBL_EXERCISES, $params);
if ($this->id) {
@ -1875,14 +1891,13 @@ class Exercise
$type = 'full';
}
// form title
// Form title
$form_title = get_lang('NewEx');
if (!empty($_GET['exerciseId'])) {
$form_title = get_lang('ModifyExercise');
} else {
$form_title = get_lang('NewEx');
}
$form->addElement('header', $form_title);
$form->addHeader($form_title);
// Title.
if (api_get_configuration_value('save_titles_as_html')) {
@ -1929,6 +1944,7 @@ class Exercise
'Width' => '100%',
'Height' => '150',
];
if (is_array($type)) {
$editor_config = array_merge($editor_config, $type);
}
@ -1943,56 +1959,9 @@ class Exercise
$skillList = [];
if ($type === 'full') {
//Can't modify a DirectFeedback question
if ($this->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_DIRECT) {
// feedback type
$radios_feedback = [];
$radios_feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('ExerciseAtTheEndOfTheTest'),
'0',
[
'id' => 'exerciseType_0',
'onclick' => 'check_feedback()',
]
);
if (api_get_setting('enable_quiz_scenario') === 'true') {
// Can't convert a question from one feedback to another
// if there is more than 1 question already added
if ($this->selectNbrQuestions() == 0) {
$radios_feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('DirectFeedback'),
'1',
[
'id' => 'exerciseType_1',
'onclick' => 'check_direct_feedback()',
]
);
}
}
$radios_feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('NoFeedback'),
'2',
['id' => 'exerciseType_2']
);
$form->addGroup(
$radios_feedback,
null,
[
get_lang('FeedbackType'),
get_lang('FeedbackDisplayOptions'),
]
);
// Can't modify a DirectFeedback question.
if (!in_array($this->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
$this->setResultFeedbackGroup($form);
// Type of results display on the final page
$this->setResultDisabledGroup($form);
@ -2026,41 +1995,7 @@ class Exercise
} else {
// if is Direct feedback but has not questions we can allow to modify the question type
if ($this->getQuestionCount() === 0) {
// feedback type
$radios_feedback = [];
$radios_feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('ExerciseAtTheEndOfTheTest'),
'0',
['id' => 'exerciseType_0', 'onclick' => 'check_feedback()']
);
if (api_get_setting('enable_quiz_scenario') == 'true') {
$radios_feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('DirectFeedback'),
'1',
['id' => 'exerciseType_1', 'onclick' => 'check_direct_feedback()']
);
}
$radios_feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('NoFeedback'),
'2',
['id' => 'exerciseType_2']
);
$form->addGroup(
$radios_feedback,
null,
[get_lang('FeedbackType'), get_lang('FeedbackDisplayOptions')]
);
$this->setResultFeedbackGroup($form);
$this->setResultDisabledGroup($form);
// Type of questions disposition on page
@ -2079,7 +2014,7 @@ class Exercise
$group->freeze();
// we force the options to the DirectFeedback exercisetype
$form->addElement('hidden', 'exerciseFeedbackType', EXERCISE_FEEDBACK_TYPE_DIRECT);
$form->addElement('hidden', 'exerciseFeedbackType', $this->getFeedbackType());
$form->addElement('hidden', 'exerciseType', ONE_PER_PAGE);
// Type of questions disposition on page
@ -2154,6 +2089,30 @@ class Exercise
]
);
$group = [
$form->createElement(
'checkbox',
'hide_expected_answer',
null,
get_lang('HideExpectedAnswer')
),
$form->createElement(
'checkbox',
'hide_total_score',
null,
get_lang('HideTotalScore')
),
$form->createElement(
'checkbox',
'hide_question_score',
null,
get_lang('HideQuestionScore')
)
];
$form->addGroup($group, null, get_lang('ResultsConfigurationPage'));
$displayMatrix = 'none';
$displayRandom = 'none';
$selectionType = $this->getQuestionSelectionType();
@ -2201,13 +2160,6 @@ class Exercise
$form->addElement('label', null, $cat_form);
$form->addElement('html', '</div>');
// Category name.
$radio_display_cat_name = [
$form->createElement('radio', 'display_category_name', null, get_lang('Yes'), '1'),
$form->createElement('radio', 'display_category_name', null, get_lang('No'), '0'),
];
$form->addGroup($radio_display_cat_name, null, get_lang('QuestionDisplayCategoryName'));
// Random answers.
$radios_random_answers = [
$form->createElement('radio', 'randomAnswers', null, get_lang('Yes'), '1'),
@ -2215,6 +2167,13 @@ class Exercise
];
$form->addGroup($radios_random_answers, null, get_lang('RandomAnswers'));
// Category name.
$radio_display_cat_name = [
$form->createElement('radio', 'display_category_name', null, get_lang('Yes'), '1'),
$form->createElement('radio', 'display_category_name', null, get_lang('No'), '0'),
];
$form->addGroup($radio_display_cat_name, null, get_lang('QuestionDisplayCategoryName'));
// Hide question title.
$group = [
$form->createElement('radio', 'hide_question_title', null, get_lang('Yes'), '1'),
@ -2298,11 +2257,19 @@ class Exercise
null,
get_lang('PropagateNegativeResults')
);
$form->addCheckBox(
$options = [
'' => get_lang('SelectAnOption'),
1 => get_lang('SaveTheCorrectAnswersForTheNextAttempt'),
2 => get_lang('SaveAllAnswers'),
];
$form->addSelect(
'save_correct_answers',
null,
get_lang('SaveTheCorrectAnswersForTheNextAttempt')
);
get_lang('SaveAnswers'),
$options
);
$form->addElement('html', '<div class="clear">&nbsp;</div>');
$form->addElement('checkbox', 'review_answers', null, get_lang('ReviewAnswers'));
$form->addElement('html', '<div id="divtimecontrol" style="display:'.$display.';">');
@ -2439,24 +2406,19 @@ class Exercise
$form->addRule('end_time', get_lang('InvalidDate'), 'datetime');
if ($this->id > 0) {
//if ($this->random > $this->selectNbrQuestions()) {
// $defaults['randomQuestions'] = $this->selectNbrQuestions();
//} else {
$defaults['randomQuestions'] = $this->random;
//}
$defaults['randomAnswers'] = $this->getRandomAnswers();
$defaults['exerciseType'] = $this->selectType();
$defaults['exerciseTitle'] = $this->get_formated_title();
$defaults['exerciseDescription'] = $this->selectDescription();
$defaults['exerciseAttempts'] = $this->selectAttempts();
$defaults['exerciseFeedbackType'] = $this->selectFeedbackType();
$defaults['exerciseFeedbackType'] = $this->getFeedbackType();
$defaults['results_disabled'] = $this->selectResultsDisabled();
$defaults['propagate_neg'] = $this->selectPropagateNeg();
$defaults['save_correct_answers'] = $this->selectSaveCorrectAnswers();
$defaults['save_correct_answers'] = $this->getSaveCorrectAnswers();
$defaults['review_answers'] = $this->review_answers;
$defaults['randomByCat'] = $this->getRandomByCategory();
$defaults['text_when_finished'] = $this->selectTextWhenFinished();
$defaults['text_when_finished'] = $this->getTextWhenFinished();
$defaults['display_category_name'] = $this->selectDisplayCategoryName();
$defaults['pass_percentage'] = $this->selectPassPercentage();
$defaults['question_selection_type'] = $this->getQuestionSelectionType();
@ -2512,6 +2474,8 @@ class Exercise
if (api_get_setting('search_enabled') === 'true') {
$defaults['index_document'] = 'checked="checked"';
}
$this->setPageResultConfigurationDefaults($defaults);
$form->setDefaults($defaults);
// Freeze some elements.
@ -2533,6 +2497,71 @@ class Exercise
}
}
/**
* @param $form
*/
public function setResultFeedbackGroup(FormValidator $form)
{
// Feedback type.
$feedback = [];
$feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('ExerciseAtTheEndOfTheTest'),
EXERCISE_FEEDBACK_TYPE_END,
[
'id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_END,
'onclick' => 'check_feedback()',
]
);
if (api_get_setting('enable_quiz_scenario') === 'true') {
// Can't convert a question from one feedback to another
// if there is more than 1 question already added
if ($this->selectNbrQuestions() == 0) {
$feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('DirectFeedback'),
EXERCISE_FEEDBACK_TYPE_DIRECT,
[
'id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_DIRECT,
'onclick' => 'check_direct_feedback()',
]
);
}
}
$feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('ExerciseDirectPopUp'),
EXERCISE_FEEDBACK_TYPE_POPUP,
['id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_POPUP, 'onclick' => 'check_direct_feedback()']
);
$feedback[] = $form->createElement(
'radio',
'exerciseFeedbackType',
null,
get_lang('NoFeedback'),
EXERCISE_FEEDBACK_TYPE_EXAM,
['id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_EXAM]
);
$form->addGroup(
$feedback,
null,
[
get_lang('FeedbackType'),
get_lang('FeedbackDisplayOptions'),
]
);
}
/**
* function which process the creation of exercises.
*
@ -2576,6 +2605,7 @@ class Exercise
$this->setShowPreviousButton($form->getSubmitValue('show_previous_button'));
$this->setNotifications($form->getSubmitValue('notifications'));
$this->setExerciseCategoryId($form->getSubmitValue('exercise_category_id'));
$this->setPageResultConfiguration($form->getSubmitValues());
$this->start_time = null;
if ($form->getSubmitValue('activate_start_date_check') == 1) {
@ -3082,7 +3112,9 @@ class Exercise
$html = $label = '';
$hotspot_get = isset($_POST['hotspot']) ? Security::remove_XSS($_POST['hotspot']) : null;
if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT && $this->type == ONE_PER_PAGE) {
if (in_array($this->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP]) &&
$this->type == ONE_PER_PAGE
) {
$urlTitle = get_lang('ContinueTest');
if ($questionNum == count($this->questionList)) {
$urlTitle = get_lang('EndTest');
@ -3090,7 +3122,7 @@ class Exercise
$html .= Display::url(
$urlTitle,
'exercise_submit_modal.php?'.http_build_query([
api_get_path(WEB_CODE_PATH).'exercise/exercise_submit_modal.php?'.http_build_query([
'learnpath_id' => $safe_lp_id,
'learnpath_item_id' => $safe_lp_item_id,
'learnpath_item_view_id' => $safe_lp_item_view_id,
@ -3104,7 +3136,7 @@ class Exercise
]),
[
'class' => 'ajax btn btn-default',
'data-title' => $urlTitle,
'data-title' => Security::remove_XSS(get_lang('Comment')),
'data-size' => 'md',
]
);
@ -3158,7 +3190,6 @@ class Exercise
$num++;
}
$prev_question = $num;
//$question_id = $beforeId;
}
}
@ -3338,7 +3369,7 @@ class Exercise
global $learnpath_id, $learnpath_item_id;
require_once api_get_path(LIBRARY_PATH).'geometry.lib.php';
$em = Database::getManager();
$feedback_type = $this->selectFeedbackType();
$feedback_type = $this->getFeedbackType();
$results_disabled = $this->selectResultsDisabled();
if ($debug) {
@ -4354,10 +4385,12 @@ class Exercise
case MATCHING:
case MATCHING_DRAGGABLE:
echo '<tr>';
if (!in_array($this->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
])
if (!in_array(
$this->results_disabled,
[
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
]
)
) {
echo '<td>'.$s_answer_label.'</td>';
echo '<td>'.$user_answer.'</td>';
@ -4367,31 +4400,35 @@ class Exercise
}
if ($this->showExpectedChoice()) {
echo '<td>';
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt == true
) {
echo Display::span(
$real_list[$i_answer_correct_answer]
);
if ($this->showExpectedChoiceColumn()) {
echo '<td>';
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt == true
) {
echo Display::span(
$real_list[$i_answer_correct_answer]
);
}
}
echo '</td>';
}
echo '</td>';
echo '<td>'.$status.'</td>';
} else {
echo '<td>';
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt === true
) {
echo Display::span(
$real_list[$i_answer_correct_answer],
['style' => 'color: #008000; font-weight: bold;']
);
if ($this->showExpectedChoiceColumn()) {
echo '<td>';
echo Display::span(
$real_list[$i_answer_correct_answer],
['style' => 'color: #008000; font-weight: bold;']
);
echo '</td>';
}
}
}
echo '</td>';
}
echo '</tr>';
break;
@ -4699,6 +4736,7 @@ class Exercise
);
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty(
$this,
$feedback_type,
$studentChoice,
$studentChoiceDegree,
@ -4725,6 +4763,7 @@ class Exercise
);
} elseif ($answerType == FILL_IN_BLANKS) {
ExerciseShowFunctions::display_fill_in_blanks_answer(
$this,
$feedback_type,
$answer,
0,
@ -4806,8 +4845,12 @@ class Exercise
$coords = explode('/', $user_answer);
$user_array = '';
foreach ($coords as $coord) {
list($x, $y) = explode(';', $coord);
$user_array .= round($x).';'.round($y).'/';
if (!empty($coord)) {
$parts = explode(';', $coord);
if (!empty($parts)) {
$user_array .= round($parts[0]).';'.round($parts[1]).'/';
}
}
}
$user_array = substr($user_array, 0, -1);
@ -5091,6 +5134,7 @@ class Exercise
case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY:
if ($answerId == 1) {
ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty(
$this,
$feedback_type,
$studentChoice,
$studentChoiceDegree,
@ -5102,6 +5146,7 @@ class Exercise
);
} else {
ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty(
$this,
$feedback_type,
$studentChoice,
$studentChoiceDegree,
@ -5115,6 +5160,7 @@ class Exercise
break;
case FILL_IN_BLANKS:
ExerciseShowFunctions::display_fill_in_blanks_answer(
$this,
$feedback_type,
$answer,
$exeId,
@ -7190,7 +7236,10 @@ class Exercise
if ($currentQuestion != $i) {
continue;
} else {
if ($this->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (!in_array(
$this->getFeedbackType(),
[EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP]
)) {
// if the user has already answered this question
if (isset($exerciseResult[$questionId])) {
echo Display::return_message(
@ -7799,12 +7848,13 @@ class Exercise
/**
* Get the correct answers in all attempts.
*
* @param int $learnPathId
* @param int $learnPathItemId
* @param int $learnPathId
* @param int $learnPathItemId
* @param bool $onlyCorrect
*
* @return array
*/
public function getCorrectAnswersInAllAttempts($learnPathId = 0, $learnPathItemId = 0)
public function getAnswersInAllAttempts($learnPathId = 0, $learnPathItemId = 0, $onlyCorrect = true)
{
$attempts = Event::getExerciseResultsByUser(
api_get_user_id(),
@ -7813,43 +7863,63 @@ class Exercise
api_get_session_id(),
$learnPathId,
$learnPathItemId,
'asc'
'DESC'
);
$corrects = [];
$list = [];
foreach ($attempts as $attempt) {
foreach ($attempt['question_list'] as $answers) {
foreach ($answers as $answer) {
$objAnswer = new Answer($answer['question_id']);
switch ($objAnswer->getQuestionType()) {
case FILL_IN_BLANKS:
$isCorrect = FillBlanks::isCorrect($answer['answer']);
break;
case MATCHING:
case DRAGGABLE:
case MATCHING_DRAGGABLE:
$isCorrect = Matching::isCorrect(
$answer['position'],
$answer['answer'],
$answer['question_id']
);
break;
case ORAL_EXPRESSION:
$isCorrect = false;
break;
default:
$isCorrect = $objAnswer->isCorrectByAutoId($answer['answer']);
}
if ($isCorrect) {
$corrects[$answer['question_id']][] = $answer;
if ($onlyCorrect) {
switch ($objAnswer->getQuestionType()) {
case FILL_IN_BLANKS:
$isCorrect = FillBlanks::isCorrect($answer['answer']);
break;
case MATCHING:
case DRAGGABLE:
case MATCHING_DRAGGABLE:
$isCorrect = Matching::isCorrect(
$answer['position'],
$answer['answer'],
$answer['question_id']
);
break;
case ORAL_EXPRESSION:
$isCorrect = false;
break;
default:
$isCorrect = $objAnswer->isCorrectByAutoId($answer['answer']);
}
if ($isCorrect) {
$list[$answer['question_id']][] = $answer;
}
} else {
$list[$answer['question_id']][] = $answer;
}
}
}
if ($onlyCorrect === false) {
// Only take latest attempt
break;
}
}
return $corrects;
return $list;
}
/**
* Get the correct answers in all attempts.
*
* @param int $learnPathId
* @param int $learnPathItemId
*
* @return array
*/
public function getCorrectAnswersInAllAttempts($learnPathId = 0, $learnPathItemId = 0)
{
return $this->getAnswersInAllAttempts($learnPathId , $learnPathItemId);
}
/**
@ -7881,6 +7951,76 @@ class Exercise
$this->exerciseCategoryId = (int) $value;
}
/**
* @param array $values
*
* @throws \Doctrine\DBAL\DBALException
*/
public function setPageResultConfiguration($values)
{
$pageConfig = api_get_configuration_value('allow_quiz_results_page_config');
if ($pageConfig) {
$params = [
'hide_expected_answer' => isset($values['hide_expected_answer']) ? $values['hide_expected_answer'] : '',
'hide_question_score' => isset($values['hide_question_score']) ? $values['hide_question_score'] : '',
'hide_total_score' => isset($values['hide_total_score']) ? $values['hide_total_score'] : ''
];
$type = Type::getType('array');
$platform = Database::getManager()->getConnection()->getDatabasePlatform();
$this->pageResultConfiguration = $type->convertToDatabaseValue($params, $platform);
}
}
/**
* @param array $defaults
*/
public function setPageResultConfigurationDefaults(&$defaults)
{
$configuration = $this->getPageResultConfiguration();
if (!empty($configuration) && !empty($defaults)) {
$defaults = array_merge($defaults, $configuration);
}
}
/**
* @return array
*/
public function getPageResultConfiguration()
{
$pageConfig = api_get_configuration_value('allow_quiz_results_page_config');
if ($pageConfig) {
/*$params = [
'hide_expected_answer' => isset($values['hide_expected_answer']) ? $values['hide_expected_answer'] : '',
'hide_question_score' => isset($values['hide_question_score']) ? $values['hide_question_score'] : '',
'hide_total_score' => isset($values['hide_total_score']) ? $values['hide_total_score'] : ''
];*/
$type = Type::getType('array');
$platform = Database::getManager()->getConnection()->getDatabasePlatform();
$result = $type->convertToPHPValue($this->pageResultConfiguration, $platform);
return $result;
}
return [];
}
/**
* @param string $attribute
*
* @return mixed|null
*/
public function getPageConfigurationAttribute($attribute)
{
$result = $this->getPageResultConfiguration();
if (!empty($result)) {
$value = isset($result[$attribute]) ? $result[$attribute] : null;
return $value;
}
return null;
}
/**
* @param bool $showPreviousButton
*
@ -7917,6 +8057,26 @@ class Exercise
return api_get_configuration_value('show_exercise_expected_choice');
}
/**
* @return bool
*/
public function showExpectedChoiceColumn()
{
if (!in_array($this->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER
])
) {
$hide = (int) $this->getPageConfigurationAttribute('hide_expected_answer');
if ($hide === 1) {
return false;
}
return true;
}
return false;
}
/**
* @param string $class
* @param string $scoreLabel
@ -7927,6 +8087,11 @@ class Exercise
*/
public function getQuestionRibbon($class, $scoreLabel, $result, $array)
{
$hide = (int) $this->getPageConfigurationAttribute('hide_question_score');
if ($hide === 1) {
return '';
}
if ($this->showExpectedChoice()) {
$html = null;
$hideLabel = api_get_configuration_value('exercise_hide_label');
@ -8072,6 +8237,8 @@ class Exercise
$courseId = $courseInfo['real_id'];
$sessionId = (int) $sessionId;
$exerciseId = (int) $exerciseId;
$result = $this->read($exerciseId);
if (empty($result)) {
@ -8081,7 +8248,7 @@ class Exercise
$statusToFilter = empty($sessionId) ? STUDENT : 0;
$studentList = CourseManager::get_user_list_from_course_code(
api_get_course_id(),
$courseInfo['code'],
$sessionId,
null,
null,
@ -8164,18 +8331,27 @@ class Exercise
$em = Database::getManager();
$links = AbstractLink::getGradebookLinksFromItem(
$this->selectId(),
$this->id,
LINK_EXERCISE,
api_get_course_id(),
api_get_session_id()
$courseInfo['code'],
$sessionId
);
if (empty($links)) {
$links = AbstractLink::getGradebookLinksFromItem(
$this->iId,
LINK_EXERCISE,
$courseInfo['code'],
$sessionId
);
}
if (!empty($links)) {
$repo = $em->getRepository('ChamiloCoreBundle:GradebookLink');
foreach ($links as $link) {
$linkId = $link['id'];
/** @var \Chamilo\CoreBundle\Entity\GradebookLink $exerciseLink */
/** @var GradebookLink $exerciseLink */
$exerciseLink = $repo->find($linkId);
if ($exerciseLink) {
$exerciseLink
@ -9640,7 +9816,7 @@ class Exercise
['id' => 'result_disabled_2', 'onclick' => 'check_results_disabled()']
);
if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (in_array($this->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
$group = $form->addGroup(
$resultDisabledGroup,
null,

@ -185,7 +185,6 @@ if ($form->validate()) {
Display::display_header($nameTools, get_lang('Exercise'));
echo '<div class="actions">';
if ($objExercise->id != 0) {
echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'">'.
Display::return_icon('back.png', get_lang('GoBackToQuestionList'), '', ICON_SIZE_MEDIUM).'</a>';
@ -199,7 +198,7 @@ if ($form->validate()) {
}
$lp_id = (int) $lp_id;
echo "<a href=\"../lp/lp_controller.php?".api_get_cidreq()."&gradebook=&action=add_item&type=step&lp_id=".$lp_id."#resource_tab-2\">".
Display::return_icon('back.png', get_lang("BackTo").' '.get_lang("LearningPaths"), '', ICON_SIZE_MEDIUM)."</a>";
Display::return_icon('back.png', get_lang("BackTo").' '.get_lang('LearningPaths'), '', ICON_SIZE_MEDIUM)."</a>";
} else {
echo '<a href="exercise.php?'.api_get_cidreq().'">'.
Display::return_icon('back.png', get_lang('BackToExercisesList'), '', ICON_SIZE_MEDIUM).
@ -208,11 +207,11 @@ if ($form->validate()) {
}
echo '</div>';
if ($objExercise->feedback_type == 1) {
if (in_array($objExercise->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
echo Display::return_message(get_lang('DirectFeedbackCantModifyTypeQuestion'));
}
if (api_get_setting('search_enabled') == 'true' &&
if (api_get_setting('search_enabled') === 'true' &&
!extension_loaded('xapian')
) {
echo Display::return_message(get_lang('SearchXapianModuleNotInstalled'), 'error');

@ -100,7 +100,7 @@ if (api_is_course_admin() && !in_array($origin, ['learnpath', 'embeddable'])) {
echo '</div>';
}
$feedback_type = $objExercise->feedback_type;
$feedback_type = $objExercise->getFeedbackType();
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
if (!empty($exercise_stat_info['data_tracking'])) {
@ -222,7 +222,7 @@ if (!in_array($origin, ['learnpath', 'embeddable'])) {
Session::erase('duration_time');
}
Display::display_footer();
} elseif ($origin == 'embeddable') {
} elseif ($origin === 'embeddable') {
if (api_is_allowed_to_session_edit()) {
Session::erase('objExercise');
Session::erase('exe_id');
@ -232,14 +232,12 @@ if (!in_array($origin, ['learnpath', 'embeddable'])) {
}
Session::write('attempt_remaining', $remainingMessage);
showEmbeddableFinishButton();
Display::display_reduced_footer();
} else {
$lp_mode = Session::read('lp_mode');
$url = '../lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->feedback_type.'#atoc_'.$learnpath_item_id;
$href = $lp_mode == 'fullscreen' ? ' window.opener.location.href="'.$url.'" ' : ' top.location.href="'.$url.'"';
$url = '../lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->getFeedbackType().'#atoc_'.$learnpath_item_id;
$href = $lp_mode === 'fullscreen' ? ' window.opener.location.href="'.$url.'" ' : ' top.location.href="'.$url.'"';
if (api_is_allowed_to_session_edit()) {
Session::erase('objExercise');

@ -127,7 +127,7 @@ if (empty($objExercise)) {
$objExercise = new Exercise();
$objExercise->read($exercise_id);
}
$feedback_type = $objExercise->feedback_type;
$feedback_type = $objExercise->getFeedbackType();
// Only users can see their own results
if (!$is_allowedToEdit) {
@ -358,7 +358,7 @@ if (!empty($track_exercise_info['data_tracking'])) {
}
// Display the text when finished message if we are on a LP #4227
$end_of_message = $objExercise->selectTextWhenFinished();
$end_of_message = $objExercise->getTextWhenFinished();
if (!empty($end_of_message) && ($origin === 'learnpath')) {
echo Display::return_message($end_of_message, 'normal', false);
echo "<div class='clear'>&nbsp;</div>";

@ -109,7 +109,6 @@ $logInfo = [
];
Event::registerLog($logInfo);
// Error message
$error = '';
$exercise_attempt_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
@ -667,7 +666,7 @@ if ($formSent && isset($_POST)) {
// stores the user answer into the array
$exerciseResult[$key] = $choice[$key];
//saving each question
if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (!in_array($objExercise->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
$nro_question = $current_question; // - 1;
$questionId = $key;
// gets the student choice for this question
@ -1395,7 +1394,7 @@ if (!empty($error)) {
$i++;
continue;
} else {
if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) {
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
@ -1414,11 +1413,23 @@ if (!empty($error)) {
$user_choice = null;
if (isset($attempt_list[$questionId])) {
$user_choice = $attempt_list[$questionId];
} elseif ($objExercise->saveCorrectAnswers) {
$correctAnswers = $objExercise->getCorrectAnswersInAllAttempts(
$learnpath_id,
$learnpath_item_id
);
} 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;
}
if (isset($correctAnswers[$questionId])) {
$user_choice = $correctAnswers[$questionId];
@ -1426,8 +1437,7 @@ if (!empty($error)) {
}
$remind_highlight = '';
//Hides questions when reviewing a ALL_ON_ONE_PAGE exercise see #4542 no_remind_highlight class hide with jquery
// 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
) {

@ -9,13 +9,10 @@ use ChamiloSession as Session;
* @author Julio Montoya <gugli100@gmail.com>
*/
require_once __DIR__.'/../inc/global.inc.php';
api_protect_course_script(false);
require_once api_get_path(LIBRARY_PATH).'geometry.lib.php';
//Display::display_reduced_header();
api_protect_course_script();
echo '<div id="delineation-container">';
require_once api_get_path(LIBRARY_PATH).'geometry.lib.php';
$message = null;
$dbg_local = 0;
@ -34,23 +31,30 @@ $origin = api_get_origin();
// if origin is learnpath
$learnpath_id = 0;
if (isset($_REQUEST['learnpath_id'])) {
$learnpath_id = intval($_REQUEST['learnpath_id']);
$learnpath_id = (int) $_REQUEST['learnpath_id'];
}
$learnpath_item_id = 0;
if (isset($_REQUEST['learnpath_item_id'])) {
$learnpath_item_id = intval($_REQUEST['learnpath_item_id']);
$learnpath_item_id = (int) $_REQUEST['learnpath_item_id'];
}
/** @var Exercise $objExercise */
$objExercise = Session::read('objExercise');
if (empty($objExercise)) {
api_not_allowed();
}
$_SESSION['hotspot_coord'] = [];
$newquestionList = Session::read('newquestionList', []);
$newQuestionList = Session::read('newquestionList', []);
$questionList = Session::read('questionList');
$exerciseId = intval($_GET['exerciseId']);
$exerciseType = intval($_GET['exerciseType']);
$questionNum = intval($_GET['num']);
$nbrQuestions = isset($_GET['nbrQuestions']) ? intval($_GET['nbrQuestions']) : null;
$exerciseId = (int) $_GET['exerciseId'];
$exerciseType = (int) $_GET['exerciseType'];
$questionNum = (int) $_GET['num'];
$nbrQuestions = isset($_GET['nbrQuestions']) ? (int) $_GET['nbrQuestions'] : null;
//clean extra session variables
// Clean extra session variables
Session::erase('objExerciseExtra'.$exerciseId);
Session::erase('exerciseResultExtra'.$exerciseId);
Session::erase('questionListExtra'.$exerciseId);
@ -69,13 +73,13 @@ if (isset($_GET['hotspot'])) {
}
}
$choice_value = '';
$user_array = substr($user_array, 0, -1);
$choice_value = '';
if (isset($_GET['choice'])) {
$choice_value = intval($_GET['choice']);
$choice_value = (int) $_GET['choice'];
}
echo '<div id="delineation-container">';
// Getting the options by js
if (empty($choice_value)) {
echo "<script>
@ -116,9 +120,9 @@ if (empty($choice_value)) {
}
$choice = [];
$questionid = $questionList[$questionNum];
$questionId = $questionList[$questionNum];
// $choice_value => value of the user selection
$choice[$questionid] = isset($choice_value) ? $choice_value : null;
$choice[$questionId] = isset($choice_value) ? $choice_value : null;
// initializing
if (!is_array($exerciseResult)) {
@ -127,7 +131,7 @@ if (!is_array($exerciseResult)) {
// if the user has answered at least one question
if (is_array($choice)) {
if ($exerciseType == EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (in_array($exerciseType, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
// $exerciseResult receives the content of the form.
// Each choice of the student is stored into the array $choice
$exerciseResult = $choice;
@ -147,8 +151,8 @@ Session::write('exerciseResult', $exerciseResult);
Session::write('exerciseResultCoordinates', $exerciseResultCoordinates);
// creates a temporary Question object
if (in_array($questionid, $questionList)) {
$objQuestionTmp = Question:: read($questionid);
if (in_array($questionId, $questionList)) {
$objQuestionTmp = Question:: read($questionId);
$questionName = $objQuestionTmp->selectTitle();
$questionDescription = $objQuestionTmp->selectDescription();
$questionWeighting = $objQuestionTmp->selectWeighting();
@ -156,9 +160,9 @@ if (in_array($questionid, $questionList)) {
$quesId = $objQuestionTmp->selectId(); //added by priya saini
}
$objAnswerTmp = new Answer($questionid);
$objAnswerTmp = new Answer($questionId);
$nbrAnswers = $objAnswerTmp->selectNbrAnswers();
$choice = $exerciseResult[$questionid];
$choice = $exerciseResult[$questionId];
$destination = [];
$comment = '';
$next = 1;
@ -181,27 +185,24 @@ if (!empty($choice_value)) {
$answerWeighting = $objAnswerTmp->selectWeighting($answerId);
$numAnswer = $objAnswerTmp->selectAutoId($answerId);
//delineation
// Delineation
$delineation_cord = $objAnswerTmp->selectHotspotCoordinates(1);
$answer_delineation_destination = $objAnswerTmp->selectDestination(1);
if ($dbg_local > 0) {
error_log(__LINE__.' answerId: '.$answerId.'('.$answerType.') - user delineation_cord: '.$delineation_cord.' - $answer_delineation_destination: '.$answer_delineation_destination, 0);
}
switch ($answerType) {
// for unique answer
case UNIQUE_ANSWER:
$studentChoice = ($choice_value == $numAnswer) ? 1 : 0;
$studentChoice = $choice_value == $numAnswer ? 1 : 0;
if ($studentChoice) {
$questionScore += $answerWeighting;
$totalScore += $answerWeighting;
$newquestionList[] = $questionid;
$newQuestionList[] = $questionId;
}
break;
case HOT_SPOT_DELINEATION:
$studentChoice = $choice[$answerId];
if ($studentChoice) {
$newquestionList[] = $questionid;
$newQuestionList[] = $questionId;
}
if ($answerId === 1) {
$questionScore += $answerWeighting;
@ -219,12 +220,9 @@ if (!empty($choice_value)) {
}
} elseif ($answerType == HOT_SPOT_DELINEATION) {
if ($next) {
if ($dbg_local > 0) {
error_log(__LINE__.' - next', 0);
}
$hot_spot_load = true; //apparently the script is called twice
$user_answer = $user_array;
$_SESSION['exerciseResultCoordinates'][$questionid] = $user_answer; //needed for exercise_result.php
$_SESSION['exerciseResultCoordinates'][$questionId] = $user_answer; //needed for exercise_result.php
// we compare only the delineation not the other points
$answer_question = $_SESSION['hotspot_coord'][1];
@ -255,12 +253,8 @@ if (!empty($choice_value)) {
$excess = $poly_results['s2Only'];
}
//$overlap = round(polygons_overlap($poly_answer,$poly_user)); //this is an area in pixels
if ($dbg_local > 0) {
error_log(__LINE__.' - Polygons results are '.print_r($poly_results, 1), 0);
}
if ($overlap < 1) {
//shortcut to avoid complicated calculations
// shortcut to avoid complicated calculations
$final_overlap = 0;
$final_missing = 100;
$final_excess = 100;
@ -293,15 +287,15 @@ if (!empty($choice_value)) {
if ($answerId === 1) {
//setting colors
if ($final_overlap >= $threadhold1) {
$overlap_color = true; //echo 'a';
$overlap_color = true;
}
if ($final_excess <= $threadhold2) {
$excess_color = true; //echo 'b';
$excess_color = true;
}
if ($final_missing <= $threadhold3) {
$missing_color = true; //echo 'c';
$missing_color = true;
}
$try_hotspot = null;
@ -328,17 +322,11 @@ if (!empty($choice_value)) {
$select_question_hotspot = $destination_items[3];
$url_hotspot = $destination_items[4];
} elseif ($answerId > 1) {
if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') {
if ($dbg_local > 0) {
error_log(__LINE__.' - answerId is of type noerror', 0);
}
//type no error shouldn't be treated
if ($objAnswerTmp->selectHotspotType($answerId) === 'noerror') {
// Type no error shouldn't be treated
$next = 1;
continue;
}
if ($dbg_local > 0) {
error_log(__LINE__.' - answerId is >1 so we\'re probably in OAR', 0);
}
//check the intersection between the oar and the user
//echo 'user'; print_r($x_user_list); print_r($y_user_list);
//echo 'official';print_r($x_list);print_r($y_list);
@ -347,14 +335,14 @@ if (!empty($choice_value)) {
//$delineation_cord=$objAnswerTmp->selectHotspotCoordinates($answerId);
$delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId); //getting the oars coordinates
$poly_answer = convert_coordinates($delineation_cord, '|');
// getting max coordinates
$max_coord = poly_get_max(
$poly_user,
$poly_answer
); //getting max coordinates
);
$test = false;
// if ($answerId == 2 ){$test = true;} for test oars
if (empty($_GET['hotspot'])) { //no user response
if (empty($_GET['hotspot'])) {
// no user response
$overlap = false;
} else {
// poly_compile really works tested with gnuplot
@ -402,29 +390,22 @@ if (!empty($choice_value)) {
$url_hotspot = $destination_items[4];
}
}
} else {
// the first delineation feedback
if ($dbg_local > 0) {
error_log(__LINE__.' first', 0);
}
}
}
}
$overlap_color = 'red';
if ($overlap_color) {
$overlap_color = 'green';
} else {
$overlap_color = 'red';
}
$missing_color = 'red';
if ($missing_color) {
$missing_color = 'green';
} else {
$missing_color = 'red';
}
$excess_color = 'red';
if ($excess_color) {
$excess_color = 'green';
} else {
$excess_color = 'red';
}
if (!is_numeric($final_overlap)) {
@ -466,52 +447,50 @@ if (!empty($choice_value)) {
</tr>
</table>';
}
Session::write('newquestionList', $newquestionList);
Session::write('newquestionList', $newQuestionList);
$links = '';
if (isset($choice_value) && $choice_value == -1) {
if ($answerType != HOT_SPOT_DELINEATION) {
$links .= '<a href="#" onclick="tb_remove();">'.get_lang('ChooseAnAnswer').'</a><br />';
if ($objExercise->getFeedbackType() === EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (isset($choice_value) && $choice_value == -1) {
if ($answerType != HOT_SPOT_DELINEATION) {
$links .= '<a href="#" onclick="tb_remove();">'.get_lang('ChooseAnAnswer').'</a><br />';
}
}
}
$destinationid = null;
$destinationId = null;
if ($answerType != HOT_SPOT_DELINEATION) {
if (!empty($destination)) {
$item_list = explode('@@', $destination);
$try = $item_list[0];
$lp = $item_list[1];
$destinationid = $item_list[2];
$destinationId = $item_list[2];
$url = $item_list[3];
}
$table_resume = '';
} else {
$try = $try_hotspot;
$lp = $lp_hotspot;
$destinationid = $select_question_hotspot;
$destinationId = $select_question_hotspot;
$url = $url_hotspot;
$exerciseResult[$questionId] = 0;
if ($organs_at_risk_hit == 0 && $wrong_results == false) {
// no error = no oar and no wrong result for delineation
//show if no error
//echo 'no error';
// show if no error
$comment = $answerComment = $objAnswerTmp->selectComment($nbrAnswers);
$answerDestination = $objAnswerTmp->selectDestination($nbrAnswers);
//we send the error
// we send the error
$destination_items = explode('@@', $answerDestination);
$try = $destination_items[1];
$lp = $destination_items[2];
$destinationid = $destination_items[3];
$destinationId = $destination_items[3];
$url = $destination_items[4];
$exerciseResult[$questionid] = 1;
} else {
$exerciseResult[$questionid] = 0;
$exerciseResult[$questionId] = 1;
}
}
// the link to retry the question
if (isset($try) && $try == 1) {
$num_value_array = array_keys($questionList, $questionid);
$num_value_array = array_keys($questionList, $questionId);
$links .= Display:: return_icon(
'reload.gif',
'',
@ -530,6 +509,7 @@ if (!empty($lp)) {
['style' => 'padding-left:0px;padding-right:5px;']
).'<a target="_blank" href="'.$lp_url.'">'.get_lang('SeeTheory').'</a><br />';
}
$links .= '<br />';
// the link to an external website or link
@ -541,8 +521,13 @@ if (!empty($url)) {
).'<a target="_blank" href="'.$url.'">'.get_lang('VisitUrl').'</a><br /><br />';
}
if ($objExercise->getFeedbackType() === EXERCISE_FEEDBACK_TYPE_POPUP) {
$nextQuestion = $questionNum + 1;
$destinationId = isset($questionList[$nextQuestion]) ? $questionList[$nextQuestion] : -1;
}
// the link to finish the test
if ($destinationid == -1) {
if ($destinationId == -1) {
$links .= Display:: return_icon(
'finish.gif',
'',
@ -550,17 +535,18 @@ if ($destinationid == -1) {
).'<a onclick="SendEx(-1);" href="#">'.get_lang('EndActivity').'</a><br /><br />';
} else {
// the link to other question
if (in_array($destinationid, $questionList)) {
$objQuestionTmp = Question :: read($destinationid);
if (in_array($destinationId, $questionList)) {
$objQuestionTmp = Question::read($destinationId);
$questionName = $objQuestionTmp->selectTitle();
$num_value_array = (array_keys($questionList, $destinationid));
$links .= Display:: return_icon(
$num_value_array = array_keys($questionList, $destinationId);
$icon = Display::return_icon(
'quiz.png',
'',
['style' => 'padding-left:0px;padding-right:5px;']
);
$links .= '<a onclick="SendEx('.$num_value_array[0].');" href="#">'.
get_lang('GoToQuestion').' '.$num_value_array[0].'</a><br /><br />';
get_lang('Question').' '.$num_value_array[0].'</a>&nbsp;';
$links .= $icon;
}
}
@ -568,25 +554,20 @@ echo '<script>
function SendEx(num) {
if (num == -1) {
window.location.href = "exercise_result.php?take_session=1&exerciseId='.$exerciseId.'&num="+num+"&exerciseType='.$exerciseType.'&origin='.$origin.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
//tb_remove();
} else {
num -= 1;
window.location.href = "exercise_submit.php?tryagain=1&exerciseId='.$exerciseId.'&num="+num+"&exerciseType='.$exerciseType.'&origin='.$origin.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
//tb_remove();
}
return false;
}
</script>';
if ($links != '') {
echo '<h1><div style="color:#333;">'.get_lang('Feedback').'</div></h1>';
if (!empty($links)) {
//echo '<h1><div style="color:#333;">'.get_lang('Feedback').'</div></h1>';
if ($answerType == HOT_SPOT_DELINEATION) {
if ($organs_at_risk_hit > 0) {
//$message='<p>'.get_lang('YourDelineation').'</p>';
//$message.=$table_resume;
$message .= '<br />'.get_lang('ResultIs').' <b>'.get_lang('Unacceptable').'</b><br />';
//if ($wrong_results) { }
$message .= '<p style="color:#DC0A0A;"><b>'.get_lang('OARHit').'</b></p>';
$message .= '<p>'.$comment.'</p>';
} else {
@ -595,16 +576,17 @@ if ($links != '') {
$message .= '<br />'.get_lang('ResultIs').' <b>'.$result_comment.'</b><br />';
$message .= '<p>'.$comment.'</p>';
}
echo '<br />';
echo $message;
} else {
echo '<p>'.$comment.'</p>';
}
echo '<h3>'.$links.'</h3>';
echo '<div style="padding-left: 450px"><h5>'.$links.'</h5></div>';
echo '</div>';
Session::write('hot_spot_result', $message);
$_SESSION['hotspot_delineation_result'][$exerciseId][$questionid] = [$message, $exerciseResult[$questionid]];
//reseting the exerciseResult variable
$_SESSION['hotspot_delineation_result'][$exerciseId][$questionId] = [$message, $exerciseResult[$questionId]];
// Resetting the exerciseResult variable
Session::write('exerciseResult', $exerciseResult);
//save this variables just in case the exercise loads an LP with other exercise
@ -615,10 +597,7 @@ if ($links != '') {
$questionNum++;
echo '<script>
window.location.href = "exercise_submit.php?exerciseId='.$exerciseId.'&num='.$questionNum.'&exerciseType='.$exerciseType.'&'.api_get_cidreq().'";
//tb_remove();
</script>';
}
echo '</div>';
//Display::display_footer();

@ -266,13 +266,11 @@ class GlobalMultipleAnswer extends Question
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'"><tr>';
if (!in_array($exercise->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
])
) {
if (!in_array($exercise->results_disabled, [RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER])) {
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
}
$header .= '<th>'.get_lang('Answer').'</th>';

@ -159,9 +159,9 @@ if ($submitAnswers || $buttonBack) {
}
$questionWeighting = $nbrGoodAnswers = 0;
$select_question = $_POST['select_question'];
$select_question = isset($_POST['select_question']) ? $_POST['select_question'] : null;
$try = isset($_POST['try']) ? $_POST['try'] : [];
$url = $_POST['url'];
$url = isset($_POST['url']) ? $_POST['url'] : '';
$destination = [];
$threadhold1 = $_POST['threadhold1'];
@ -169,10 +169,6 @@ if ($submitAnswers || $buttonBack) {
$threadhold3 = $_POST['threadhold3'];
for ($i = 1; $i <= $nbrAnswers; $i++) {
if ($debug > 0) {
echo str_repeat('&nbsp;', 4).'$answerType is HOT_SPOT'."<br />\n";
}
$reponse[$i] = trim($reponse[$i]);
$comment[$i] = trim($comment[$i]);
$weighting[$i] = $weighting[$i];
@ -180,19 +176,19 @@ if ($submitAnswers || $buttonBack) {
if (empty($threadhold1[$i])) {
$threadhold1_str = 0;
} else {
$threadhold1_str = intval($threadhold1[$i]);
$threadhold1_str = (int) $threadhold1[$i];
}
if (empty($threadhold2[$i])) {
$threadhold2_str = 0;
} else {
$threadhold2_str = intval($threadhold2[$i]);
$threadhold2_str = (int) $threadhold2[$i];
}
if (empty($threadhold3[$i])) {
$threadhold3_str = 0;
} else {
$threadhold3_str = intval($threadhold3[$i]);
$threadhold3_str = (int) $threadhold3[$i];
}
$threadhold_total = $threadhold1_str.';'.$threadhold2_str.';'.$threadhold3_str;
@ -209,9 +205,8 @@ if ($submitAnswers || $buttonBack) {
$lp_str = $lp[$i];
}
if ($url[$i] == '') {
$url_str = '';
} else {
$url_str = '';
if (isset($url[$i]) && !empty($url[$i])) {
$url_str = $url[$i];
}
@ -245,14 +240,14 @@ if ($submitAnswers || $buttonBack) {
$objAnswer->cancel();
break;
}
} // end for()
}
//now the noerror section
$selectQuestionNoError = Security::remove_XSS($_POST['select_question_noerror']);
$lp_noerror = Security::remove_XSS($_POST['lp_noerror']);
// now the noerror section
$selectQuestionNoError = isset($_POST['select_question_noerror']) ? Security::remove_XSS($_POST['select_question_noerror']) : null;
$lp_noerror = isset($_POST['lp_noerror']) ? Security::remove_XSS($_POST['lp_noerror']) : '';
$try_noerror = isset($_POST['try_noerror']) ? Security::remove_XSS($_POST['try_noerror']) : null;
$url_noerror = Security::remove_XSS($_POST['url_noerror']);
$comment_noerror = Security::remove_XSS($_POST['comment_noerror']);
$url_noerror = isset($_POST['url_noerror']) ? Security::remove_XSS($_POST['url_noerror']) : null;
$comment_noerror = isset($_POST['comment_noerror']) ? Security::remove_XSS($_POST['comment_noerror']) : null;
$threadhold_total = '0;0;0';
if ($try_noerror == 'on') {
@ -385,7 +380,7 @@ if (isset($modifyAnswers)) {
for ($i = 1; $i <= $nbrAnswers; $i++) {
$reponse[$i] = $objAnswer->selectAnswer($i);
if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$comment[$i] = $objAnswer->selectComment($i);
}
@ -436,7 +431,7 @@ if (isset($modifyAnswers)) {
$_SESSION['tmp_answers'] = [];
$_SESSION['tmp_answers']['answer'] = $reponse;
if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$_SESSION['tmp_answers']['comment'] = $comment;
}
@ -474,7 +469,7 @@ if (isset($modifyAnswers)) {
$nbrAnswers--;
// Remove the last answer
$tmp = array_pop($_SESSION['tmp_answers']['answer']);
if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$tmp = array_pop($_SESSION['tmp_answers']['comment']);
}
$tmp = array_pop($_SESSION['tmp_answers']['weighting']);
@ -494,7 +489,7 @@ if (isset($modifyAnswers)) {
// Add a new answer
$_SESSION['tmp_answers']['answer'][] = '';
if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$_SESSION['tmp_answers']['comment'][] = '';
}
$_SESSION['tmp_answers']['weighting'][] = '1';
@ -615,7 +610,7 @@ if (isset($modifyAnswers)) {
<th width="5">&nbsp;</th>
<th><?php echo get_lang('HotspotDescription'); ?> *</th>
<?php
if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
echo '<th>'.get_lang('Comment').'</th>';
if ($answerType == HOT_SPOT_DELINEATION) {
echo '<th >'.get_lang('Scenario').'</th>';
@ -736,7 +731,7 @@ if (isset($modifyAnswers)) {
<input type="hidden" name="hotspot_coordinates[<?php echo $i; ?>]" value="<?php
echo empty($hotspot_coordinates[$i]) ? '0;0|0|0' : $hotspot_coordinates[$i]; ?>"/>
</td>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
<?php if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
<td>
<div class="checkbox">
@ -795,7 +790,7 @@ if (isset($modifyAnswers)) {
name="comment[<?php echo $i; ?>]"
style="width: 100%"><?php echo Security::remove_XSS($comment[$i]); ?></textarea>
</td>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
<?php if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
<td>
<table>
@ -850,7 +845,7 @@ if (isset($modifyAnswers)) {
<tr>
<th width="5">&nbsp;<?php /* echo get_lang('Hotspot'); */ ?></th>
<th><?php echo get_lang('OAR'); ?>*</th>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
<?php if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
<th colspan="2"><?php echo get_lang('Comment'); ?></th>
<th><?php if ($answerType == HOT_SPOT_DELINEATION) {
@ -883,7 +878,7 @@ if (isset($modifyAnswers)) {
<input type="hidden" name="hotspot_coordinates[<?php echo $i; ?>]" value="<?php
echo empty($hotspot_coordinates[$i]) ? '0;0|0|0' : $hotspot_coordinates[$i]; ?>"/>
</td>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
<?php if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
<td>
<div class="checkbox">
@ -1029,7 +1024,7 @@ if (isset($modifyAnswers)) {
?>
<tr>
<th colspan="2"><?php echo get_lang('IfNoError'); ?></th>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
<?php if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
<th colspan="2"><?php echo get_lang('Feedback'); ?></th>
<th><?php echo get_lang('Scenario'); ?></th>
@ -1049,7 +1044,7 @@ if (isset($modifyAnswers)) {
<textarea class="form-control" wrap="virtual" rows="3" cols="25"
name="comment_noerror"><?php echo Security::remove_XSS($comment_noerror); ?></textarea>
</td>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
<?php if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
<td>
<div class="checkbox">

@ -292,13 +292,17 @@ class Matching extends Question
])
) {
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
//if ($exercise->showExpectedChoiceColumn()) {
//$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
//}
}
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
} else {
$header .= '<th>'.get_lang('CorrespondsTo').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('CorrespondsTo').'</th>';
}
}
$header .= '</tr>';

@ -235,11 +235,8 @@ class MultipleAnswer extends Question
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
if (!in_array($exercise->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
])
) {
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}

@ -233,12 +233,13 @@ class MultipleAnswerCombination extends Question
$header .= '<table class="'.$this->question_table_class.'"><tr>';
if (!in_array($exercise->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER
])
) {
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
}
$header .= '<th>'.get_lang('Answer').'</th>';

@ -52,7 +52,7 @@ class MultipleAnswerTrueFalse extends Question
$html .= '<th>'.get_lang('Answer').'</th>';
// show column comment when feedback is enable
if ($obj_ex->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($obj_ex->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$html .= '<th>'.get_lang('Comment').'</th>';
}
@ -146,7 +146,7 @@ class MultipleAnswerTrueFalse extends Question
);
// show comment when feedback is enable
if ($obj_ex->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
if ($obj_ex->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
$form->addElement(
'html_editor',
'comment['.$i.']',
@ -314,12 +314,13 @@ class MultipleAnswerTrueFalse extends Question
$header .= '<table class="'.$this->question_table_class.'"><tr>';
if (!in_array($exercise->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER
])
) {
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
}
$header .= '<th>'.get_lang('Answer').'</th>';
@ -327,7 +328,7 @@ class MultipleAnswerTrueFalse extends Question
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM ||
if ($exercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM ||
in_array(
$exercise->results_disabled,
[

@ -286,7 +286,7 @@ if (!empty($attempts)) {
]
) || (
$objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY &&
$objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_END
$objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_END
)
) {
if ($blockShowAnswers &&
@ -355,7 +355,7 @@ if (!empty($attempts)) {
$header_names = [get_lang('Attempt'), get_lang('StartDate'), get_lang('IP')];
break;
case RESULT_DISABLE_SHOW_SCORE_ONLY:
if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_END) {
if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_END) {
$header_names = [get_lang('Attempt'), get_lang('StartDate'), get_lang('IP'), get_lang('Score')];
} else {
$header_names = [

@ -1816,17 +1816,17 @@ abstract class Question
*/
public static function displayTypeMenu($objExercise)
{
$feedback_type = $objExercise->feedback_type;
$feedbackType = $objExercise->getFeedbackType();
$exerciseId = $objExercise->id;
// 1. by default we show all the question types
$question_type_custom_list = self::get_question_type_list();
if (!isset($feedback_type)) {
$feedback_type = 0;
if (!isset($feedbackType)) {
$feedbackType = 0;
}
if ($feedback_type == 1) {
if (in_array($feedbackType, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
//2. but if it is a feedback DIRECT we only show the UNIQUE_ANSWER type that is currently available
$question_type_custom_list = [
UNIQUE_ANSWER => self::$questionTypes[UNIQUE_ANSWER],
@ -1875,7 +1875,7 @@ abstract class Question
ICON_SIZE_BIG
);
} else {
if ($feedback_type == 1) {
if (in_array($feedbackType, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) {
echo $url = "<a href=\"question_pool.php?".api_get_cidreq()."&type=1&fromExercise=$exerciseId\">";
} else {
echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&fromExercise='.$exerciseId.'">';
@ -2403,7 +2403,7 @@ abstract class Question
{
return
in_array($this->type, $this->questionTypeWithFeedback) &&
$exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM;
$exercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM;
}
/**

@ -43,7 +43,6 @@ $ajax_url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&
<?php echo get_lang('AreYouSureToDelete'); ?>
</p>
</div>
<script>
$(function () {
$("#dialog:ui-dialog").dialog("destroy");
@ -148,7 +147,7 @@ $ajax_url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&
</script>
<?php
//we filter the type of questions we can add
// Filter the type of questions we can add
Question::displayTypeMenu($objExercise);
echo '<div id="message"></div>';

@ -478,7 +478,10 @@ $new_question_list = [];
$new_question_list['-1'] = get_lang('All');
if (!empty($_course)) {
foreach ($question_list as $key => $item) {
if ($objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (in_array(
$objExercise->getFeedbackType(),
[EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP]
)) {
if (!in_array($key, [HOT_SPOT_DELINEATION, UNIQUE_ANSWER])) {
continue;
}

@ -58,12 +58,18 @@ class UniqueAnswer extends Question
*/
$feedback_title = '';
if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
//Scenario
$comment_title = '<th width="20%">'.get_lang('Comment').'</th>';
$feedback_title = '<th width="20%">'.get_lang('Scenario').'</th>';
} else {
$comment_title = '<th width="40%">'.get_lang('Comment').'</th>';
switch ($obj_ex->getFeedbackType()) {
case EXERCISE_FEEDBACK_TYPE_DIRECT:
// Scenario
$comment_title = '<th width="20%">'.get_lang('Comment').'</th>';
$feedback_title = '<th width="20%">'.get_lang('Scenario').'</th>';
break;
case EXERCISE_FEEDBACK_TYPE_POPUP:
$comment_title = '<th width="20%">'.get_lang('Comment').'</th>';
break;
default:
$comment_title = '<th width="40%">'.get_lang('Comment').'</th>';
break;
}
$html = '<table class="table table-striped table-hover">
@ -218,52 +224,14 @@ class UniqueAnswer extends Question
'required'
);
if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
$form->addHtmlEditor(
'comment['.$i.']',
null,
null,
false,
$editor_config
);
// Direct feedback
//Adding extra feedback fields
$group = [];
$group['try'.$i] = $form->createElement(
'checkbox',
'try'.$i,
null,
get_lang('TryAgain')
);
$group['lp'.$i] = $form->createElement(
'select',
'lp'.$i,
get_lang('SeeTheory').': ',
$select_lp_id
);
$group['destination'.$i] = $form->createElement(
'select',
'destination'.$i,
get_lang('GoToQuestion').': ',
$select_question
);
$group['url'.$i] = $form->createElement(
'text',
'url'.$i,
get_lang('Other').': ',
[
'class' => 'col-md-2',
'placeholder' => get_lang('Other'),
]
);
$form->addGroup($group, 'scenario');
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}',
'scenario'
);
} else {
$form->addHtmlEditor('comment['.$i.']', null, null, false, $editor_config);
switch ($obj_ex->getFeedbackType()) {
case EXERCISE_FEEDBACK_TYPE_DIRECT:
$this->setDirectOptions($i, $form, $renderer, $select_lp_id, $select_question);
break;
case EXERCISE_FEEDBACK_TYPE_POPUP:
default:
$form->addHtmlEditor('comment['.$i.']', null, null, false, $editor_config);
break;
}
$form->addText('weighting['.$i.']', null, null, ['value' => '0']);
$form->addHtml('</tr>');
@ -314,6 +282,59 @@ class UniqueAnswer extends Question
$form->setConstants(['nb_answers' => $nb_answers]);
}
public function setDirectOptions($i, FormValidator $form, $renderer, $select_lp_id, $select_question)
{
$editor_config = [
'ToolbarSet' => 'TestProposedAnswer',
'Width' => '100%',
'Height' => '125',
];
$form->addHtmlEditor(
'comment['.$i.']',
null,
null,
false,
$editor_config
);
// Direct feedback
//Adding extra feedback fields
$group = [];
$group['try'.$i] = $form->createElement(
'checkbox',
'try'.$i,
null,
get_lang('TryAgain')
);
$group['lp'.$i] = $form->createElement(
'select',
'lp'.$i,
get_lang('SeeTheory').': ',
$select_lp_id
);
$group['destination'.$i] = $form->createElement(
'select',
'destination'.$i,
get_lang('GoToQuestion').': ',
$select_question
);
$group['url'.$i] = $form->createElement(
'text',
'url'.$i,
get_lang('Other').': ',
[
'class' => 'col-md-2',
'placeholder' => get_lang('Other'),
]
);
$form->addGroup($group, 'scenario');
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}',
'scenario'
);
}
/**
* {@inheritdoc}
*/
@ -414,11 +435,7 @@ class UniqueAnswer extends Question
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
if (!in_array($exercise->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
])
) {
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}

@ -54,7 +54,7 @@ class UniqueAnswerNoOption extends Question
*/
$feedback_title = '';
if ($obj_ex->selectFeedbackType() == 1) {
if ($obj_ex->getFeedbackType() == 1) {
$editor_config['Width'] = '250';
$editor_config['Height'] = '110';
$comment_title = '<th width="50%" >'.get_lang('Comment').'</th>';
@ -405,12 +405,13 @@ class UniqueAnswerNoOption extends Question
$header .= '<table class="'.$this->question_table_class.'"><tr>';
if (!in_array($exercise->results_disabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
//RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER
])
) {
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
if ($exercise->showExpectedChoiceColumn()) {
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
}
}
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {

@ -45,19 +45,17 @@ if ($showlink == '0' && $showeval == '0') {
$cat = Category::load($categoryId);
$userId = isset($_GET['userid']) ? (int) $_GET['userid'] : 0;
$alleval = null;
if ($showeval) {
$alleval = $cat[0]->get_evaluations($userId, true);
} else {
$alleval = null;
}
$alllinks = null;
if ($showlink) {
$alllinks = $cat[0]->get_links($userId, true);
} else {
$alllinks = null;
}
if (isset($export_flatview_form) && !$file_type == 'pdf') {
if (isset($export_flatview_form) && !$file_type === 'pdf') {
Display::addFlash(
Display::return_message(
$export_flatview_form->toHtml(),
@ -76,7 +74,7 @@ $simple_search_form = new UserForm(
null,
'simple_search_form',
null,
api_get_self().'?selectcat='.$category_id
api_get_self().'?selectcat='.$category_id.'&'.api_get_cidreq()
);
$values = $simple_search_form->exportValues();
@ -91,10 +89,9 @@ if ($simple_search_form->validate() && empty($keyword)) {
if (!empty($keyword)) {
$users = GradebookUtils::find_students($keyword);
} else {
$users = null;
if (isset($alleval) && isset($alllinks)) {
$users = GradebookUtils::get_all_users($alleval, $alllinks);
} else {
$users = null;
}
}
$offset = isset($_GET['offset']) ? $_GET['offset'] : '0';
@ -176,7 +173,7 @@ if (isset($_GET['exportpdf'])) {
if ($export_pdf_form->validate()) {
$params = $export_pdf_form->exportValues();
Display::set_header(null, false, false);
Display::set_header();
$params['join_firstname_lastname'] = true;
$params['show_official_code'] = true;
$params['export_pdf'] = true;
@ -214,7 +211,7 @@ if (isset($_GET['print'])) {
}
if (!empty($_GET['export_report']) &&
$_GET['export_report'] == 'export_report'
$_GET['export_report'] === 'export_report'
) {
if (api_is_platform_admin() || api_is_course_admin() || api_is_session_general_coach() || $isDrhOfCourse) {
$user_id = null;

@ -39,11 +39,21 @@ switch ($action) {
if (!empty($itemId)) {
$link = LinkFactory::create(LINK_EXERCISE);
$links = $link::load($itemId);
$exercise = new Exercise(api_get_course_int_id());
/** @var ExerciseLink $link */
foreach ($links as $link) {
$exercise = new Exercise(api_get_course_int_id());
$exercise->read($link->get_ref_id());
$exercise->generateStats($link->get_ref_id(), api_get_course_info(), api_get_session_id());
$exerciseId = $link->get_ref_id();
$data = $link->get_exercise_data();
if (empty($data)) {
continue;
}
$exerciseId = $data['id'];
$result = $exercise->read($exerciseId);
if ($result) {
$exercise->generateStats($exerciseId, api_get_course_info(), api_get_session_id());
}
}
Display::addFlash(Display::return_message(get_lang('Updated')));
}

@ -2525,7 +2525,6 @@ class Category implements GradebookItem
Session::write('gradebook_dest', $url);
}
/**
* @return int
*/

@ -240,7 +240,7 @@ class ExerciseLink extends AbstractLink
$courseId = $this->getCourseId();
$exerciseData = $this->get_exercise_data();
$exerciseId = isset($exerciseData['id']) ? $exerciseData['id'] : 0;
$exerciseId = isset($exerciseData['id']) ? (int) $exerciseData['id'] : 0;
$stud_id = (int) $stud_id;
if (empty($exerciseId)) {
@ -262,7 +262,7 @@ class ExerciseLink extends AbstractLink
}
$exercise = new Exercise($courseId);
$exercise->read($exerciseData['id']);
$exercise->read($exerciseId);
if (!$this->is_hp) {
if ($exercise->exercise_was_added_in_lp == false) {
@ -303,7 +303,7 @@ class ExerciseLink extends AbstractLink
ON (hp.exe_name = doc.path AND doc.c_id = hp.c_id)
WHERE
hp.c_id = $courseId AND
doc.id = ".$exerciseId;
doc.id = $exerciseId";
if (!empty($stud_id)) {
$sql .= " AND hp.exe_user_id = $stud_id ";
@ -315,7 +315,12 @@ class ExerciseLink extends AbstractLink
if (isset($stud_id) && empty($type)) {
// for 1 student
if ($data = Database::fetch_array($scores)) {
$result = [$data['score'], $data['max_score']];
$attempts = Database::query($sql);
$counter = 0;
while ($attempt = Database::fetch_array($attempts)) {
$counter++;
}
$result = [$data['score'], $data['max_score'], $data['exe_date'], $counter];
if ($cacheAvailable) {
$cacheDriver->save($key, $result);
}
@ -357,11 +362,11 @@ class ExerciseLink extends AbstractLink
if ($data['max_score'] != 0) {
$students[$data['exe_user_id']] = $data['score'];
$student_count++;
if ($data['score'] > $bestResult) {
$bestResult = $data['score'];
if ($data['exe_result'] > $bestResult) {
$bestResult = $data['exe_result'];
}
$sum += $data['score'] / $data['max_score'];
$sumResult += $data['score'];
$sumResult += $data['exe_result'];
$weight = $data['max_score'];
}
}
@ -500,9 +505,9 @@ class ExerciseLink extends AbstractLink
{
if ($this->is_hp == 1) {
return 'HotPotatoes';
} else {
return get_lang('Quiz');
}
return get_lang('Quiz');
}
public function needs_name_and_description()
@ -550,58 +555,45 @@ class ExerciseLink extends AbstractLink
{
switch ($type) {
case 'best':
break;
}
}
/**
* Lazy load function to get the database table of the exercise.
*/
private function get_exercise_table()
{
$this->exercise_table = Database::get_course_table(TABLE_QUIZ_TEST);
return $this->exercise_table;
}
/**
* Lazy load function to get the database contents of this exercise.
*/
private function get_exercise_data()
public function get_exercise_data()
{
$tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
if ($this->is_hp == 1) {
$table = Database::get_course_table(TABLE_DOCUMENT);
} else {
$table = $this->get_exercise_table();
$table = Database::get_course_table(TABLE_QUIZ_TEST);
}
$exerciseId = $this->get_ref_id();
if ($table == '') {
return false;
} elseif (empty($this->exercise_data)) {
if (empty($this->exercise_data)) {
if ($this->is_hp == 1) {
$sql = "SELECT * FROM $table ex
INNER JOIN $tableItemProperty ip
ON (ip.ref = ex.id AND ip.c_id = ex.c_id)
WHERE
ip.c_id = $this->course_id AND
ex.c_id = $this->course_id AND
ip.ref = $exerciseId AND
ip.tool = '".TOOL_DOCUMENT."' AND
ex.path LIKE '%htm%' AND
ex.path LIKE '%HotPotatoes_files%' AND
ip.visibility = 1";
INNER JOIN $tableItemProperty ip
ON (ip.ref = ex.id AND ip.c_id = ex.c_id)
WHERE
ip.c_id = $this->course_id AND
ex.c_id = $this->course_id AND
ip.ref = $exerciseId AND
ip.tool = '".TOOL_DOCUMENT."' AND
ex.path LIKE '%htm%' AND
ex.path LIKE '%HotPotatoes_files%' AND
ip.visibility = 1";
$result = Database::query($sql);
$this->exercise_data = Database::fetch_array($result);
} else {
// Try with iid
$sql = 'SELECT * FROM '.$table.'
WHERE
c_id = '.$this->course_id.' AND
iid = '.$exerciseId;
WHERE
c_id = '.$this->course_id.' AND
iid = '.$exerciseId;
$result = Database::query($sql);
$rows = Database::num_rows($result);
@ -610,15 +602,29 @@ class ExerciseLink extends AbstractLink
} else {
// Try wit id
$sql = 'SELECT * FROM '.$table.'
WHERE
c_id = '.$this->course_id.' AND
id = '.$exerciseId;
WHERE
c_id = '.$this->course_id.' AND
id = '.$exerciseId;
$result = Database::query($sql);
$this->exercise_data = Database::fetch_array($result);
}
}
}
if (empty($this->exercise_data)) {
return false;
}
return $this->exercise_data;
}
/**
* Lazy load function to get the database table of the exercise.
*/
private function get_exercise_table()
{
$this->exercise_table = Database::get_course_table(TABLE_QUIZ_TEST);
return $this->exercise_table;
}
}

@ -34,17 +34,18 @@ class StudentPublicationLink extends AbstractLink
// with the same title as the evaluation name
$eval = $this->get_evaluation();
$stud_id = intval($stud_id);
$stud_id = (int) $stud_id;
$itemProperty = $this->get_itemprop_table();
$workTable = $this->get_studpub_table();
$courseId = $this->course_id;
$sql = "SELECT pub.url
FROM $itemProperty prop INNER JOIN $workTable pub
FROM $itemProperty prop
INNER JOIN $workTable pub
ON (prop.c_id = pub.c_id AND prop.ref = pub.id)
WHERE
prop.c_id = ".$courseId." AND
pub.c_id = ".$courseId." AND
prop.c_id = $courseId AND
pub.c_id = $courseId AND
prop.tool = 'work' AND
prop.insert_user_id = $stud_id AND
pub.title = '".Database::escape_string($eval->get_name())."' AND
@ -82,7 +83,8 @@ class StudentPublicationLink extends AbstractLink
return [];
}
$em = Database::getManager();
$session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
$sessionId = $this->get_session_id();
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
/*
if (empty($session_id)) {
$session_condition = api_get_session_condition(0, true);
@ -128,7 +130,7 @@ class StudentPublicationLink extends AbstractLink
$id = $data['id'];
$em = Database::getManager();
$session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
$session = $em->find('ChamiloCoreBundle:Session', $this->get_session_id());
$results = $em
->getRepository('ChamiloCourseBundle:CStudentPublication')
->findBy([
@ -155,7 +157,7 @@ class StudentPublicationLink extends AbstractLink
return [];
}
$id = $data['id'];
$session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
$session = api_get_session_entity($this->get_session_id());
$assignment = $em
->getRepository('ChamiloCourseBundle:CStudentPublication')
@ -225,7 +227,7 @@ class StudentPublicationLink extends AbstractLink
// for 1 student
if (!empty($stud_id)) {
if (!count($scores)) {
return '';
return [null, null];
}
$data = $scores[0];
@ -233,6 +235,8 @@ class StudentPublicationLink extends AbstractLink
return [
$data->getQualification(),
$assignment->getQualification(),
api_get_local_time($assignment->getDateOfQualification()),
1,
];
}
@ -261,7 +265,7 @@ class StudentPublicationLink extends AbstractLink
}
if ($rescount == 0) {
return null;
return [null, null];
}
switch ($type) {
@ -302,8 +306,8 @@ class StudentPublicationLink extends AbstractLink
public function get_link()
{
$session_id = api_get_session_id();
$url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $session_id).'&id='.$this->exercise_data['id'].'&gradebook=view';
$sessionId = $this->get_session_id();
$url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&id='.$this->exercise_data['id'].'&gradebook=view';
return $url;
}
@ -329,7 +333,7 @@ class StudentPublicationLink extends AbstractLink
$sql = 'SELECT count(id) FROM '.$this->get_studpub_table().'
WHERE
c_id = "'.$this->course_id.'" AND
id = '.$id.'';
id = '.$id;
$result = Database::query($sql);
$number = Database::fetch_row($result);

@ -90,141 +90,6 @@ a:active {text-decoration: none; font-weight : bold; color : black;}
return $printdata;
}
/**
* This function get a content html for export inside a pdf file.
*
* @param array table headers
* @param array table body
* @param array pdf headers
* @param array pdf footers
*/
function export_pdf_attendance($headers_table, $data_table, $headers_pdf, $footers_pdf, $title_pdf)
{
$mpdf = new mPDF('UTF-8', 'A4-L', '', '', 15, 10, 35, 20, 4, 2, 'L');
$mpdf->useOnlyCoreFonts = true;
$mpdf->mirrorMargins = 0;
// Use different Odd/Even headers and footers and mirror margins
if (is_array($headers_pdf)) {
// preparing headers pdf
$header = '
<table width="100%" cellspacing="1" cellpadding="1" border="0" class="strong">
<tr>
<td ROWSPAN="3" style="text-align: left;" class="title">
<img src="'.api_get_path(WEB_CSS_PATH).api_get_setting('stylesheets').'/images/header-logo.png">
</td>
<td colspan="3">
<h1>'.$title_pdf.'</h1>
</td>
<tr>
<td></td>
<td><strong>'.$headers_pdf[0][0].'</strong> </td><td> <strong>'.$headers_pdf[0][1].'</strong></td>
<td><strong>'.$headers_pdf[1][0].'</strong> </td><td> <strong>'.$headers_pdf[1][1].'</strong></td>
</tr>
<tr>
<td></td>
<td><strong>'.$headers_pdf[2][0].'</strong> </td><td> <strong>'.$headers_pdf[2][1].'</strong></td>
<td><strong>'.$headers_pdf[3][0].' </strong></td><td> <strong>'.$headers_pdf[3][1].'</strong></td>
</tr>
<tr>
<td></td><td></td>
<td><strong>'.$headers_pdf[4][0].'</strong></td><td> <strong>'.$headers_pdf[4][1].'</strong></td>
<td><strong>'.$headers_pdf[5][0].'</strong> </td><td> <strong>'.$headers_pdf[5][1].'</strong></td>
</tr>
</table>';
}
// preparing footer pdf
$footer = '<table width="100%" cellspacing="2" cellpadding="10" border="0">';
if (is_array($footers_pdf)) {
$footer .= '<tr>';
foreach ($footers_pdf as $foot_pdf) {
$footer .= '<td width="33%" style="text-align: center;">'.$foot_pdf.'</td>';
}
$footer .= '</tr>';
}
$footer .= '</table>';
$footer .= '<div align="right" style="font-weight: bold;">{PAGENO}/{nb}</div>';
// preparing content pdf
$css_file = api_get_path(SYS_CSS_PATH).'themes/'.api_get_setting('stylesheets').'/print.css';
if (file_exists($css_file)) {
$css = @file_get_contents($css_file);
} else {
$css = '';
}
if (count($data_table) > 30) {
$items_per_page = (count($data_table) / 2);
} else {
$items_per_page = count($data_table);
}
$count_pages = ceil(count($data_table) / $items_per_page);
$content_table = '';
for ($x = 0; $x < $count_pages; $x++) {
$content_table .= '<table width="100%" border="1" style="border-collapse:collapse">';
// header table
$content_table .= '<tr>';
$i = 0;
if (is_array($headers_table)) {
foreach ($headers_table as $head_table) {
if (!empty($head_table[0])) {
$width = (!empty($head_table[1]) ? $head_table[1].'%' : '');
$content_table .= '<th width="'.$width.'">'.$head_table[0].'</th>';
$i++;
}
}
}
$content_table .= '</tr>';
// body table
if (is_array($data_table) && count($data_table) > 0) {
$offset = $x * $items_per_page;
$data_table = array_slice($data_table, $offset, count($data_table));
$i = 1;
$item = $offset + 1;
foreach ($data_table as $data) {
$content_table .= '<tr>';
$content_table .= '<td>'.($item < 10 ? '0'.$item : $item).'</td>';
foreach ($data as $key => $content) {
if (isset($content)) {
$key == 1 ? $align = 'align="left"' : $align = 'align="center"';
$content_table .= '<td '.$align.' style="padding:4px;" >'.$content.'</td>';
}
}
$content_table .= '</tr>';
$i++;
$item++;
if ($i > $items_per_page) {
break;
}
}
} else {
$content_table .= '<tr colspan="'.$i.'"><td>'.get_lang('Empty').'</td></tr>';
}
$content_table .= '</table>';
if ($x < ($count_pages - 1)) {
$content_table .= '<pagebreak />';
}
}
$html = $content_table;
// set attributes for pdf
$mpdf->SetHTMLHeader($header);
$mpdf->SetHTMLFooter($footer);
if (!empty($css)) {
$mpdf->WriteHTML($css, 1);
$mpdf->WriteHTML($html, 2);
} else {
$mpdf->WriteHTML($html);
}
$mpdf->Output(api_replace_dangerous_char($title_pdf.'.pdf'), 'D');
exit;
}
/**
* This function get a content html for export inside a pdf file.
*

@ -483,7 +483,6 @@ class GradebookTable extends SortableTable
}
// Students get the results and certificates columns
$value_data = isset($data[4]) ? $data[4] : null;
$best = isset($data['best']) ? $data['best'] : null;
$average = isset($data['average']) ? $data['average'] : null;
@ -497,15 +496,17 @@ class GradebookTable extends SortableTable
$totalUserResult[0] += $totalResult[0] / ($totalResult[1] ?: 1) * $data[3];
$totalUserResult[1] += $data[3];
$totalBest = [
$scoredisplay->format_score($totalBest[0] + $data['best_score'][0]),
$scoredisplay->format_score($totalBest[1] + $data['best_score'][1]),
];
$totalAverage = [
$data['average_score'][0],
$data['average_score'][1],
];
if (empty($model)) {
$totalBest = [
$scoredisplay->format_score($totalBest[0] + $data['best_score'][0]),
$scoredisplay->format_score($totalBest[1] + $data['best_score'][1]),
];
$totalAverage = [
$data['average_score'][0],
$data['average_score'][1],
];
}
// Student result
if (empty($model)) {

@ -460,8 +460,6 @@ class FlatViewDataGenerator
if (api_get_setting('gradebook_detailed_admin_view') === 'true') {
$links = $sub_cat->get_links();
$evaluations = $sub_cat->get_evaluations();
/** @var ExerciseLink $link */
$linkScoreList = [];
foreach ($links as $link) {
@ -472,7 +470,9 @@ class FlatViewDataGenerator
);
}
$evaluations = $sub_cat->get_evaluations();
$evalScoreList = [];
/** @var Evaluation $evaluation */
foreach ($evaluations as $evaluation) {
$evalScore = $evaluation->calc_score($user_id);
$evalScoreList[] = $scoreDisplay->display_score(

@ -1501,8 +1501,6 @@ class Template
$this->assign('footer_extra_content', $extra_footer);
}
}
// Tutor name
}
/**

Loading…
Cancel
Save