id = 0;
$this->exercise = '';
$this->description = '';
$this->sound = '';
$this->type = ALL_ON_ONE_PAGE;
$this->random = 0;
$this->random_answers = 0;
$this->active = 1;
$this->questionList = array();
$this->timeLimit = 0;
$this->end_time = '0000-00-00 00:00:00';
$this->start_time = '0000-00-00 00:00:00';
$this->results_disabled = 1;
$this->expired_time = '0000-00-00 00:00:00';
$this->propagate_neg = 0;
$this->review_answers = false;
$this->randomByCat = 0; //
$this->text_when_finished = ""; //
$this->display_category_name = 0;
$this->pass_percentage = null;
if (!empty($course_id)) {
$course_info = api_get_course_info_by_id($course_id);
} else {
$course_info = api_get_course_info();
}
$this->course_id = $course_info['real_id'];
$this->course = $course_info;
$this->sessionId = api_get_session_id();
}
/**
* Reads exercise information from the data base
*
* @author Olivier Brouckaert
* @param integer $id - exercise Id
*
* @return boolean - true if exercise exists, otherwise false
*/
public function read($id)
{
global $_configuration;
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$table_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$id = intval($id);
if (empty($this->course_id)) {
return false;
}
$sql = "SELECT * FROM $TBL_EXERCISES WHERE c_id = ".$this->course_id." AND id = ".$id;
$result = Database::query($sql);
// if the exercise has been found
if ($object = Database::fetch_object($result)) {
$this->id = $id;
$this->exercise = $object->title;
$this->name = $object->title;
$this->title = $object->title;
$this->description = $object->description;
$this->sound = $object->sound;
$this->type = $object->type;
if (empty($this->type)) {
$this->type = ONE_PER_PAGE;
}
$this->random = $object->random;
$this->random_answers = $object->random_answers;
$this->active = $object->active;
$this->results_disabled = $object->results_disabled;
$this->attempts = $object->max_attempt;
$this->feedback_type = $object->feedback_type;
$this->propagate_neg = $object->propagate_neg;
$this->randomByCat = $object->random_by_category;
$this->text_when_finished = $object->text_when_finished;
$this->display_category_name = $object->display_category_name;
$this->pass_percentage = $object->pass_percentage;
$this->sessionId = $object->session_id;
$this->is_gradebook_locked = api_resource_is_locked_by_gradebook($id, LINK_EXERCISE);
$this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false;
$sql = "SELECT lp_id, max_score
FROM $table_lp_item
WHERE c_id = {$this->course_id} AND
item_type = '".TOOL_QUIZ."' AND
path = '".$id."'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
$this->exercise_was_added_in_lp = true;
$this->lpList = Database::store_result($result, 'ASSOC');
}
$this->force_edit_exercise_in_lp = isset($_configuration['force_edit_exercise_in_lp']) ? $_configuration['force_edit_exercise_in_lp'] : false;
if ($this->exercise_was_added_in_lp) {
$this->edit_exercise_in_lp = $this->force_edit_exercise_in_lp == true;
} else {
$this->edit_exercise_in_lp = true;
}
if ($object->end_time != '0000-00-00 00:00:00') {
$this->end_time = $object->end_time;
}
if ($object->start_time != '0000-00-00 00:00:00') {
$this->start_time = $object->start_time;
}
//control time
$this->expired_time = $object->expired_time;
//Checking if question_order is correctly set
$this->questionList = $this->selectQuestionList(true);
//overload questions list with recorded questions list
//load questions only for exercises of type 'one question per page'
//this is needed only is there is no questions
/*
// @todo not sure were in the code this is used somebody mess with the exercise tool
// @todo don't know who add that config and why $_configuration['live_exercise_tracking']
global $_configuration, $questionList;
if ($this->type == ONE_PER_PAGE && $_SERVER['REQUEST_METHOD'] != 'POST' && defined('QUESTION_LIST_ALREADY_LOGGED') &&
isset($_configuration['live_exercise_tracking']) && $_configuration['live_exercise_tracking']) {
$this->questionList = $questionList;
}*/
return true;
}
return false;
}
/**
* @return string
*/
public function getCutTitle()
{
return cut($this->exercise, EXERCISE_MAX_NAME_SIZE);
}
/**
* returns the exercise ID
*
* @author Olivier Brouckaert
* @return int - exercise ID
*/
public function selectId()
{
return $this->id;
}
/**
* returns the exercise title
*
* @author Olivier Brouckaert
* @return string - exercise title
*/
public function selectTitle()
{
return $this->exercise;
}
/**
* returns the number of attempts setted
*
* @return int - exercise attempts
*/
public function selectAttempts()
{
return $this->attempts;
}
/** returns the number of FeedbackType *
* 0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback
* @return int - exercise attempts
*/
public function selectFeedbackType()
{
return $this->feedback_type;
}
/**
* returns the time limit
*/
public function selectTimeLimit()
{
return $this->timeLimit;
}
/**
* returns the exercise description
*
* @author Olivier Brouckaert
* @return string - exercise description
*/
public function selectDescription()
{
return $this->description;
}
/**
* returns the exercise sound file
*
* @author Olivier Brouckaert
* @return string - exercise description
*/
public function selectSound()
{
return $this->sound;
}
/**
* returns the exercise type
*
* @author Olivier Brouckaert
* @return integer - exercise type
*/
public function selectType()
{
return $this->type;
}
/**
* @author hubert borderiou 30-11-11
* @return integer : do we display the question category name for students
*/
public function selectDisplayCategoryName()
{
return $this->display_category_name;
}
/**
* @return int
*/
public function selectPassPercentage()
{
return $this->pass_percentage;
}
/**
*
* Modify object to update the switch display_category_name
* @author hubert borderiou 30-11-11
* @param int $in_txt is an integer 0 or 1
*/
public function updateDisplayCategoryName($in_txt)
{
$this->display_category_name = $in_txt;
}
/**
* @author hubert borderiou 28-11-11
* @return string html text : the text to display ay the end of the test.
*/
public function selectTextWhenFinished()
{
return $this->text_when_finished;
}
/**
* @author hubert borderiou 28-11-11
* @return string html text : update the text to display ay the end of the test.
*/
public function updateTextWhenFinished($in_txt)
{
$this->text_when_finished = $in_txt;
}
/**
* return 1 or 2 if randomByCat
* @author hubert borderiou
* @return integer - quiz random by category
*/
public function selectRandomByCat()
{
return $this->randomByCat;
}
/**
* return 0 if no random by cat
* return 1 if random by cat, categories shuffled
* return 2 if random by cat, categories sorted by alphabetic order
* @author hubert borderiou
* @return integer - quiz random by category
*/
public function isRandomByCat()
{
$res = 0;
if ($this->randomByCat == 1) {
$res = 1;
} else if ($this->randomByCat == 2) {
$res = 2;
}
return $res;
}
/**
* return nothing
* update randomByCat value for object
* @author hubert borderiou
*/
public function updateRandomByCat($in_randombycat)
{
if ($in_randombycat == 1) {
$this->randomByCat = 1;
} else if ($in_randombycat == 2) {
$this->randomByCat = 2;
} else {
$this->randomByCat = 0;
}
}
/**
* Tells if questions are selected randomly, and if so returns the draws
*
* @author Carlos Vargas
* @return integer - results disabled exercise
*/
public function selectResultsDisabled()
{
return $this->results_disabled;
}
/**
* tells if questions are selected randomly, and if so returns the draws
*
* @author Olivier Brouckaert
* @return integer - 0 if not random, otherwise the draws
*/
public function isRandom()
{
if($this->random > 0 || $this->random == -1) {
return true;
} else {
return false;
}
}
/**
* returns random answers status.
*
* @author Juan Carlos Rana
*/
public function selectRandomAnswers()
{
return $this->random_answers;
}
/**
* Same as isRandom() but has a name applied to values different than 0 or 1
*/
public function getShuffle()
{
return $this->random;
}
/**
* returns the exercise status (1 = enabled ; 0 = disabled)
*
* @author Olivier Brouckaert
* @return boolean - true if enabled, otherwise false
*/
public function selectStatus()
{
return $this->active;
}
/**
* returns the array with the question ID list
*
* @author Olivier Brouckaert
* @return array - question ID list
*/
public function selectQuestionList($from_db = false)
{
if ($from_db && !empty($this->id)) {
$TBL_EXERCISE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$sql = "SELECT DISTINCT e.question_order
FROM $TBL_EXERCISE_QUESTION e
INNER JOIN $TBL_QUESTIONS q
ON (e.question_id = q.id AND e.c_id = ".$this->course_id." AND q.c_id = ".$this->course_id.")
WHERE e.exercice_id = ".intval($this->id)."";
$result = Database::query($sql);
$count_question_orders = Database::num_rows($result);
$sql = "SELECT e.question_id, e.question_order
FROM $TBL_EXERCISE_QUESTION e
INNER JOIN $TBL_QUESTIONS q
ON (e.question_id= q.id AND e.c_id = ".$this->course_id." AND q.c_id = ".$this->course_id.")
WHERE e.exercice_id = ".intval($this->id)."
ORDER BY question_order";
$result = Database::query($sql);
// fills the array with the question ID for this exercise
// the key of the array is the question position
$temp_question_list = array();
$counter = 1;
$question_list = array();
while ($new_object = Database::fetch_object($result)) {
$question_list[$new_object->question_order]= $new_object->question_id;
$temp_question_list[$counter] = $new_object->question_id;
$counter++;
}
if (!empty($temp_question_list)) {
if (count($temp_question_list) != $count_question_orders) {
$question_list = $temp_question_list;
}
}
return $question_list;
}
return $this->questionList;
}
/**
* returns the number of questions in this exercise
*
* @author Olivier Brouckaert
* @return integer - number of questions
*/
public function selectNbrQuestions()
{
return sizeof($this->questionList);
}
/**
* @return int
*/
public function selectPropagateNeg()
{
return $this->propagate_neg;
}
/**
* Selects questions randomly in the question list
*
* @author Olivier Brouckaert
* @author Hubert Borderiou 15 nov 2011
* @return array - if the exercise is not set to take questions randomly, returns the question list
* without randomizing, otherwise, returns the list with questions selected randomly
*/
public function selectRandomList()
{
$nbQuestions = $this->selectNbrQuestions();
$temp_list = $this->questionList;
//Not a random exercise, or if there are not at least 2 questions
if($this->random == 0 || $nbQuestions < 2) {
return $this->questionList;
}
if ($nbQuestions != 0) {
shuffle($temp_list);
$my_random_list = array_combine(range(1,$nbQuestions),$temp_list);
$my_question_list = array();
// $this->random == -1 if random with all questions
if ($this->random > 0) {
$i = 0;
foreach ($my_random_list as $item) {
if ($i < $this->random) {
$my_question_list[$i] = $item;
} else {
break;
}
$i++;
}
} else {
$my_question_list = $my_random_list;
}
return $my_question_list;
}
}
/**
* returns 'true' if the question ID is in the question list
*
* @author Olivier Brouckaert
* @param integer $questionId - question ID
* @return boolean - true if in the list, otherwise false
*/
public function isInList($questionId)
{
if (is_array($this->questionList))
return in_array($questionId,$this->questionList);
else
return false;
}
/**
* changes the exercise title
*
* @author Olivier Brouckaert
* @param string $title - exercise title
*/
public function updateTitle($title)
{
$this->exercise=$title;
}
/**
* changes the exercise max attempts
*
* @param int $attempts - exercise max attempts
*/
public function updateAttempts($attempts)
{
$this->attempts=$attempts;
}
/**
* changes the exercise feedback type
*
* @param int $feedback_type
*/
public function updateFeedbackType($feedback_type)
{
$this->feedback_type=$feedback_type;
}
/**
* changes the exercise description
*
* @author Olivier Brouckaert
* @param string $description - exercise description
*/
public function updateDescription($description)
{
$this->description=$description;
}
/**
* changes the exercise expired_time
*
* @author Isaac flores
* @param int $expired_time The expired time of the quiz
*/
public function updateExpiredTime($expired_time)
{
$this->expired_time = $expired_time;
}
/**
* @param $value
*/
public function updatePropagateNegative($value)
{
$this->propagate_neg = $value;
}
/**
* @param $value
*/
public function updateReviewAnswers($value)
{
$this->review_answers = isset($value) && $value ? true : false;
}
/**
* @param $value
*/
public function updatePassPercentage($value)
{
$this->pass_percentage = $value;
}
/**
* changes the exercise sound file
*
* @author Olivier Brouckaert
* @param string $sound - exercise sound file
* @param string $delete - ask to delete the file
*/
public function updateSound($sound,$delete)
{
global $audioPath, $documentPath;
$TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
if ($sound['size'] && (strstr($sound['type'],'audio') || strstr($sound['type'],'video'))) {
$this->sound=$sound['name'];
if (@move_uploaded_file($sound['tmp_name'],$audioPath.'/'.$this->sound)) {
$query = "SELECT 1 FROM $TBL_DOCUMENT
WHERE c_id = ".$this->course_id." AND path='".str_replace($documentPath,'',$audioPath).'/'.$this->sound."'";
$result=Database::query($query);
if (!Database::num_rows($result)) {
$id = add_document(
$this->course,
str_replace($documentPath,'',$audioPath).'/'.$this->sound,
'file',
$sound['size'],
$sound['name']
);
api_item_property_update(
$this->course,
TOOL_DOCUMENT,
$id,
'DocumentAdded',
api_get_user_id()
);
item_property_update_on_folder(
$this->course,
str_replace($documentPath, '', $audioPath),
api_get_user_id()
);
}
}
} elseif($delete && is_file($audioPath.'/'.$this->sound)) {
$this->sound='';
}
}
/**
* changes the exercise type
*
* @author Olivier Brouckaert
* @param integer $type - exercise type
*/
public function updateType($type)
{
$this->type=$type;
}
/**
* sets to 0 if questions are not selected randomly
* if questions are selected randomly, sets the draws
*
* @author Olivier Brouckaert
* @param integer $random - 0 if not random, otherwise the draws
*/
public function setRandom($random)
{
/*if ($random == 'all') {
$random = $this->selectNbrQuestions();
}*/
$this->random = $random;
}
/**
* sets to 0 if answers are not selected randomly
* if answers are selected randomly
* @author Juan Carlos Rana
* @param integer $random_answers - random answers
*/
public function updateRandomAnswers($random_answers)
{
$this->random_answers = $random_answers;
}
/**
* enables the exercise
*
* @author Olivier Brouckaert
*/
public function enable()
{
$this->active=1;
}
/**
* disables the exercise
*
* @author Olivier Brouckaert
*/
public function disable()
{
$this->active=0;
}
/**
* Set disable results
*/
public function disable_results()
{
$this->results_disabled = true;
}
/**
* Enable results
*/
public function enable_results()
{
$this->results_disabled = false;
}
/**
* @param int $results_disabled
*/
public function updateResultsDisabled($results_disabled)
{
$this->results_disabled = intval($results_disabled);
}
/**
* updates the exercise in the data base
*
* @author Olivier Brouckaert
*/
public function save($type_e = '')
{
$_course = $this->course;
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$id = $this->id;
$exercise = $this->exercise;
$description = $this->description;
$sound = $this->sound;
$type = $this->type;
$attempts = isset($this->attempts) ? $this->attempts : 0;
$feedback_type = isset($this->feedback_type) ? $this->feedback_type : 0;
$random = $this->random;
$random_answers = $this->random_answers;
$active = $this->active;
$propagate_neg = $this->propagate_neg;
$review_answers = isset($this->review_answers) && $this->review_answers ? 1 : 0;
$randomByCat = $this->randomByCat;
$text_when_finished = $this->text_when_finished;
$display_category_name = intval($this->display_category_name);
$pass_percentage = intval($this->pass_percentage);
$session_id = $this->sessionId;
//If direct we do not show results
if ($feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) {
$results_disabled = 0;
} else {
$results_disabled = intval($this->results_disabled);
}
$expired_time = intval($this->expired_time);
// Exercise already exists
if ($id) {
// we prepare date in the database using the api_get_utc_datetime() function
if (!empty($this->start_time) && $this->start_time != '0000-00-00 00:00:00') {
$start_time = Database::escape_string($this->start_time);
} else {
$start_time = '0000-00-00 00:00:00';
}
if (!empty($this->end_time) && $this->end_time != '0000-00-00 00:00:00') {
$end_time = Database::escape_string($this->end_time);
} else {
$end_time = '0000-00-00 00:00:00';
}
$params = [
'title' => $exercise,
'description' => $description,
];
$paramsExtra = [];
if ($type_e != 'simple') {
$paramsExtra = [
'sound' => $sound,
'type' => $type,
'random' => $random,
'random_answers' => $random_answers,
'active' => $active,
'feedback_type' => $feedback_type,
'start_time' => $start_time,
'end_time' => $end_time,
'max_attempt' => $attempts,
'expired_time' => $expired_time,
'propagate_neg' => $propagate_neg,
'review_answers' => $review_answers,
'random_by_category' => $randomByCat,
'text_when_finished' => $text_when_finished,
'display_category_name' => $display_category_name,
'pass_percentage' => $pass_percentage,
'results_disabled' => $results_disabled,
];
}
$params = array_merge($params, $paramsExtra);
Database::update(
$TBL_EXERCISES,
$params,
['c_id = ? AND id = ?' => [$this->course_id, $id]]
);
// update into the item_property table
api_item_property_update(
$_course,
TOOL_QUIZ,
$id,
'QuizUpdated',
api_get_user_id()
);
if (api_get_setting('search_enabled')=='true') {
$this->search_engine_edit();
}
} else {
// Creates a new exercise
// In this case of new exercise, we don't do the api_get_utc_datetime()
// for date because, bellow, we call function api_set_default_visibility()
// In this function, api_set_default_visibility,
// the Quiz is saved too, with an $id and api_get_utc_datetime() is done.
// If we do it now, it will be done twice (cf. https://support.chamilo.org/issues/6586)
if (!empty($this->start_time) && $this->start_time != '0000-00-00 00:00:00') {
$start_time = $this->start_time;
} else {
$start_time = '0000-00-00 00:00:00';
}
if (!empty($this->end_time) && $this->end_time != '0000-00-00 00:00:00') {
$end_time = $this->end_time;
} else {
$end_time = '0000-00-00 00:00:00';
}
$params = [
'c_id' => $this->course_id,
'start_time' => $start_time,
'end_time' => $end_time,
'title' => $exercise,
'description' => $description,
'sound' => $sound,
'type' => $type,
'random' => $random,
'random_answers' => $random_answers,
'active' => $active,
'results_disabled' => $results_disabled,
'max_attempt' => $attempts,
'feedback_type' => $feedback_type,
'expired_time' => $expired_time,
'session_id' => $session_id,
'review_answers' => $review_answers,
'random_by_category' => $randomByCat,
'text_when_finished' => $text_when_finished,
'display_category_name' => $display_category_name,
'pass_percentage' => $pass_percentage
];
$this->id = Database::insert($TBL_EXERCISES, $params);
if ($this->id) {
$sql = "UPDATE $TBL_EXERCISES SET id = iid WHERE iid = {$this->id} ";
Database::query($sql);
// insert into the item_property table
api_item_property_update(
$this->course,
TOOL_QUIZ,
$this->id,
'QuizAdded',
api_get_user_id()
);
// This function save the quiz again, carefull about start_time
// and end_time if you remove this line (see above)
api_set_default_visibility(
$this->id,
TOOL_QUIZ,
null,
$this->course
);
if (api_get_setting('search_enabled') == 'true' && extension_loaded('xapian')) {
$this->search_engine_save();
}
}
}
// Updates the question position
$this->update_question_positions();
}
/**
* Updates question position
*/
public function update_question_positions()
{
$quiz_question_table = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
//Fixes #3483 when updating order
$question_list = $this->selectQuestionList(true);
if (!empty($question_list)) {
foreach ($question_list as $position => $questionId) {
$sql = "UPDATE $quiz_question_table SET
question_order ='".intval($position)."'
WHERE
c_id = ".$this->course_id." AND
question_id = ".intval($questionId)." AND
exercice_id=".intval($this->id);
Database::query($sql);
}
}
}
/**
* Adds a question into the question list
*
* @author Olivier Brouckaert
* @param integer $questionId - question ID
* @return boolean - true if the question has been added, otherwise false
*/
public function addToList($questionId)
{
// checks if the question ID is not in the list
if (!$this->isInList($questionId)) {
// selects the max position
if (!$this->selectNbrQuestions()) {
$pos = 1;
} else {
if (is_array($this->questionList)) {
$pos = max(array_keys($this->questionList)) + 1;
}
}
$this->questionList[$pos] = $questionId;
return true;
}
return false;
}
/**
* removes a question from the question list
*
* @author Olivier Brouckaert
* @param integer $questionId - question ID
* @return boolean - true if the question has been removed, otherwise false
*/
public function removeFromList($questionId)
{
// searches the position of the question ID in the list
$pos = array_search($questionId,$this->questionList);
// question not found
if ($pos === false) {
return false;
} else {
// dont reduce the number of random question if we use random by category option, or if
// random all questions
if ($this->isRandom() && $this->isRandomByCat() == 0) {
if (count($this->questionList) >= $this->random && $this->random > 0) {
$this->random -= 1;
$this->save();
}
}
// deletes the position from the array containing the wanted question ID
unset($this->questionList[$pos]);
return true;
}
}
/**
* deletes the exercise from the database
* Notice : leaves the question in the data base
*
* @author Olivier Brouckaert
*/
public function delete()
{
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$sql = "UPDATE $TBL_EXERCISES SET active='-1'
WHERE c_id = ".$this->course_id." AND id = ".intval($this->id)."";
Database::query($sql);
api_item_property_update($this->course, TOOL_QUIZ, $this->id, 'QuizDeleted', api_get_user_id());
api_item_property_update($this->course, TOOL_QUIZ, $this->id, 'delete', api_get_user_id());
if (api_get_setting('search_enabled')=='true' && extension_loaded('xapian') ) {
$this->search_engine_delete();
}
}
/**
* Creates the form to create / edit an exercise
* @param FormValidator $form
*/
public function createForm($form, $type='full')
{
global $id;
if (empty($type)){
$type='full';
}
// form title
if (!empty($_GET['exerciseId'])) {
$form_title = get_lang('ModifyExercise');
} else {
$form_title = get_lang('NewEx');
}
$form->addElement('header', $form_title);
// Title.
$form->addElement('text', 'exerciseTitle', get_lang('ExerciseName'), array('class' => 'span6','id'=>'exercise_title'));
$form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
$form->addElement('html', '
');
$editor_config = array('ToolbarSet' => 'TestQuestionDescription', 'Width' => '100%', 'Height' => '150');
if (is_array($type)){
$editor_config = array_merge($editor_config, $type);
}
$form->addHtmlEditor('exerciseDescription', get_lang('ExerciseDescription'), false, false, $editor_config);
if ($type == 'full') {
//Can't modify a DirectFeedback question
if ($this->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_DIRECT ) {
// feedback type
$radios_feedback = array();
$radios_feedback[] = $form->createElement('radio', 'exerciseFeedbackType', null, get_lang('ExerciseAtTheEndOfTheTest'),'0',array('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',array('id' =>'exerciseType_1' , 'onclick' => 'check_direct_feedback()'));
}
}
$radios_feedback[] = $form->createElement('radio', 'exerciseFeedbackType', null, get_lang('NoFeedback'),'2',array('id' =>'exerciseType_2'));
$form->addGroup($radios_feedback, null, array(get_lang('FeedbackType'),get_lang('FeedbackDisplayOptions')), '');
// Type of results display on the final page
$radios_results_disabled = array();
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('ShowScoreAndRightAnswer'), '0', array('id'=>'result_disabled_0'));
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('DoNotShowScoreNorRightAnswer'), '1',array('id'=>'result_disabled_1','onclick' => 'check_results_disabled()'));
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('OnlyShowScore'), '2', array('id'=>'result_disabled_2'));
//$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('ExamModeWithFinalScoreShowOnlyFinalScoreWithCategoriesIfAvailable'), '3', array('id'=>'result_disabled_3','onclick' => 'check_results_disabled()'));
$form->addGroup($radios_results_disabled, null, get_lang('ShowResultsToStudents'), '');
// Type of questions disposition on page
$radios = array();
$radios[] = $form->createElement('radio', 'exerciseType', null, get_lang('SimpleExercise'), '1', array('onclick' => 'check_per_page_all()', 'id'=>'option_page_all'));
$radios[] = $form->createElement('radio', 'exerciseType', null, get_lang('SequentialExercise'),'2', array('onclick' => 'check_per_page_one()', 'id'=>'option_page_one'));
$form->addGroup($radios, null, get_lang('QuestionsPerPage'), '');
} else {
// if is Directfeedback but has not questions we can allow to modify the question type
if ($this->selectNbrQuestions() == 0) {
// feedback type
$radios_feedback = array();
$radios_feedback[] = $form->createElement('radio', 'exerciseFeedbackType', null, get_lang('ExerciseAtTheEndOfTheTest'),'0',array('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', array('id' =>'exerciseType_1' , 'onclick' => 'check_direct_feedback()'));
}
$radios_feedback[] = $form->createElement('radio', 'exerciseFeedbackType', null, get_lang('NoFeedback'),'2',array('id' =>'exerciseType_2'));
$form->addGroup($radios_feedback, null, array(get_lang('FeedbackType'),get_lang('FeedbackDisplayOptions')));
//$form->addElement('select', 'exerciseFeedbackType',get_lang('FeedbackType'),$feedback_option,'onchange="javascript:feedbackselection()"');
$radios_results_disabled = array();
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('ShowScoreAndRightAnswer'), '0', array('id'=>'result_disabled_0'));
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('DoNotShowScoreNorRightAnswer'), '1',array('id'=>'result_disabled_1','onclick' => 'check_results_disabled()'));
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('OnlyShowScore'), '2',array('id'=>'result_disabled_2','onclick' => 'check_results_disabled()'));
$form->addGroup($radios_results_disabled, null, get_lang('ShowResultsToStudents'),'');
// Type of questions disposition on page
$radios = array();
$radios[] = $form->createElement('radio', 'exerciseType', null, get_lang('SimpleExercise'), '1');
$radios[] = $form->createElement('radio', 'exerciseType', null, get_lang('SequentialExercise'),'2');
$form->addGroup($radios, null, get_lang('ExerciseType'));
} else {
//Show options freeze
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('ShowScoreAndRightAnswer'), '0', array('id'=>'result_disabled_0'));
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('DoNotShowScoreNorRightAnswer'), '1',array('id'=>'result_disabled_1','onclick' => 'check_results_disabled()'));
$radios_results_disabled[] = $form->createElement('radio', 'results_disabled', null, get_lang('OnlyShowScore'), '2',array('id'=>'result_disabled_2','onclick' => 'check_results_disabled()'));
$result_disable_group = $form->addGroup($radios_results_disabled, null, get_lang('ShowResultsToStudents'),'');
$result_disable_group->freeze();
//we force the options to the DirectFeedback exercisetype
$form->addElement('hidden', 'exerciseFeedbackType', EXERCISE_FEEDBACK_TYPE_DIRECT);
$form->addElement('hidden', 'exerciseType', ONE_PER_PAGE);
// Type of questions disposition on page
$radios[] = $form->createElement('radio', 'exerciseType', null, get_lang('SimpleExercise'), '1', array('onclick' => 'check_per_page_all()', 'id'=>'option_page_all'));
$radios[] = $form->createElement('radio', 'exerciseType', null, get_lang('SequentialExercise'),'2', array('onclick' => 'check_per_page_one()', 'id'=>'option_page_one'));
$type_group = $form->addGroup($radios, null, get_lang('QuestionsPerPage'), '');
$type_group->freeze();
}
}
// number of random question
$max = ($this->id > 0) ? $this->selectNbrQuestions() : 10 ;
$option = range(0,$max);
$option[0] = get_lang('No');
$option[-1] = get_lang('AllQuestionsShort');
$form->addElement('select', 'randomQuestions',array(get_lang('RandomQuestions'), get_lang('RandomQuestionsHelp')), $option, array('id'=>'randomQuestions','class'=>'chzn-select'));
//random answers
$radios_random_answers = array();
$radios_random_answers[] = $form->createElement('radio', 'randomAnswers', null, get_lang('Yes'),'1');
$radios_random_answers[] = $form->createElement('radio', 'randomAnswers', null, get_lang('No'),'0');
$form->addGroup($radios_random_answers, null, get_lang('RandomAnswers'), '');
//randow by category
$form->addElement('html','
';
break;
}
}
}
if ($debug) error_log(' ------ ');
} // end for that loops over all answers of the current question
if ($debug) error_log('-- end answer loop --');
$final_answer = true;
foreach ($real_answers as $my_answer) {
if (!$my_answer) {
$final_answer = false;
}
}
//we add the total score after dealing with the answers
if ($answerType == MULTIPLE_ANSWER_COMBINATION || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE ) {
if ($final_answer) {
//getting only the first score where we save the weight of all the question
$answerWeighting = $objAnswerTmp->selectWeighting(1);
$questionScore += $answerWeighting;
$totalScore += $answerWeighting;
}
}
//Fixes multiple answer question in order to be exact
//if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
/* if ($answerType == GLOBAL_MULTIPLE_ANSWER) {
$diff = @array_diff($answer_correct_array, $real_answers);
// All good answers or nothing works like exact
$counter = 1;
$correct_answer = true;
foreach ($real_answers as $my_answer) {
if ($debug)
error_log(" my_answer: $my_answer answer_correct_array[counter]: ".$answer_correct_array[$counter]);
if ($my_answer != $answer_correct_array[$counter]) {
$correct_answer = false;
break;
}
$counter++;
}
if ($debug) error_log(" answer_correct_array: ".print_r($answer_correct_array, 1)."");
if ($debug) error_log(" real_answers: ".print_r($real_answers, 1)."");
if ($debug) error_log(" correct_answer: ".$correct_answer);
if ($correct_answer == false) {
$questionScore = 0;
}
// This makes the result non exact
if (!empty($diff)) {
$questionScore = 0;
}
}*/
$extra_data = array(
'final_overlap' => $final_overlap,
'final_missing'=>$final_missing,
'final_excess'=> $final_excess,
'overlap_color' => $overlap_color,
'missing_color'=>$missing_color,
'excess_color'=> $excess_color,
'threadhold1' => $threadhold1,
'threadhold2'=>$threadhold2,
'threadhold3'=> $threadhold3,
);
if ($from == 'exercise_result') {
// if answer is hotspot. To the difference of exercise_show.php,
// we use the results from the session (from_db=0)
// TODO Change this, because it is wrong to show the user
// some results that haven't been stored in the database yet
if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER || $answerType == HOT_SPOT_DELINEATION ) {
if ($debug) error_log('$from AND this is a hotspot kind of question ');
$my_exe_id = 0;
$from_database = 0;
if ($answerType == HOT_SPOT_DELINEATION) {
if (0) {
if ($overlap_color) {
$overlap_color='green';
} else {
$overlap_color='red';
}
if ($missing_color) {
$missing_color='green';
} else {
$missing_color='red';
}
if ($excess_color) {
$excess_color='green';
} else {
$excess_color='red';
}
if (!is_numeric($final_overlap)) {
$final_overlap = 0;
}
if (!is_numeric($final_missing)) {
$final_missing = 0;
}
if (!is_numeric($final_excess)) {
$final_excess = 0;
}
if ($final_overlap>100) {
$final_overlap = 100;
}
$table_resume='