Add the type of question Unique Answer Image - refs #7613

1.10.x
Angel Fernando Quiroz Campos 11 years ago
parent 5322ec517d
commit beffaccfe3
  1. 38
      main/css/base.css
  2. 360
      main/exercice/UniqueAnswerImage.php
  3. 7
      main/exercice/exercise.class.php
  4. 1
      main/exercice/exercise_submit.php
  5. 3
      main/exercice/question.class.php
  6. 1
      main/inc/lib/api.lib.php
  7. 24
      main/inc/lib/exercise.lib.php

@ -5820,3 +5820,41 @@ ul.holder li.bit-box{
border-radius: 50%;
border: 5px solid rgba(0,0,30,0.8);
}
.question_options .exercise-unique-answer-image {
}
@media (min-width: 768px) {
.question_options .exercise-unique-answer-image:nth-child(2n-1) {
clear: both;
}
}
@media (min-width: 992px) {
.question_options .exercise-unique-answer-image:nth-child(2n-1) {
clear: none;
}
.question_options .exercise-unique-answer-image:nth-child(3n-2) {
clear: both;
}
}
.question_options label > input + div.thumbnail {
border-color: transparent;
border-width: 5px;
}
.question_options label > input:checked + div.thumbnail {
border: 5px solid red;
}
.question_options div.thumbnail p {
margin: 0;
}
.question_options div.thumbnail img {
height: auto !important;
max-width: 100%;
}

@ -0,0 +1,360 @@
<?php
/* For licensing terms, see /license.txt */
/**
* UniqueAnswerImage
*
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
*/
class UniqueAnswerImage extends UniqueAnswer
{
static $typePicture = 'mcua.png';
static $explanationLangVar = 'UniqueSelect';
public function __construct()
{
//this is highly important
parent::__construct();
$this->type = UNIQUE_ANSWER_IMAGE;
$this->isContent = $this->getIsContent();
}
public function createAnswersForm($form)
{
$objExercise = $_SESSION['objExercise'];
$editorConfig = array(
'ToolbarSet' => 'UniqueAnswerImage',
'Width' => '100%',
'Height' => '125'
);
//this line defines how many questions by default appear when creating a choice question
// The previous default value was 2. See task #1759.
$numberAnswers = isset($_POST['nb_answers']) ? (int) $_POST['nb_answers'] : 4;
$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>';
}
$html = '<table class="table table-striped table-hover">
<thead>
<tr style="text-align: center;">
<th width="10">' . get_lang('Number') . '</th>
<th>' . get_lang('True') . '</th>
<th>' . get_lang('Answer') . '</th>
' . $commentTitle . '
' . $feedbackTitle . '
<th width="10">' . get_lang('Weighting') . '</th>
</tr>
</thead>
<tbody>';
$form->addHeader(get_lang('Answers'));
$form->addHtml($html);
$defaults = array();
$correct = 0;
if (!empty($this->id)) {
$answer = new Answer($this->id);
$answer->read();
if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
$numberAnswers = $answer->nbrAnswers;
}
}
$form->addElement('hidden', 'nb_answers');
//Feedback SELECT
$questionList = $objExercise->selectQuestionList();
$selectQuestion = array();
$selectQuestion[0] = get_lang('SelectTargetQuestion');
if (is_array($questionList)) {
foreach ($questionList as $key => $questionid) {
//To avoid warning messages
if (!is_numeric($questionid)) {
continue;
}
$question = Question::read($questionid);
$selectQuestion[$questionid] = 'Q' . $key . ' :' . cut(
$question->selectTitle(), 20
);
}
}
$selectQuestion[-1] = get_lang('ExitTest');
$list = new LearnpathList(api_get_user_id());
$flatList = $list->get_flat_list();
$selectLpId = array();
$selectLpId[0] = get_lang('SelectTargetLP');
foreach ($flatList as $id => $details) {
$selectLpId[$id] = cut($details['lp_name'], 20);
}
$tempScenario = array();
if ($numberAnswers < 1) {
$numberAnswers = 1;
Display::display_normal_message(
get_lang('YouHaveToCreateAtLeastOneAnswer')
);
}
for ($i = 1; $i <= $numberAnswers; ++$i) {
$form->addHtml('<tr>');
if (isset($answer) && is_object($answer)) {
if ($answer->correct[$i]) {
$correct = $i;
}
$defaults['answer[' . $i . ']'] = $answer->answer[$i];
$defaults['comment[' . $i . ']'] = $answer->comment[$i];
$defaults['weighting[' . $i . ']'] = float_format(
$answer->weighting[$i], 1
);
$itemList = explode('@@', $answer->destination[$i]);
$try = $itemList[0];
$lp = $itemList[1];
$listDestination = $itemList[2];
$url = $itemList[3];
$try = 0;
if ($try != 0) {
$tryResult = 1;
}
$urlResult = '';
if ($url != 0) {
$urlResult = $url;
}
$tempScenario['url' . $i] = $urlResult;
$tempScenario['try' . $i] = $tryResult;
$tempScenario['lp' . $i] = $lp;
$tempScenario['destination' . $i] = $listDestination;
} else {
$defaults['answer[1]'] = get_lang('DefaultUniqueAnswer1');
$defaults['weighting[1]'] = 10;
$defaults['answer[2]'] = get_lang('DefaultUniqueAnswer2');
$defaults['weighting[2]'] = 0;
$tempScenario['destination' . $i] = array('0');
$tempScenario['lp' . $i] = array('0');
}
$defaults['scenario'] = $tempScenario;
$renderer = $form->defaultRenderer();
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
'correct'
);
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
'counter[' . $i . ']'
);
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
'answer[' . $i . ']'
);
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
'comment[' . $i . ']'
);
$renderer->setElementTemplate(
'<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
'weighting[' . $i . ']'
);
$answerNumber = $form->addElement('text', 'counter[' . $i . ']', null, ' value = "' . $i . '"');
$answerNumber->freeze();
$form->addElement('radio', 'correct', null, null, $i, 'class="checkbox"');
$form->addHtmlEditor('answer[' . $i . ']', null, null, true, $editorConfig);
$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 = array();
$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') . ': ',
array(
'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);
}
$form->addText('weighting[' . $i . ']', null, null, array('class' => "col-md-1", 'value' => '0'));
$form->addHtml('</tr>');
}
$form->addHtml('</tbody>');
$form->addHtml('</table>');
global $text, $class;
$buttonGroup = [];
if ($objExercise->edit_exercise_in_lp == true) {
//setting the save button here and not in the question class.php
$buttonGroup[] = $form->addButtonDelete(get_lang('LessAnswer'), 'lessAnswers', true);
$buttonGroup[] = $form->addButtonCreate(get_lang('PlusAnswer'), 'moreAnswers', true);
$buttonGroup[] = $form->addButtonSave($text, 'submitQuestion', true);
$form->addGroup($buttonGroup);
}
// We check the first radio button to be sure a radio button will be check
if ($correct == 0) {
$correct = 1;
}
$defaults['correct'] = $correct;
if (!empty($this->id)) {
$form->setDefaults($defaults);
} else {
if ($this->isContent == 1) {
// Default sample content.
$form->setDefaults($defaults);
} else {
$form->setDefaults(array('correct' => 1));
}
}
$form->setConstants(array('nb_answers' => $numberAnswers));
}
public function processAnswersCreation($form)
{
$questionWeighting = $nbrGoodAnswers = 0;
$correct = $form->getSubmitValue('correct');
$objAnswer = new Answer($this->id);
$numberAnswers = $form->getSubmitValue('nb_answers');
for ($i = 1; $i <= $numberAnswers; $i++) {
$answer = trim($form->getSubmitValue('answer[' . $i . ']'));
$comment = trim($form->getSubmitValue('comment[' . $i . ']'));
$weighting = trim($form->getSubmitValue('weighting[' . $i . ']'));
$scenario = $form->getSubmitValue('scenario');
//$listDestination = $form -> getSubmitValue('destination'.$i);
//$destinationStr = $form -> getSubmitValue('destination'.$i);
$try = $scenario['try' . $i];
$lp = $scenario['lp' . $i];
$destination = $scenario['destination' . $i];
$url = trim($scenario['url' . $i]);
/*
How we are going to parse the destination value
here we parse the destination value which is a string
1@@3@@2;4;4;@@http://www.chamilo.org
where: try_again@@lp_id@@selected_questions@@url
try_again = is 1 || 0
lp_id = id of a learning path (0 if dont select)
selected_questions= ids of questions
url= an url
$destinationStr='';
foreach ($listDestination as $destination_id)
{
$destinationStr.=$destination_id.';';
} */
$goodAnswer = ($correct == $i) ? true : false;
if ($goodAnswer) {
$nbrGoodAnswers++;
$weighting = abs($weighting);
if ($weighting > 0) {
$questionWeighting += $weighting;
}
}
if (empty($try)) {
$try = 0;
}
if (empty($lp)) {
$lp = 0;
}
if (empty($destination)) {
$destination = 0;
}
if ($url == '') {
$url = 0;
}
//1@@1;2;@@2;4;4;@@http://www.chamilo.org
$dest = $try . '@@' . $lp . '@@' . $destination . '@@' . $url;
$objAnswer->createAnswer($answer, $goodAnswer, $comment, $weighting, $i, null, null, $dest);
}
// saves the answers into the data base
$objAnswer->save();
// sets the total weighting of the question
$this->updateWeighting($questionWeighting);
$this->save();
}
public function return_header($feedback_type = null, $counter = null, $score = null)
{
return parent::return_header($feedback_type, $counter, $score);
}
}

@ -2277,6 +2277,7 @@ class Exercise
switch ($answerType) {
// for unique answer
case UNIQUE_ANSWER:
case UNIQUE_ANSWER_IMAGE:
case UNIQUE_ANSWER_NO_OPTION:
if ($from_database) {
$sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT
@ -2937,7 +2938,7 @@ class Exercise
if ($debug) error_log('Showing questions $from '.$from);
//display answers (if not matching type, or if the answer is correct)
if ($answerType != MATCHING || $answerCorrect) {
if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, GLOBAL_MULTIPLE_ANSWER))) {
if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, GLOBAL_MULTIPLE_ANSWER))) {
//if ($origin != 'learnpath') {
ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, 0, 0, $results_disabled);
//}
@ -3132,6 +3133,7 @@ class Exercise
switch ($answerType) {
case UNIQUE_ANSWER :
case UNIQUE_ANSWER_IMAGE:
case UNIQUE_ANSWER_NO_OPTION:
case MULTIPLE_ANSWER :
case GLOBAL_MULTIPLE_ANSWER :
@ -3604,8 +3606,7 @@ class Exercise
} elseif ($answerType == ORAL_EXPRESSION) {
$answer = $choice;
Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id, $nano);
} elseif ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) {
} elseif (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION])) {
$answer = $choice;
Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
// } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {

@ -1128,6 +1128,7 @@ if (!empty($error)) {
echo Display::div($exercise_actions, array('class'=>'exercise_actions'));
}
echo '</form>';
echo '</div>';
}
if ($origin != 'learnpath') {

@ -45,7 +45,8 @@ abstract class Question
MULTIPLE_ANSWER_TRUE_FALSE => array('multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'),
MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE => array('multiple_answer_combination_true_false.class.php', 'MultipleAnswerCombinationTrueFalse'),
GLOBAL_MULTIPLE_ANSWER => array('global_multiple_answer.class.php' , 'GlobalMultipleAnswer'),
CALCULATED_ANSWER => array('calculated_answer.class.php' , 'CalculatedAnswer')
CALCULATED_ANSWER => array('calculated_answer.class.php' , 'CalculatedAnswer'),
UNIQUE_ANSWER_IMAGE => ['UniqueAnswerImage.php', 'UniqueAnswerImage']
//MEDIA_QUESTION => array('media_question.class.php' , 'MediaQuestion')
);

@ -472,6 +472,7 @@ define('ORAL_EXPRESSION', 13);
define('GLOBAL_MULTIPLE_ANSWER', 14);
define('MEDIA_QUESTION', 15);
define('CALCULATED_ANSWER', 16);
define('UNIQUE_ANSWER_IMAGE', 17);
//Some alias used in the QTI exports
define('MCUA', 1);

@ -82,7 +82,8 @@ class ExerciseLib
return '';
}
echo '<div class="question_options">';
echo '<div class="question_options row">';
// construction of the Answer object (also gets all answers details)
$objAnswerTmp = new Answer($questionId);
@ -263,7 +264,7 @@ class ExerciseLib
$attributes = array();
// Unique answer
if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) {
if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) {
$input_id = 'choice-' . $questionId . '-' . $answerId;
if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
$attributes = array(
@ -282,6 +283,11 @@ class ExerciseLib
}
}
if ($answerType == UNIQUE_ANSWER_IMAGE) {
$s .= '<div id="answer' . $questionId . $numAnswer . '" '
. 'class="exercise-unique-answer-image col-sm-6 col-md-4" style="text-align: center">';
}
$answer = Security::remove_XSS($answer, STUDENT);
$s .= Display::input(
'hidden',
@ -289,7 +295,15 @@ class ExerciseLib
'0'
);
$answer_input = '<label class="radio">';
$answer_input = null;
if ($answerType == UNIQUE_ANSWER_IMAGE) {
$attributes['style'] = 'display: none;';
$answer = '<div class="thumbnail">' . $answer . '</div>';
}
$answer_input .= '<label class="radio">';
$answer_input .= Display::input(
'radio',
'choice[' . $questionId . ']',
@ -299,6 +313,10 @@ class ExerciseLib
$answer_input .= $answer;
$answer_input .= '</label>';
if ($answerType == UNIQUE_ANSWER_IMAGE) {
$answer_input .= "</div>";
}
if ($show_comment) {
$s .= '<tr><td>';
$s .= $answer_input;

Loading…
Cancel
Save