Adding question categories see #294 developed by Hubert Borderiou

skala
Julio Montoya 14 years ago
parent 7858249e5c
commit 35b1978eeb
  1. 24
      main/exercice/admin.php
  2. 12
      main/exercice/exercice.php
  3. 140
      main/exercice/exercise.class.php
  4. 26
      main/exercice/exercise.lib.php
  5. 5
      main/exercice/exercise_submit.php
  6. 381
      main/exercice/question.class.php
  7. 176
      main/exercice/question_list_admin.inc.php
  8. 727
      main/exercice/question_pool.php
  9. 421
      main/exercice/testcategory.class.php
  10. 274
      main/exercice/tests_category.php
  11. 29
      main/inc/lib/add_course.lib.inc.php
  12. 3
      main/inc/lib/database.constants.inc.php
  13. 10
      main/inc/lib/fckeditor/toolbars/default/test_category.php
  14. 1
      main/install/migrate-db-1.8.8-1.9.0-pre.sql

@ -42,6 +42,7 @@
*
* @package chamilo.exercise
* @author Olivier Brouckaert
* Modified by Hubert Borderiou 21-10-2011 Question by category
*/
/**
* Code
@ -234,7 +235,6 @@ if ($cancelQuestion) {
} else {
// goes back to the question viewing
$editQuestion=$modifyQuestion;
unset($newQuestion,$modifyQuestion);
}
}
@ -448,6 +448,9 @@ if (isset($exerciseId) && !empty($exerciseId)) {
}
}
// If we are in a test
$inATest = isset($exerciseId) && $exerciseId > 0;
if ($inATest) {
echo '<div class="actions">';
if (isset($_GET['hotspotadmin']) || isset($_GET['newQuestion']) || isset($_GET['myid']))
echo '<a href="admin.php?exerciseId='.$exerciseId.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
@ -473,20 +476,33 @@ foreach ($objExercise->questionList as $q) {
echo '<span style="float:right">'.sprintf(get_lang('XQuestionsWithTotalScoreY'),$objExercise->selectNbrQuestions(),$maxScoreAllQuestions).'</span>';
echo '</div>';
}
else if (isset($_GET['newQuestion'])) {
// we are in create a new question from question pool not in a test
echo '<div class="actions">';
echo '<a href="admin.php?'.api_get_cidreq().'">.'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
echo '</div>';
}
else {
// If we are in question_poolbut not in an test, go back to question create in pool
echo '<div class="actions">';
echo '<a href="question_pool.php">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
echo '</div>';
}
if (isset($_GET['message'])) {
if (in_array($_GET['message'], array('ExerciseStored', 'ItemUpdated', 'ItemAdded'))) {
Display::display_confirmation_message(get_lang($_GET['message']));
}
}
if ($newQuestion || $editQuestion) {
// statement management
$type = Security::remove_XSS($_REQUEST['answerType']);
echo '<input type="hidden" name="Type" value="'.$type.'" />';
require 'question_admin.inc.php';
}
if (isset($_GET['hotspotadmin'])) {
if (!is_object($objQuestion)) {
$objQuestion = Question :: read($_GET['hotspotadmin']);
@ -495,6 +511,7 @@ if (isset($_GET['hotspotadmin'])) {
api_not_allowed();
}
require 'hotspot_admin.inc.php';}
if (!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspotadmin'])) {
// question list management
require 'question_list_admin.inc.php';
@ -503,5 +520,4 @@ if (!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspot
api_session_register('objExercise');
api_session_register('objQuestion');
api_session_register('objAnswer');
Display::display_footer();

@ -7,6 +7,7 @@
* @author Denes Nagy, HotPotatoes integration
* @author Wolfgang Schneider, code/html cleanup
* @author Julio Montoya <gugli100@gmail.com>, lots of cleanup + several improvements
* Modified by hubert.borderiou (question category)
*/
/**
* Code
@ -197,8 +198,7 @@ if ($show == 'result' && $_REQUEST['comments'] == 'update' && ($is_allowedToEdit
Database::query($query);
//Saving results in the track recording table
$recording_changes = 'INSERT INTO '.$TBL_TRACK_ATTEMPT_RECORDING.' (exe_id, question_id, marks, insert_date, author, teacher_comment)
VALUES ('."'$id','".$my_questionid."','$my_marks','".api_get_utc_datetime()."','".api_get_user_id()."'".',"'.$my_comments.'")';
$recording_changes = 'INSERT INTO '.$TBL_TRACK_ATTEMPT_RECORDING.' (exe_id, question_id, marks, insert_date, author, teacher_comment) VALUES ('."'$id','".$my_questionid."','$my_marks','".api_get_utc_datetime()."','".api_get_user_id()."'".',"'.$my_comments.'")';
Database::query($recording_changes);
}
@ -520,6 +520,14 @@ if ($is_allowedToEdit && $origin != 'learnpath') {
if ($show != 'result') {
echo '<a href="exercise_admin.php?' . api_get_cidreq() . '">' . Display :: return_icon('new_exercice.png', get_lang('NewEx'),'','32').'</a>';
echo '<a href="question_create.php?' . api_get_cidreq() . '">' . Display :: return_icon('new_question.png', get_lang('AddQ'),'','32').'</a>';
// Question category
echo '<a href="tests_category.php">';
echo Display::return_icon('question_category.gif', get_lang('QuestionCategory'));
echo '</a>';
echo '<a href="question_pool.php">';
echo Display::return_icon('database.png', get_lang('langQuestionPool'), array('style'=>'width:32px'));
echo '</a>';
// end question category
echo '<a href="hotpotatoes.php?' . api_get_cidreq() . '">' . Display :: return_icon('import_hotpotatoes.png', get_lang('ImportHotPotatoesQuiz'),'','32').'</a>';
// link to import qti2 ...
echo '<a href="qti2.php?' . api_get_cidreq() . '">' . Display :: return_icon('import_qti2.png', get_lang('ImportQtiQuiz'),'','32') .'</a>';

@ -5,6 +5,7 @@
* @package chamilo.exercise
* @author Olivier Brouckaert
* @author Julio Montoya Cleaning exercises
* Modified by Hubert Borderiou 2011-10-21 (question category)
*/
/**
* Code
@ -48,6 +49,7 @@ class Exercise {
public $course;
public $propagate_neg;
public $review_answers; //
public $randomByCat;
/**
@ -72,6 +74,7 @@ class Exercise {
$this->expired_time = '0000-00-00 00:00:00';
$this->propagate_neg = 0;
$this->review_answers = false;
$this->randomByCat = 0; //
if (!empty($course_id)) {
$course_info = api_get_course_info_by_id($this->course_id);
@ -114,6 +117,7 @@ class Exercise {
$this->attempts = $object->max_attempt;
$this->feedbacktype = $object->feedback_type;
$this->propagate_neg = $object->propagate_neg;
$this->randomByCat = $object->random_by_category; //
$this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false;
@ -234,6 +238,53 @@ class Exercise {
return $this->type;
}
/**
* return 1 or 2 if randomByCat
* @author - hubert borderiou
* @return - integer - quiz random by category
*/
function selectRandomByCat() {
return $this->randomByCat;
}
/**
* return 0 if no random by cat
* return 1 if rendom by cat, categories shuffled
* return 2 if random by cat, categories sorted by alphabetic order
* @author - hubert borderiou
* @return - integer - quiz random by category
*/
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
*/
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
*
@ -554,6 +605,7 @@ class Exercise {
$active = $this->active;
$propagate_neg = $this->propagate_neg;
$review_answers = (isset($this->review_answers) && $this->review_answers) ? 1 : 0;
$randomByCat = $this->randomByCat; //
$session_id = api_get_session_id();
@ -584,9 +636,10 @@ class Exercise {
start_time = '$start_time',
end_time = '$end_time',
max_attempt ='".Database::escape_string($attempts)."',
expired_time ='".Database::escape_string($expired_time)."',
propagate_neg ='".Database::escape_string($propagate_neg)."',
review_answers ='".Database::escape_string($review_answers)."',
expired_time ='".Database::escape_string($expired_time)."',
propagate_neg ='".Database::escape_string($propagate_neg)."',
review_answers ='".Database::escape_string($review_answers)."',
random_by_category ='".Database::escape_string($randomByCat)."',
results_disabled='".Database::escape_string($results_disabled)."'";
}
@ -601,8 +654,7 @@ class Exercise {
}
} else {
// creates a new exercise
$sql="INSERT INTO $TBL_EXERCICES (c_id, start_time, end_time, title, description, sound, type, random, random_answers,
active, results_disabled, max_attempt, feedback_type, expired_time, session_id, review_answers)
$sql="INSERT INTO $TBL_EXERCICES (c_id, start_time, end_time, title, description, sound, type, random, random_answers, active, results_disabled, max_attempt, feedback_type, expired_time, session_id, review_answers, random_by_category)
VALUES(
".$this->course_id.",
'$start_time','$end_time',
@ -618,7 +670,8 @@ class Exercise {
'".Database::escape_string($feedbacktype)."',
'".Database::escape_string($expired_time)."',
'".Database::escape_string($session_id)."',
'".Database::escape_string($review_answers)."'
'".Database::escape_string($review_answers)."',
'".Database::escape_string($randomByCat)."'
)";
Database::query($sql);
$this->id = Database::insert_id();
@ -868,6 +921,15 @@ class Exercise {
$radios_random_answers[] = FormValidator :: createElement ('radio', 'randomAnswers', null, get_lang('No'),'0');
$form->addGroup($radios_random_answers, null, get_lang('RandomAnswers'));
//randow by category
$form->addElement('html','<div class="clear">&nbsp;</div>');
$radiocat = array();
$radiocat[] = FormValidator::createElement('radio', 'randomByCat', null, get_lang('yesWithCategoriesShuffled'),'1');
$radiocat[] = FormValidator::createElement('radio', 'randomByCat', null, get_lang('yesWithCategoriesSorted'),'2');
$radiocat[] = FormValidator::createElement('radio', 'randomByCat', null, get_lang('No'),'0');
$form->addGroup($radiocat, null, get_lang('RandomQuestionByCategory'));
$form->addElement('html','<div class="clear">&nbsp;</div>');
//Attempts
$attempt_option=range(0,10);
$attempt_option[0]=get_lang('Infinite');
@ -898,6 +960,7 @@ class Exercise {
//$check_option=$this->selectType();
$diplay = 'block';
$form->addElement('checkbox', 'propagate_neg', get_lang('PropagateNegativeResults'), null);
$form->addElement('html','<div class="clear">&nbsp;</div>');
$form->addElement('checkbox', 'review_answers', get_lang('ReviewAnswers'), null);
$form->addElement('html','<div id="divtimecontrol" style="display:'.$diplay.';">');
@ -981,9 +1044,8 @@ class Exercise {
$defaults['exerciseFeedbackType'] = $this->selectFeedbackType();
$defaults['results_disabled'] = $this->selectResultsDisabled();
$defaults['propagate_neg'] = $this->selectPropagateNeg();
$defaults['review_answers'] = $this->review_answers;
$defaults['randomByCat'] = $this->selectRandomByCat(); //
if (($this->start_time!='0000-00-00 00:00:00'))
$defaults['activate_start_date_check'] = 1;
@ -1008,7 +1070,7 @@ class Exercise {
$defaults['exerciseDescription'] = '';
$defaults['exerciseFeedbackType'] = 0;
$defaults['results_disabled'] = 0;
$defaults['randomByCat'] = 0; //
$defaults['start_time'] = date('Y-m-d 12:00:00');
$defaults['end_time'] = date('Y-m-d 12:00:00',time()+84600);
}
@ -1038,7 +1100,7 @@ class Exercise {
$this->updateResultsDisabled($form->getSubmitValue('results_disabled'));
$this->updateExpiredTime($form->getSubmitValue('enabletimercontroltotalminutes'));
$this->updatePropagateNegative($form->getSubmitValue('propagate_neg'));
$this->updateRandomByCat($form->getSubmitValue('randomByCat')); //
$this->updateReviewAnswers($form->getSubmitValue('review_answers'));
if ($form->getSubmitValue('activate_start_date_check') == 1) {
@ -3223,8 +3285,62 @@ class Exercise {
}
function get_validated_question_list() {
return ($this->isRandom() ? $this->selectRandomList() : $this->selectQuestionList());
}
$tabres = array();
$isRandomByCategory = $this->isRandomByCat();
if (!$isRandomByCategory) {
if ($this->isRandom()) {
$tabres = $this->selectRandomList();
}
else {
$tabres = $this->selectQuestionList();
}
}
else {
if ($this->isRandom()) {
if (!class_exists("Testcategory")) {
require_once("testcategory.class.php");
}
// -----------------------------
// USE question categories hub 13-10-2011
// -----------------------------
// get questions by category for this exercice
// we have to choice $objExercise->random question in each array values of $tabCategoryQuestions
// key of $tabCategoryQuestions are the categopy id (0 for not in a category)
// value is the array of question id of this category
$questionList = array();
$tabCategoryQuestions = array();
$tabCategoryQuestions = Testcategory::getQuestionsByCat($this->id);
$isRandomByCategory = $this->selectRandomByCat();
// on tri les catégories en fonction du terme entre [] en tête de la description de la catégorie
/*
* ex de catégories :
* [biologie] Maîtriser les mécanismes de base de la génétique
* [biologie] Relier les moyens de défenses et les agents infectieux
* [biologie] Savoir où est produite l'énergie dans les cellules et sous quelle forme
* [chimie] Classer les molécules suivant leur pouvoir oxydant ou réducteur
* [chimie] Connaître la définition de la théorie acide/base selon Brönsted
* [chimie] Connaître les charges des particules
* On veut dans l'ordre des groupes définis par le terme entre crochet au début du titre de la catégorie
*/
// If test option is Grouped By Categories
if ($isRandomByCategory == 2) {
$tabCategoryQuestions = Testcategory::sortTabByBracketLabel($tabCategoryQuestions); // 24-02-2011 hub pour projet Bernard Ycard
}
while (list($cat_id, $tabquestion) = each($tabCategoryQuestions)) {
$questionList = array_merge($questionList, Testcategory::getNElementsFromArray($tabquestion, $this->random));
}
// shuffle the question list if test is not grouped by categories
if ($isRandomByCategory == 1) {
shuffle($questionList); // or not
}
$tabres = $questionList;
}
else {
// Problem, random by category has been selected and we have no $this->isRandom nnumber of question selected
// Should not happened
}
}
return $tabres; }
public function get_stat_track_exercise_info_by_exe_id($exe_id) {
$track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);

@ -8,6 +8,7 @@
* @package chamilo.exercise
* @author Olivier Brouckaert <oli.brouckaert@skynet.be>
* @version $Id: exercise.lib.php 22247 2009-07-20 15:57:25Z ivantcholakov $
* Modified by Hubert Borderiou 2011-10-21 Question Category
*/
/**
* Code
@ -51,6 +52,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$questionDescription = $objQuestionTmp->selectDescription();
if ($show_title) {
Testcategory::displayCategoryAndTitle($objQuestionTmp->id); //
echo Display::div($current_item.'. '.$objQuestionTmp->selectTitle(), array('class'=>'question_title'));
}
if (!empty($questionDescription)) {
@ -501,6 +503,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
if (!$only_questions) {
if ($show_title) {
Testcategory::displayCategoryAndTitle($objQuestionTmp->id); //
echo '<div class="question_title">'.$current_item.'. '.$questionName.'</div>';
}
//@todo I need to the get the feedback type
@ -1257,6 +1260,29 @@ function get_all_exercises($course_info = null, $session_id = 0, $check_dates =
return Database::select('*',$TBL_EXERCICES, $conditions);
}
/**
* Getting all active exercises from a course from a session (if a session_id is provided we will show all the exercises in the course + all exercises in the session)
* @param array course data
* @param int session id
* @param int course c_id
* @return array array with exercise data
* modified by Hubert Borderiou
*/
function get_all_exercises_for_course_id($course_info = null, $session_id = 0, $course_id=0) {
$TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST);
if ($session_id == -1) {
$session_id = 0;
}
if ($session_id == 0) {
$conditions = array('where'=>array('active = ? AND session_id = ? AND c_id=?'=>array('1', $session_id, $course_id)), 'order'=>'title');
} else {
//All exercises
$conditions = array('where'=>array('active = ? AND (session_id = 0 OR session_id = ? ) AND c_id=?' =>array('1', $session_id, $course_id)), 'order'=>'title');
}
return Database::select('*',$TBL_EXERCICES, $conditions);
}
/**
* Gets the position of the score based in a given score (result/weight) and the exe_id based in the user list
* (NO Exercises in LPs )

@ -22,6 +22,7 @@
* Cleaning exercises (2010),
* Adding hotspot delineation support (2011)
* Adding reminder + ajax support (2011)
* Modified by hubert.borderiou (2011-10-21 question category)
*/
/**
* Code
@ -585,6 +586,10 @@ if ($question_count != 0) {
}
} else {
$error = get_lang('ThereAreNoQuestionsForThisExercise');
// if we are in the case where user select random by category, but didn't choose the number of random question
if ($objExercise->selectRandomByCat() > 0 && $objExercise->random <= 0) {
$error .= "<br/>".get_lang('pleaseSelectSomeRandomQuestion');
}
}
if (!empty ($_GET['gradebook']) && $_GET['gradebook'] == 'view') {

@ -5,10 +5,12 @@
* @package chamilo.exercise
* @author Olivier Brouckaert
* @author Julio Montoya <gugli100@gmail.com> lot of bug fixes
* Modified by hubert.borderiou@grenet.fr - add question categories
*/
/**
* Code
*/
if(!class_exists('Question')):
// answer types
@ -25,6 +27,7 @@ define('UNIQUE_ANSWER_NO_OPTION', 10);
define('MULTIPLE_ANSWER_TRUE_FALSE', 11);
define('MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE', 12);
if (!class_exists('Category')) include_once("testcategory.class.php"); // hub 12-10-2011
/**
QUESTION CLASS
@ -46,8 +49,9 @@ abstract class Question
public $level;
public $picture;
public $exerciseList; // array with the list of exercises which this question is in
public $category; // hub 12-10-2011
private $isContent;
public $course;
public $course;
static $typePicture = 'new_question.png';
static $explanationLangVar = '';
@ -79,10 +83,10 @@ abstract class Question
$this->position=1;
$this->picture='';
$this->level = 1;
$this->extra='';
$this->category=0; // hub 12-10-2011
$this->extra='';
$this->exerciseList=array();
$this->course = api_get_course_info();
$this->course_id = api_get_course_int_id();
}
public function getIsContent() {
@ -105,17 +109,17 @@ abstract class Question
if (!empty($course_id)) {
$course_info = api_get_course_info_by_id($course_id);
} else {
} else {
global $course;
$course_info = api_get_course_info();
}
$course_id = $course_info['real_id'];
$TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST, $course_info['db_name']);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $course_info['db_name']);
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $course_info['db_name']);
$sql = "SELECT question,description,ponderation,position,type,picture,level,extra
FROM $TBL_QUESTIONS WHERE c_id = $course_id AND id = $id ";
$sql = "SELECT question,description,ponderation,position,type,picture,level,extra FROM $TBL_QUESTIONS WHERE c_id = $course_id AND id = $id ";
$result = Database::query($sql);
@ -132,8 +136,9 @@ abstract class Question
$objQuestion->type = $object->type;
$objQuestion->picture = $object->picture;
$objQuestion->level = (int) $object->level;
$objQuestion->extra = $object->extra;
$objQuestion->course = $course_info;
$objQuestion->extra = $object->extra;
$objQuestion->course = $course_info;
$objQuestion->category = Testcategory::getCategoryForQuestion($id); // hub 12-10-2011
$sql = "SELECT exercice_id FROM $TBL_EXERCICE_QUESTION WHERE c_id = $course_id AND question_id = $id";
$result_exercise_list = Database::query($sql);
@ -299,6 +304,74 @@ abstract class Question
$this->weighting=$weighting;
}
/**
* @author - Hubert Borderiou 12-10-2011
* @param - array of category $in_category
*/
function updateCategory($in_category) {
$this->category=$in_category;
}
/**
* @author - Hubert Borderiou 12-10-2011
* @param - interger $in_positive
*/
function updateScoreAlwaysPositive($in_positive) {
$this->scoreAlwaysPositive=$in_positive;
}
/**
* @author - Hubert Borderiou 12-10-2011
* @param - interger $in_positive
*/
function updateUncheckedMayScore($in_positive) {
$this->uncheckedMayScore=$in_positive;
}
/**
* @author - Hubert Borderiou 12-10-2011
* @param - interger $in_positive
* in this version, a question can only have 1 category
* if category is 0, then question has no category then delete the category entry
*/
function saveCategory($in_category) {
if ($in_category <= 0) {
$this->deleteCategory();
}
// update or add category for a question
else {
$TBL_QUESTION_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$category_id = Database::escape_string($in_category);
$question_id = Database::escape_string($this->id);
$sql = "SELECT count(*) AS nb FROM $TBL_QUESTION_REL_CATEGORY WHERE question_id=$question_id AND c_id=".api_get_course_int_id();
$res = Database::query($sql);
$row = Database::fetch_array($res);
if ($row['nb'] > 0){
$sql = "UPDATE $TBL_QUESTION_REL_CATEGORY SET category_id=$category_id WHERE question_id=$question_id AND c_id=".api_get_course_int_id();
$res = Database::query($sql);
}
else {
$sql = "INSERT INTO $TBL_QUESTION_REL_CATEGORY VALUES (".api_get_course_int_id().", $question_id, $category_id)";
$res = Database::query($sql);
}
}
}
/**
* @author hubert borderiou 12-10-2011
* delete any category entry for question id
* @param : none
* delte the category for question
*/
function deleteCategory() {
$TBL_QUESTION_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$question_id = Database::escape_string($this->id);
$sql = "DELETE FROM $TBL_QUESTION_REL_CATEGORY WHERE question_id=$question_id AND c_id=".api_get_course_int_id();
$res = Database::query($sql);
}
/**
* changes the question position
*
@ -329,16 +402,17 @@ abstract class Question
* @param - integer $type - answer type
*/
function updateType($type) {
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
// if we really change the type
if($type != $this->type) {
// if we don't change from "unique answer" to "multiple answers" (or conversely)
if(!in_array($this->type,array(UNIQUE_ANSWER, MULTIPLE_ANSWER)) || !in_array($type,array(UNIQUE_ANSWER,MULTIPLE_ANSWER))) {
if(!in_array($this->type,array(UNIQUE_ANSWER,MULTIPLE_ANSWER)) || !in_array($type,array(UNIQUE_ANSWER,MULTIPLE_ANSWER))) {
// removes old answers
$sql = "DELETE FROM $TBL_REPONSES WHERE c_id = ".api_get_course_int_id()." AND question_id = ".Database::escape_string($this->id);
$sql="DELETE FROM $TBL_REPONSES WHERE question_id='".Database::escape_string($this->id)."'";
Database::query($sql);
}
$this->type=$type;
}
}
@ -479,12 +553,12 @@ abstract class Question
*/
function exportPicture($questionId, $course_info) {
$course_id = $course_info['real_id'];
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $course_info['db_name']);
$destination_path = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/document/images';
$source_path = api_get_path(SYS_COURSE_PATH).$this->course['path'].'/document/images';
// if the question has got an ID and if the picture exists
if ($this->id && !empty($this->picture)) {
if($this->id && !empty($this->picture)) {
$picture=explode('.',$this->picture);
$Extension=$picture[sizeof($picture)-1];
$picture='quiz-'.$questionId.'.'.$Extension;
@ -577,8 +651,8 @@ abstract class Question
*/
function save($exerciseId=0) {
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $this->course['db_name']);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $this->course['db_name']);
$id = $this->id;
$question = $this->question;
@ -588,11 +662,13 @@ abstract class Question
$type = $this->type;
$picture = $this->picture;
$level = $this->level;
$extra = $this->extra;
$c_id = $this->course['real_id'];
$extra = $this->extra;
$c_id = $this->course['real_id'];
$category = $this->category; // hub 12-10-2011
// question already exists
if (!empty($id)) {
if(!empty($id)) {
$sql="UPDATE $TBL_QUESTIONS SET
question ='".Database::escape_string($question)."',
description ='".Database::escape_string($description)."',
@ -600,23 +676,24 @@ abstract class Question
position ='".Database::escape_string($position)."',
type ='".Database::escape_string($type)."',
picture ='".Database::escape_string($picture)."',
extra ='".Database::escape_string($extra)."',
extra ='".Database::escape_string($extra)."',
level ='".Database::escape_string($level)."'
WHERE c_id = ".$c_id." AND id = '".Database::escape_string($id)."'";
WHERE id='".Database::escape_string($id)."'";
Database::query($sql);
$this->saveCategory($category); // hub 12-10-2011
if (!empty($exerciseId)) {
api_item_property_update($this->course, TOOL_QUIZ, $id,'QuizQuestionUpdated',api_get_user_id);
}
if (api_get_setting('search_enabled')=='true') {
if ($exerciseId != 0) {
$this -> search_engine_edit($exerciseId);
} else {
/**
* actually there is *not* an user interface for
* creating questions without a relation with an exercise
*/
}
}
if (api_get_setting('search_enabled')=='true') {
if ($exerciseId != 0) {
$this -> search_engine_edit($exerciseId);
} else {
/**
* actually there is *not* an user interface for
* creating questions without a relation with an exercise
*/
}
}
} else {
// creates a new question
@ -624,7 +701,8 @@ abstract class Question
WHERE question.id = test_question.question_id AND
test_question.exercice_id = '".Database::escape_string($exerciseId)."' AND
question.c_id = $c_id AND
test_question.c_id = $c_id
test_question.c_id = $c_id
";
$result = Database::query($sql);
$current_position = Database::result($result,0,0);
@ -642,8 +720,9 @@ abstract class Question
'".Database::escape_string($level)."'
)";
Database::query($sql);
$this->id = Database::insert_id();
api_item_property_update($this->course, TOOL_QUIZ, $this->id,'QuizQuestionAdded',api_get_user_id());
// If hotspot, create first answer
@ -662,16 +741,17 @@ abstract class Question
}
if (api_get_setting('search_enabled')=='true') {
if ($exerciseId != 0) {
$this -> search_engine_edit($exerciseId, TRUE);
} else {
/**
* actually there is *not* an user interface for
* creating questions without a relation with an exercise
*/
}
}
if (api_get_setting('search_enabled')=='true') {
if ($exerciseId != 0) {
$this -> search_engine_edit($exerciseId, TRUE);
}
else {
/**
* actually there is *not* an user interface for
* creating questions without a relation with an exercise
*/
}
}
}
// if the question is created in an exercise
@ -835,28 +915,28 @@ abstract class Question
$id=$this->id;
// searches the position of the exercise ID in the list
$pos = array_search($exerciseId,$this->exerciseList);
$pos=array_search($exerciseId,$this->exerciseList);
// exercise not found
if ($pos === false) {
if($pos === false) {
return false;
} else {
// deletes the position in the array containing the wanted exercise ID
unset($this->exerciseList[$pos]);
//update order of other elements
$sql = "SELECT question_order FROM $TBL_EXERCICE_QUESTION WHERE c_id = ".api_get_course_int_id()." AND question_id='".Database::escape_string($id)."' AND exercice_id='".Database::escape_string($exerciseId)."'";
$sql = "SELECT question_order FROM $TBL_EXERCICE_QUESTION WHERE question_id='".Database::escape_string($id)."' AND exercice_id='".Database::escape_string($exerciseId)."'";
$res = Database::query($sql);
if (Database::num_rows($res)>0) {
$row = Database::fetch_array($res);
if (!empty($row['question_order'])) {
echo $sql = "UPDATE $TBL_EXERCICE_QUESTION SET question_order = question_order-1
WHERE c_id = ".api_get_course_int_id()." AND exercice_id='".Database::escape_string($exerciseId)."' AND question_order > ".$row['question_order'];
$sql = "UPDATE $TBL_EXERCICE_QUESTION SET question_order = question_order-1 WHERE exercice_id='".Database::escape_string($exerciseId)."' AND question_order > ".$row['question_order'];
$res = Database::query($sql);
}
}
$sql = "DELETE FROM $TBL_EXERCICE_QUESTION WHERE c_id = ".api_get_course_int_id()." AND question_id='".Database::escape_string($id)."' AND exercice_id='".Database::escape_string($exerciseId)."'";
$sql="DELETE FROM $TBL_EXERCICE_QUESTION WHERE question_id='".Database::escape_string($id)."' AND exercice_id='".Database::escape_string($exerciseId)."'";
Database::query($sql);
return true;
}
}
@ -869,45 +949,52 @@ abstract class Question
* @author - Olivier Brouckaert
* @param - integer $deleteFromEx - exercise ID if the question is only removed from one exercise
*/
function delete($deleteFromEx = 0) {
function delete($deleteFromEx=0) {
global $_course,$_user;
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
$id = $this->id;
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $this->course['db_name']);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $this->course['db_name']);
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
$TBL_QUIZ_QUESTION_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY, $this->course['db_name']); // hub 12-10-2011
$id=$this->id;
// if the question must be removed from all exercises
if (!$deleteFromEx) {
if(!$deleteFromEx)
{
//update the question_order of each question to avoid inconsistencies
$sql = "SELECT exercice_id, question_order FROM $TBL_EXERCICE_QUESTION WHERE c_id = ".api_get_course_int_id()." AND question_id='".Database::escape_string($id)."'";
$sql = "SELECT exercice_id, question_order FROM $TBL_EXERCICE_QUESTION WHERE question_id='".Database::escape_string($id)."'";
$res = Database::query($sql);
if (Database::num_rows($res)>0) {
while ($row = Database::fetch_array($res)) {
if (!empty($row['question_order'])) {
$sql = "UPDATE $TBL_EXERCICE_QUESTION SET question_order = question_order-1
WHERE c_id = ".api_get_course_int_id()." AND exercice_id='".Database::escape_string($row['exercice_id'])."' AND question_order > ".$row['question_order'];
$sql = "UPDATE $TBL_EXERCICE_QUESTION SET question_order = question_order-1 WHERE exercice_id='".Database::escape_string($row['exercice_id'])."' AND question_order > ".$row['question_order'];
$res = Database::query($sql);
}
}
}
$sql="DELETE FROM $TBL_EXERCICE_QUESTION WHERE c_id = ".api_get_course_int_id()." AND question_id='".Database::escape_string($id)."'";
$sql="DELETE FROM $TBL_EXERCICE_QUESTION WHERE question_id='".Database::escape_string($id)."'";
Database::query($sql);
$sql="DELETE FROM $TBL_QUESTIONS WHERE c_id = ".api_get_course_int_id()." AND id='".Database::escape_string($id)."'";
$sql="DELETE FROM $TBL_QUESTIONS WHERE id='".Database::escape_string($id)."'";
Database::query($sql);
$sql="DELETE FROM $TBL_REPONSES WHERE c_id = ".api_get_course_int_id()." AND question_id='".Database::escape_string($id)."'";
$sql="DELETE FROM $TBL_REPONSES WHERE question_id='".Database::escape_string($id)."'";
Database::query($sql);
// hub 12-10-2011 remove the category of this question in the question_rel_category table
$sql = "DELETE FROM $TBL_QUIZ_QUESTION_REL_CATEGORY WHERE question_id='".Database::escape_string($id)."' AND c_id=".api_get_course_int_id();
Database::query($sql);
api_item_property_update($this->course, TOOL_QUIZ, $id,'QuizQuestionDeleted',api_get_user_id());
$this->removePicture();
// resets the object
$this->Question();
} // just removes the exercise from the list
else {
}
// just removes the exercise from the list
else
{
$this->removeFromList($deleteFromEx);
if (api_get_setting('search_enabled')=='true' && extension_loaded('xapian')) {
// disassociate question with this exercise
@ -931,8 +1018,8 @@ abstract class Question
} else {
$course_info = $course_info;
}
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_QUESTION_OPTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $course_info['db_name']);
$TBL_QUESTION_OPTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION, $course_info['db_name']);
$question = $this->question;
$description = $this->description;
@ -1007,7 +1094,8 @@ abstract class Question
echo '<script>
// hack to hide http://cksource.com/forums/viewtopic.php?f=6&t=8700
function FCKeditor_OnComplete( editorInstance ) {
function FCKeditor_OnComplete( editorInstance )
{
if (document.getElementById ( \'HiddenFCK\' + editorInstance.Name )) {
HideFCKEditorByInstanceName (editorInstance.Name);
}
@ -1018,16 +1106,36 @@ abstract class Question
document.getElementById ( \'HiddenFCK\' + editorInstanceName ).className = "media";
}
}
function show_media() {
function show_media()
{
var my_display = document.getElementById(\'HiddenFCKquestionDescription\').style.display;
if(my_display== \'none\' || my_display == \'\') {
document.getElementById(\'HiddenFCKquestionDescription\').style.display = \'block\';
document.getElementById(\'media_icon\').innerHTML=\' <img style="vertical-align: middle;" src="../img/looknfeelna.png" alt="" /> '.addslashes(api_htmlentities(get_lang('EnrichQuestion'))).'\';
document.getElementById(\'media_icon\').innerHTML=\'&nbsp;<img style="vertical-align: middle;" src="../img/looknfeelna.png" alt="" />&nbsp;'.get_lang('EnrichQuestion').'\';
} else {
document.getElementById(\'HiddenFCKquestionDescription\').style.display = \'none\';
document.getElementById(\'media_icon\').innerHTML=\' <img style="vertical-align: middle;" src="../img/looknfeel.png" alt="" /> '.addslashes(api_htmlentities(get_lang('EnrichQuestion'))).'\';
document.getElementById(\'media_icon\').innerHTML=\'&nbsp;<img style="vertical-align: middle;" src="../img/looknfeel.png" alt="" />&nbsp;'.get_lang('EnrichQuestion').'\';
}
}
// hub 13-12-2010
function visiblerDevisibler(in_id) {
if (document.getElementById(in_id)) {
if (document.getElementById(in_id).style.display == "none") {
document.getElementById(in_id).style.display = "block";
if (document.getElementById(in_id+"Img")) {
document.getElementById(in_id+"Img").src = "../img/div_hide.gif";
}
}
else {
document.getElementById(in_id).style.display = "none";
if (document.getElementById(in_id+"Img")) {
document.getElementById(in_id+"Img").src = "../img/div_show.gif";
}
}
}
}
</script>';
@ -1041,17 +1149,12 @@ abstract class Question
//$test=FormValidator :: createElement ('text', 'questionName');
//$radios_results_enabled[]=$test;
// question level
//@todo move levles into a table
$select_level = array (1,2,3,4,5);
//$radios_results_enabled[] =
foreach($select_level as $val) {
$radios_results_enabled[] = FormValidator :: createElement ('radio', null, null,$val,$val);
}
$form->addGroup($radios_results_enabled,'questionLevel',get_lang('Difficulty'));
$renderer->setElementTemplate('<div class="row"><div class="label">{label}</div><div class="formw" >{element}</div></div>','questionName');
$renderer->setElementTemplate('<div class="row"><div class="label">{label}</div><div class="formw">{element}</div></div>','questionLevel');
// -------------------------------
// Enrich question
// -------------------------------
$form->addRule('questionName', get_lang('GiveQuestion'), 'required');
// default content
@ -1071,10 +1174,7 @@ abstract class Question
$form -> addElement('html','<div class="row">
<div class="label"></div>
<div class="formw" style="height:50px">
<a href="javascript://" onclick=" return show_media()">
<span id="media_icon">
<img style="vertical-align: middle;" src="../img/looknfeel.png" alt="" /> '.addslashes(api_htmlentities(get_lang('EnrichQuestion'))).'
</span></a>
<a href="javascript://" onclick=" return show_media()"> <span id="media_icon"> <img style="vertical-align: middle;" src="../img/looknfeel.png" alt="" />&nbsp;'.get_lang('EnrichQuestion').'</span></a>
</div>
</div>');
@ -1084,31 +1184,52 @@ abstract class Question
$renderer->setElementTemplate('<div class="row"><div class="label">{label}</div><div class="formw">{element}</div></div>','questionDescription');
// -------------------------------
// Advanced parameters
// -------------------------------
// question level
//@todo move levles into a table
$select_level = array (1,2,3,4,5);
//$radios_results_enabled[] =
foreach($select_level as $val) {
$radios_results_enabled[] = FormValidator :: createElement ('radio', null, null,$val,$val);
}
$form->addGroup($radios_results_enabled,'questionLevel',get_lang('Difficulty'));
// HUB 12-10-2011
// categories
$tabCat = array();
$tabCat = Testcategory::getCategoriesIdAndName();
$form->addElement('select', 'questionCategory', get_lang('Category'), $tabCat);
// note always positive for multiple answer questions
// Form's style
$renderer->setElementTemplate('<div class="row"><div class="label">{label}</div><div class="formw">{element}</div></div>&nbsp;','questionName');
$renderer->setElementTemplate('<div style="margin-left:0%;float:right;text-align:left;width:89%" class=""><a href="javascript:void(0)" onclick="visiblerDevisibler(\'id_advancedOption\')"><img id="id_advancedOptionImg" style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang("AdvancedParameters").'</a><div id="id_advancedOption" style="background-color:#EFEFEF;display:none;"><div class="row"><div class="label">{label}</div><div class="formw">{element}</div></div>','questionLevel');
$renderer->setElementTemplate('<div class="row"><div class="label">{label}</div><div class="formw">{element}</div></div><br/></div></div><div style="clear:both">&nbsp;</div>','questionCategory');
// fhub
// hidden values
$form->addElement('hidden','myid',$_REQUEST['myid']);
if (!isset($_GET['fromExercise'])) {
switch($answerType) {
case 1: $this->question = get_lang('langDefaultUniqueQuestion'); break;
case 2: $this->question = get_lang('langDefaultMultipleQuestion'); break;
case 3: $this->question = get_lang('langDefaultFillBlankQuestion'); break;
case 4: $this->question = get_lang('langDefaultMathingQuestion'); break;
case 5: $this->question = get_lang('langDefaultOpenQuestion'); break;
case 9: $this->question = get_lang('langDefaultMultipleQuestion'); break;
}
}
if (!isset($_GET['fromExercise'])) {
switch($answerType) {
case 1: $this->question = get_lang('langDefaultUniqueQuestion'); break;
case 2: $this->question = get_lang('langDefaultMultipleQuestion'); break;
case 3: $this->question = get_lang('langDefaultFillBlankQuestion'); break;
case 4: $this->question = get_lang('langDefaultMathingQuestion'); break;
case 5: $this->question = get_lang('langDefaultOpenQuestion'); break;
case 9: $this->question = get_lang('langDefaultMultipleQuestion'); break;
}
}
$form->addElement('html','</div>');
// default values
$defaults = array();
$defaults['questionName'] = $this -> question;
$defaults['questionDescription'] = $this -> description;
$defaults['questionLevel'] = $this -> level;
//Came from he question pool
if (isset($_GET['fromExercise'])) {
$form->setDefaults($defaults);
}
$defaults['questionCategory'] = $this->category; // hub 12-10-2011
//Came from he question pool
if (isset($_GET['fromExercise'])) {
$form->setDefaults($defaults);
}
if (!empty($_REQUEST['myid'])) {
$form->setDefaults($defaults);
@ -1126,13 +1247,13 @@ abstract class Question
*/
function processCreation ($form, $objExercise) {
$this -> updateTitle($form->getSubmitValue('questionName'));
$this -> updateDescription($form->getSubmitValue('questionDescription'));
$this -> updateLevel($form->getSubmitValue('questionLevel'));
$this -> save($objExercise -> id);
// modify the exercise
$objExercise->addToList($this -> id);
$objExercise->update_question_positions();
$this -> updateDescription($form->getSubmitValue('questionDescription'));
$this -> updateLevel($form->getSubmitValue('questionLevel'));
$this->updateCategory($form->getSubmitValue('questionCategory')); // hub 12-10-2011
$this -> save($objExercise -> id);
// modify the exercise
$objExercise->addToList($this -> id);
$objExercise->update_question_positions();
}
/**
@ -1171,7 +1292,7 @@ abstract class Question
if (isset($exerciseId) && !empty($exerciseId)) {
$TBL_LP_ITEM = Database::get_course_table(TABLE_LP_ITEM);
$sql="SELECT max_score FROM $TBL_LP_ITEM
WHERE c_id = ".api_get_course_int_id()." AND item_type = '".TOOL_QUIZ."' AND path ='".Database::escape_string($exerciseId)."'";
WHERE item_type = '".TOOL_QUIZ."' AND path ='".Database::escape_string($exerciseId)."'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
$show_quiz_edition = false;
@ -1183,14 +1304,13 @@ abstract class Question
foreach ($question_type_custom_list as $i=>$a_type) {
// include the class of the type
require_once($a_type[0]);
// get the picture of the type and the langvar which describes it
$img = $explanation = '';
// get the picture of the type and the langvar which describes it
$img = $explanation = '';
eval('$img = '.$a_type[1].'::$typePicture;');
eval('$explanation = get_lang('.$a_type[1].'::$explanationLangVar);');
echo '<li>';
echo '<div class="icon_image_content">';
if ($show_quiz_edition) {
echo '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes&answerType='.$i.'">'.Display::return_icon($img, $explanation).'</a>';
//echo '<br>';
//echo '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes&answerType='.$i.'">'.$explanation.'</a>';
@ -1199,7 +1319,6 @@ abstract class Question
$img = $img['filename'];
echo ''.Display::return_icon($img.'_na.gif',$explanation).'';
//echo '<br>';
//echo ''.$explanation.'';
}
echo '</div>';
@ -1235,8 +1354,7 @@ abstract class Question
}
static function saveQuestionOption($question_id, $name, $position = 0) {
$TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
$params['c_id'] = api_get_course_int_id();
$TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
$params['question_id'] = intval($question_id);
$params['name'] = $name;
$params['position'] = $position;
@ -1247,12 +1365,12 @@ abstract class Question
static function deleteAllQuestionOptions($question_id) {
$TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
Database::delete($TBL_EXERCICE_QUESTION_OPTION, array('question_id = ? AND c_id = ?' => array($question_id, api_get_course_int_id())));
Database::delete($TBL_EXERCICE_QUESTION_OPTION, array('question_id = ?'=> $question_id));
}
static function updateQuestionOption($id, $params) {
$TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
$result = Database::update($TBL_EXERCICE_QUESTION_OPTION, $params, array('id = ? AND c_id = ? '=>array($id, api_get_course_int_id())));
$result = Database::update($TBL_EXERCICE_QUESTION_OPTION, $params, array('id = ?'=>$id));
return $result;
}
@ -1263,7 +1381,7 @@ abstract class Question
} else {
$TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION, $db_name);
}
$result = Database::select('*', $TBL_EXERCICE_QUESTION_OPTION, array('where'=>array('question_id = ? AND c_id = ? ' =>array($question_id, api_get_course_int_id())), 'order'=>'id ASC'));
$result = Database::select('*', $TBL_EXERCICE_QUESTION_OPTION, array('where'=>array('question_id = ?' =>$question_id), 'order'=>'id ASC'));
return $result;
}
@ -1294,15 +1412,15 @@ abstract class Question
$sql = "SELECT max(position) as max_position"
." FROM $tbl_quiz_question q INNER JOIN $tbl_quiz_rel_question r"
." ON q.id = r.question_id"
." AND exercice_id = $quiz_id AND q.c_id = ".api_get_course_int_id()." AND r.c_id = ".api_get_course_int_id();
$rs_max = Database::query($sql);
." AND exercice_id = $quiz_id";
$rs_max = Database::query($sql, __FILE__, __LINE__);
$row_max = Database::fetch_object($rs_max);
$max_position = $row_max->max_position +1;
// Insert the new question
$sql = "INSERT INTO $tbl_quiz_question"
." (c_id, question,ponderation,position,type,level) "
." VALUES(".api_get_course_int_id().", '".Database::escape_string($question_name)."',"
." (question,ponderation,position,type,level) "
." VALUES('".Database::escape_string($question_name)."',"
." $max_score , $max_position, $type, $level)";
$rs = Database::query($sql);
// Get the question ID
@ -1315,10 +1433,23 @@ abstract class Question
$max_order = $row_max_order->max_order + 1;
// Attach questions to quiz
$sql = "INSERT INTO $tbl_quiz_rel_question "
."(c_id, question_id,exercice_id,question_order)"
." VALUES(".api_get_course_int_id().", $question_id, $quiz_id, $max_order)";
."(question_id,exercice_id,question_order)"
." VALUES($question_id, $quiz_id, $max_order)";
$rs = Database::query($sql);
return $question_id;
}
/**
* return the image filename of the question type
*
*/
public function get_type_icon_html() {
$type = $this->selectType();
$tabQuestionList = Question::get_types_information(); // [0]=file to include [1]=type name
require_once($tabQuestionList[$type][0]);
eval('$img = '.$tabQuestionList[$type][1].'::$typePicture;');
eval('$explanation = get_lang('.$tabQuestionList[$type][1].'::$explanationLangVar);');
return array($img, $explanation);
}
}
endif;

@ -13,6 +13,7 @@
* It is included from the script admin.php
*
* @author Olivier Brouckaert
* Modified by Hubert Borderiou 21-10-2011 (Question by category)
*/
// ALLOWED_TO_INCLUDE is defined in admin.php
@ -142,65 +143,120 @@ $token = Security::get_token();
//deletes a session when using don't know question type (ugly fix)
unset($_SESSION['less_answer']);
echo '<div id="question_list">';
if ($nbrQuestions) {
$my_exercise = new Exercise();
//forces the query to the database
$my_exercise->read($_GET['exerciseId']);
$questionList=$my_exercise->selectQuestionList();
if (is_array($questionList)) {
foreach($questionList as $id) {
//To avoid warning messages
if (!is_numeric($id)) {
continue;
}
$objQuestionTmp = Question :: read($id);
$question_class = get_class($objQuestionTmp);
$clone_link = '<a href="'.api_get_self().'?'.api_get_cidreq().'&clone_question='.$id.'">'.Display::return_icon('cd.gif',get_lang('Copy'), array(), 22).'</a>';
$edit_link = '<a href="'.api_get_self().'?'.api_get_cidreq().'&type='.$objQuestionTmp->selectType().'&myid=1&editQuestion='.$id.'">'.Display::return_icon('edit.png',get_lang('Modify'), array(), 22).'</a>';
// this variable $show_quiz_edition comes from admin.php blocks the exercise/quiz modifications
if ($show_quiz_edition) {
$delete_link = '<a id="delete_'.$id.'" class="opener" href="'.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exerciseId.'&deleteQuestion='.$id.'" >'.Display::return_icon('delete.png',get_lang('Delete'), array(), 22).'</a>';
}
$clone_link = Display::tag('div',$clone_link, array('style'=>'float:left; padding:0px; margin:0px'));
$edit_link = Display::tag('div',$edit_link, array('style'=>'float:left; padding:0px; margin:0px'));
$delete_link = Display::tag('div',$delete_link, array('style'=>'float:left; padding:0px; margin:0px'));
$actions = Display::tag('div',$edit_link.$clone_link.$delete_link, array('class'=>'edition','style'=>'width:100px; right:10px; margin-top: 0px; position: absolute; top: 10%;'));
echo '<div id="question_id_list_'.$id.'" >';
echo '<div class="header_operations">';
$move = Display::return_icon('move.png',get_lang('Move'), array('class'=>'moved', 'style'=>'margin-bottom:-0.5em;'));
$level = '';
if (!empty($objQuestionTmp->level)) {
$level = '('.get_lang('Difficulty').' '.$objQuestionTmp->level.')';
}
$title = Security::remove_XSS($objQuestionTmp->selectTitle());
echo Display::tag('span', '<a href="#" title = "'.$title.'">'.$move.' '.cut($title, 80).' '.Display::tag('span', $level.' ['.get_lang('QualificationNumeric').': '.$objQuestionTmp->selectWeighting().']', array('style'=>"right:110px; position: absolute;padding-top: 0.3em;")).'</a>', array('style'=>''));
echo $actions;
echo '</div>';
echo '<div class="question-list-description-block">';
echo '<p>';
//echo get_lang($question_class.$label);
echo get_lang($question_class);
echo '<br />';
//echo get_lang('Level').': '.$objQuestionTmp->selectLevel();
echo '<br />';
showQuestion($id, false, '', '',false, true);
echo '</p>';
echo '</div>';
echo '</div>';
unset($objQuestionTmp);
// If we are in a test
$inATest = isset($exerciseId) && $exerciseId > 0;
if (!$inATest) {
echo get_lang("ChoiceQuestionType");
}
else {
echo '<div id="question_list">';
if ($nbrQuestions) {
$my_exercise = new Exercise();
//forces the query to the database
$my_exercise->read($_GET['exerciseId']);
$questionList=$my_exercise->selectQuestionList();
// -----------------------
// Style for columns
// -----------------------
$styleQuestion = "width:50%; float:left;";
$styleType = "width:4%; float:left; padding-top:4px; text-align:center;";
$styleCat = "width:22%; float:left; padding-top:8px; text-align:center;";
$styleLevel = "width:6%; float:left; padding-top:8px; text-align:center;";
$styleScore = "width:4%; float:left; padding-top:8px; text-align:center;";
$styleAction = "width:10%; float:left; padding-top:8px;";
// -------------
// Title line
// -------------
echo "<div>";
echo "<div style='font-weight:bold; width:50%; float:left; padding:10px 0px; text-align:center;'><span style='padding-left:50px;'>&nbsp;</span>".get_lang('Questions')."</div>";
echo "<div style='font-weight:bold; width:4%; float:left; padding:10px 0px; text-align:center;'>".get_lang('Type')."</div>";
echo "<div style='font-weight:bold; width:22%; float:left; padding:10px 0px; text-align:center;'>".get_lang('Category')."</div>";
echo "<div style='font-weight:bold; width:6%; float:left; padding:10px 0px; text-align:center;'>".get_lang('Difficulty')."</div>";
echo "<div style='font-weight:bold; width:4%; float:left; padding:10px 0px; text-align:center;'>".get_lang('Score')."</div>";
echo "</div>";
echo "<div style='clear:both'>&nbsp;</div>";
// -------------
if (is_array($questionList)) {
foreach($questionList as $id) {
//To avoid warning messages
if (!is_numeric($id)) {
continue;
}
$objQuestionTmp = Question :: read($id);
$question_class = get_class($objQuestionTmp);
$clone_link = '<a href="'.api_get_self().'?'.api_get_cidreq().'&clone_question='.$id.'">'.Display::return_icon('cd.gif',get_lang('Copy'), array(), 22).'</a>';
$edit_link = '<a href="'.api_get_self().'?'.api_get_cidreq().'&type='.$objQuestionTmp->selectType().'&myid=1&editQuestion='.$id.'">'.Display::return_icon('edit.png',get_lang('Modify'), array(), 22).'</a>';
// this variable $show_quiz_edition comes from admin.php blocks the exercise/quiz modifications
if ($show_quiz_edition) {
$delete_link = '<a id="delete_'.$id.'" class="opener" href="'.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exerciseId.'&deleteQuestion='.$id.'" >'.Display::return_icon('delete.png',get_lang('RemoveFromTest'), array(), 22).'</a>';
}
$edit_link = Display::tag('div',$edit_link, array('style'=>'float:left; padding:0px; margin:0px'));
$clone_link = Display::tag('div',$clone_link, array('style'=>'float:left; padding:0px; margin:0px'));
$delete_link = Display::tag('div',$delete_link, array('style'=>'float:left; padding:0px; margin:0px'));
$actions = Display::tag('div',$edit_link.$clone_link.$delete_link, array('class'=>'edition','style'=>'width:100px; right:10px; margin-top: 0px; position: absolute; top: 10%;'));
$title = Security::remove_XSS($objQuestionTmp->selectTitle());
$move = Display::return_icon('move.png',get_lang('Move'), array('class'=>'moved', 'style'=>'margin-bottom:-0.5em;'));
// ---------------------
// Question name
// ---------------------
$questionName = Display::tag('div', '<a href="#" title = "'.$title.'">'.$move.' '.cut($title, 60).'</a>', array('style'=>$styleQuestion));
// ---------------------
// Question type
// ---------------------
$tabQuestionList = Question::get_types_information();
list($typeImg, $typeExpl) = $objQuestionTmp->get_type_icon_html();
$questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), 32), array('style'=>$styleType));
// ---------------------
// Question category
// ---------------------
$txtQuestionCat = Security::remove_XSS(Testcategory::getCategoryNameForQuestion($objQuestionTmp->id));
if (empty($txtQuestionCat)) {
$txtQuestionCat = "-";
}
$questionCategory = Display::tag('div', '<a href="#" style="padding:0px; margin:0px;" title="'.$txtQuestionCat.'">'.cut($txtQuestionCat, 55).'</a>', array('style'=>$styleCat));
// ---------------------
// Question level
// ---------------------
$txtQuestionLevel = $objQuestionTmp->level;
if (empty($objQuestionTmp->level)) {
$txtQuestionLevel = '-';
}
$questionLevel = Display::tag('div', $txtQuestionLevel, array('style'=>$styleLevel));
// ---------------------
// Question score
// ---------------------
$questionScore = Display::tag('div', $objQuestionTmp->selectWeighting(), array('style'=>$styleScore));
// ---------------------
echo '<div id="question_id_list_'.$id.'" >';
echo '<div class="header_operations">';
echo $questionName;
echo $questionType;
echo $questionCategory;
echo $questionLevel;
echo $questionScore;
echo $actions;
echo '</div>';
echo '<div class="question-list-description-block">';
echo '<p>';
//echo get_lang($question_class.$label);
echo get_lang($question_class);
echo '<br />';
//echo get_lang('Level').': '.$objQuestionTmp->selectLevel();
echo '<br />';
showQuestion($id, false, '', '',false, true);
echo '</p>';
echo '</div>';
echo '</div>';
unset($objQuestionTmp);
}
echo '</div>';
}
echo '</div>';
}
}
if(!$nbrQuestions) {
echo Display::display_warning_message(get_lang('NoQuestion'));
}
echo '</div>';
if(!$nbrQuestions) {
echo Display::display_warning_message(get_lang('NoQuestion'));
}
echo '</div>';
}

@ -8,6 +8,7 @@
* @package chamilo.exercise
* @author Olivier Brouckaert
* @author Julio Montoya adding support to query all questions from all session, courses, exercises
* Modify by hubert borderiou 2011-10-21 Question's category
*/
/**
* Code
@ -23,7 +24,7 @@ require_once '../inc/global.inc.php';
$this_section = SECTION_COURSES;
$is_allowedToEdit = api_is_allowed_to_edit(null,true);
$is_allowedToEdit=api_is_allowed_to_edit(null,true);
if (empty($delete)) {
$delete = intval($_GET['delete']);
@ -34,12 +35,14 @@ if ( empty ( $recup ) ) {
if ( empty ( $fromExercise ) ) {
$fromExercise = intval($_REQUEST['fromExercise']);
}
$exerciseId = null;
if(isset($_GET['exerciseId'])){
$exerciseId = intval($_GET['exerciseId']);
}
if (isset($_GET['courseCategoryId'])) {
$courseCategoryId = intval($_GET['courseCategoryId']);
}
$exerciseLevel = -1;
if(isset($_REQUEST['exerciseLevel'])){
$exerciseLevel = intval($_REQUEST['exerciseLevel']);
@ -56,17 +59,15 @@ if(!empty($_GET['copy_question'])){
$copy_question = intval($_GET['copy_question']);
}
//only that type of question
if(!empty($_GET['type'])){
$type = intval($_GET['type']);
}
$session_id = intval($_GET['session_id']);
$selected_course = intval($_GET['selected_course']);
$course_id_changed = intval($_GET['course_id_changed']); // save the id of the previous course selected by user to reset menu if we detect that user change course hub 13-10-2011
$exercice_id_changed = intval($_GET['exercice_id_changed']); // save the id of the previous exercice selected by user to reset menu if we detect that user change course hub 13-10-2011
$session_id = intval($_GET['session_id']);
$selected_course = intval($_GET['selected_course']);
// maximum number of questions on a same page
$limitQuestPage = 20;
// by default when we go to the page for the first time, we select the current course
if (!isset($_GET['selected_course']) && !isset($_GET['exerciseId'])) {
$selected_course = api_get_course_int_id();
}
// document path
$documentPath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
@ -82,65 +83,56 @@ $nameTools = get_lang('QuestionPool');
$interbreadcrumb[] = array("url" => "exercice.php","name" => get_lang('Exercices'));
$interbreadcrumb[] = array("url" => "admin.php?exerciseId=".$objExercise->id, "name" => $objExercise->name);
$displayMessage = ""; // messag to be displayed if actions succesfull
if ($is_allowedToEdit) {
//Duplicating a Question
if (!isset($_POST['recup']) && $copy_question != 0 && isset($fromExercise)) {
$origin_course_id = intval($_GET['course_id']);
$origin_course_info = api_get_course_info_by_id($origin_course_id);
$current_course = api_get_course_info();
$old_question_id = $copy_question;
//Reading the source question
$origin_course_id = intval($_GET['course_id']);
$origin_course_info = api_get_course_info_by_id($origin_course_id);
$current_course = api_get_course_info();
$old_question_id = $copy_question;
//Reading the source question
$old_question_obj = Question::read($old_question_id, $origin_course_id);
if ($old_question_obj) {
$old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));
//Duplicating the source question, in the current course
//Duplicating the source question, in the current course
$new_id = $old_question_obj->duplicate($current_course);
//Reading new question
//Reading new question
$new_question_obj = Question::read($new_id);
$new_question_obj->addToList($fromExercise);
//Reading Answers obj of the current course
//Reading Answers obj of the current course
$new_answer_obj = new Answer($old_question_id, $origin_course_id);
$new_answer_obj->read();
//Duplicating the Answers in the current course
//Duplicating the Answers in the current course
$new_answer_obj->duplicate($new_id, $current_course);
// destruction of the Question object
unset($new_question_obj);
unset($old_question_obj);
if (!$objExcercise instanceOf Exercise) {
$objExercise = new Exercise();
$objExercise->read($fromExercise);
}
if (!$objExcercise instanceOf Exercise) {
$objExercise = new Exercise();
$objExercise->read($fromExercise);
}
api_session_register('objExercise');
}
header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
exit();
$displayMessage = get_lang('ItemAdded');
// header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
// exit();
}
// deletes a question from the data base and all exercises
// deletes a question from the database and all exercises
if ($delete) {
// construction of the Question object
// if the question exists
if($objQuestionTmp = Question::read($delete)) {
if($objQuestionTmp = Question::read($delete))
{
// deletes the question from all exercises
$objQuestionTmp->delete();
}
// destruction of the Question object
unset($objQuestionTmp);
} elseif($recup && $fromExercise) {
/*
}
elseif($recup && $fromExercise) {
// gets an existing question and copies it into a new exercise
$objQuestionTmp = Question :: read($recup);
// if the question exists
if($objQuestionTmp = Question :: read($recup)) {
// adds the exercise ID represented by $fromExercise into the list of exercises for the current question
@ -156,9 +148,11 @@ if ($is_allowedToEdit) {
// adds the question ID represented by $recup into the list of questions for the current exercise
$objExercise->addToList($recup);
api_session_register('objExercise');
header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
exit();*/
} else if( isset($_POST['recup']) && is_array($_POST['recup']) && $fromExercise) {
// header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
// exit();
}
else if( isset($_POST['recup']) && is_array($_POST['recup']) && $fromExercise) {
$list_recup = $_POST['recup'];
foreach ($list_recup as $course_id => $question_data) {
@ -216,8 +210,8 @@ if ($is_allowedToEdit) {
}
}
api_session_register('objExercise');
header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
exit();
// header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
// exit();
}
}
@ -234,25 +228,55 @@ if (!$is_allowedToEdit) {
api_not_allowed(true);
}
$htmlHeadXtra[] = ' <script type="text/javascript">
$confirmYourChoice = addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset));
$htmlHeadXtra[] = "
<script type='text/javascript'>
function submit_form(obj) {
document.question_pool.submit();
}
</script>';
function mark_course_id_changed() {
$('#course_id_changed').val('1');
}
function mark_exercice_id_changed() {
$('#exercice_id_changed').val('1');
}
function confirm_your_choice() {
return confirm('$confirmYourChoice');
}
</script>
";
Display::display_header($nameTools,'Exercise');
// Menu
echo '<div class="actions">';
if (isset($type)) {
$url = api_get_self().'?type=1';
} else {
$url = api_get_self();
}
echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$fromExercise.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
if (isset($type)) {
$url = api_get_self().'?type=1';
} else {
$url = api_get_self();
}
if (isset($fromExercise) && $fromExercise > 0) {
echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$fromExercise.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
$titleAdd = get_lang('addQuestionToTest');
}
else {
echo '<a href="exercice.php?'.api_get_cidReq().'">'.Display::return_icon('back.png', get_lang('BackToExercisesList'),'','32').'</a>';
echo "<a href='admin.php?exerciceId=0'>".Display::return_icon('add_question.gif', get_lang('NewQu'), '', 32)."</a>";
$titleAdd = get_lang('manageAllQuestions');
}
echo '</div>';
if ($displayMessage != "") {
Display::display_confirmation_message($displayMessage);
$displayMessage = "";
}
//Title
echo '<h2>'.$nameTools.'</h2>';
echo '<h2>'.$nameTools.' - '.$titleAdd.'</h2>';
//Form
echo '<form name="question_pool" method="GET" action="'.$url.'">';
@ -261,70 +285,107 @@ if (isset($type)) {
}
echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
//Session list
// ----------------------------------------------------
// Session list, if sessions are used.
// ----------------------------------------------------
$session_list = SessionManager::get_sessions_by_coach(api_get_user_id());
// hub 13-10-2011
$tabAttrParam = array('class'=>'chzn-select', 'onchange'=>'submit_form(this)'); // when sessions are used
$labelFormRow = get_lang('Session');
if (api_get_setting('use_session_mode') == 'false') {
$tabAttrParam = array('style'=>'visibility:hidden', 'onchange'=>'submit_form(this)');
$labelFormRow = "";
}
$session_select_list = array();
foreach($session_list as $item) {
$session_select_list[$item['id']] = $item['name'];
$session_select_list[$item['id']] = $item['name'];
}
$select_session_html = Display::select('session_id', $session_select_list, $session_id, array('class'=>'chzn-select','onchange'=>'submit_form(this);'));
echo Display::form_row(get_lang('Session'), $select_session_html);
//Course list
if (!empty($session_id) && $session_id != '-1') {
$course_list = SessionManager::get_course_list_by_session_id($session_id);
} else {
$course_list = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
$select_session_html = Display::select('session_id', $session_select_list, $session_id, $tabAttrParam); // hub 13-10-2011
echo Display::form_row($labelFormRow, $select_session_html); // hub 13-10-2011
// -----------------------------------------------------------------------------
// Course list, get course list of session, or for course where user is admin
// -----------------------------------------------------------------------------
if (!empty($session_id) && $session_id != '-1') {
$course_list = SessionManager::get_course_list_by_session_id($session_id);
} else {
$course_list = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
}
$course_select_list = array();
foreach ($course_list as $item) {
$course_select_list[$item['id']] = $item['title'];
}
$course_select_list[$item['id']] = "";
if ($item['id'] == api_get_course_int_id()) {
$course_select_list[$item['id']] = ">&nbsp;&nbsp;&nbsp;&nbsp;";
}
$course_select_list[$item['id']] .= $item['title'];
}
$select_course_html = Display::select('selected_course', $course_select_list, $selected_course, array('class'=>'chzn-select','onchange'=>'submit_form(this);'));
$select_course_html = Display::select('selected_course', $course_select_list, $selected_course, array('class'=>'chzn-select','onchange'=>'mark_course_id_changed(); submit_form(this);'));
echo Display::form_row(get_lang('Course'), $select_course_html);
$db_name = "";
if (empty($selected_course) || $selected_course == '-1') {
$course_info = api_get_course_info();
} else {
$course_info = CourseManager::get_course_information_by_id($selected_course);
$course_info = api_get_course_info();
reset_menu_exo_lvl_type(); // no course selected, reset menu test / difficulté / type de reponse // hub 13-10-2011
}
else {
$course_info = CourseManager::get_course_information_by_id($selected_course);
}
// If course has changed, reset the menu default
if ($course_id_changed) {
reset_menu_exo_lvl_type();
}
$course_id = $course_info['real_id'];
//Redefining table calls
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
$TBL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY); // hub 13-10-2011
$TBL_COURSE_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY); // hub 13-10-2011
$exercise_list = get_all_exercises($course_info, $session_id);
// ---------------------------------------------
// Get course categories for the selected course
// ---------------------------------------------
// get category list for the course $selected_course
$tabCatList = Testcategory::getCategoriesIdAndName($selected_course);
$selectCourseCateogry = Display::select('courseCategoryId', $tabCatList, $courseCategoryId, array('class'=>'chzn-select','onchange'=>'submit_form(this);'), false);
echo Display::form_row(get_lang("QuestionCategory"), $selectCourseCateogry);
// ---------------------------------------------
// Get exercice list for this course
// ---------------------------------------------
$exercise_list = get_all_exercises_for_course_id($course_info, $session_id, $selected_course);
//Exercise List
$my_exercise_list = array();
$my_exercise_list['0'] = get_lang('AllExercises');
$my_exercise_list['-1'] = get_lang('OrphanQuestions');
if (is_array($exercise_list)) {
foreach($exercise_list as $row) {
if ($row['id'] != $fromExercise) {
$my_exercise_list[$row['id']] = $row['title'];
}
}
foreach($exercise_list as $row) {
$my_exercise_list[$row['id']] = "";
if ($row['id'] == $fromExercise && $selected_course == api_get_course_int_id()) {
$my_exercise_list[$row['id']] = ">&nbsp;&nbsp;&nbsp;&nbsp;"; // hub 13-10-2011
}
$my_exercise_list[$row['id']] .= $row['title'];
}
}
$select_exercise_html = Display::select('exerciseId', $my_exercise_list, $exerciseId, array('class'=>'chzn-select','onchange'=>'submit_form(this);'), false);
if ($exercice_id_changed == 1) {
reset_menu_lvl_type();
}
$select_exercise_html = Display::select('exerciseId', $my_exercise_list, $exerciseId, array('class'=>'chzn-select','onchange'=>'mark_exercice_id_changed(); submit_form(this);'), false);
echo Display::form_row(get_lang('Exercise'), $select_exercise_html);
//Difficulty list (only from 0 to 5)
// ---------------------------------------------
// Difficulty list (only from 0 to 5)
// ---------------------------------------------
$select_difficulty_html = Display::select('exerciseLevel', array(-1 => get_lang('All'), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5), $exerciseLevel, array('class'=>'chzn-select', 'onchange'=>'submit_form(this);'), false);
echo Display::form_row(get_lang('Difficulty'), $select_difficulty_html);
//Answer type
// ---------------------------------------------
// Answer type
// ---------------------------------------------
$question_list = Question::get_types_information();
$new_question_list = array();
$new_question_list['-1'] = get_lang('All');
@ -348,267 +409,323 @@ $select_answer_html = Display::select('answerType', $new_question_list, $answerT
echo Display::form_row(get_lang('AnswerType'), $select_answer_html);
$button = '<button class="save" type="submit" name="name" value="'.get_lang('Filter').'">'.get_lang('Filter').'</button>';
echo Display::form_row('', $button);
echo "<input type='hidden' id='course_id_changed' name='course_id_changed' value='0' />"; // hub 13-10-2011
echo "<input type='hidden' id='exercice_id_changed' name='exercice_id_changed' value='0' />"; // hub 13-10-2011
?>
</form>
<div class="clear"></div>
<form method="post" action="<?php echo $url.'?'.api_get_cidreq().'&fromExercise='.$fromExercise; ?>" >
<?php
echo '<input type="hidden" name="course_id" value="'.$selected_course.'">';
echo '<table class="data_table">';
$from = $page * $limitQuestPage;
$show_pagination = true;
// --------------------------------------------------------
// if we have selected an exercise in the list-box 'Filter'
// --------------------------------------------------------
if ($exerciseId > 0) {
//Specific exercise
$where = '';
if (isset($type) && $type==1) {
$where = ' type = 1 AND ';
$from = '';
if (isset($courseCategoryId) && $courseCategoryId > 0) {
$from = ", $TBL_COURSE_REL_CATEGORY crc ";
$where .= " AND crc.c_id=$selected_course AND crc.question_id=qu.id AND crc.category_id=$courseCategoryId";
}
if (isset($exerciseLevel) && $exerciseLevel != -1) {
$where .= ' level='.$exerciseLevel.' AND ';
$where .= ' AND level='.$exerciseLevel;
}
if (isset($answerType) && $answerType != -1) {
$where .= ' type='.$answerType.' AND ';
}
$sql = "SELECT id, question, type, level
FROM $TBL_EXERCICE_QUESTION eq, $TBL_QUESTIONS q
WHERE $where question_id=id AND exercice_id='".$exerciseId."' AND eq.c_id = $course_id AND q.c_id = $course_id
ORDER BY question_order";
$result=Database::query($sql);
while($row = Database::fetch_array($result, 'ASSOC')) {
$main_question_list[] = $row;
}
} elseif($exerciseId == -1) {
//Orphan
$type_where= '';
if (isset($type) && $type==1) {
$type_where = ' AND questions.type = 1 ';
$where .= ' AND type='.$answerType;
}
$sql = "SELECT DISTINCT id,question,type,level FROM $TBL_EXERCICE_QUESTION qt,$TBL_QUESTIONS qu $from WHERE qt.question_id=qu.id AND qt.exercice_id=$exerciseId AND qt.c_id=$selected_course AND qu.c_id=$selected_course $where ORDER BY question_order";
$result=Database::query($sql);
while($row = Database::fetch_array($result, 'ASSOC')) {
$main_question_list[] = $row;
}
}
elseif ($exerciseId == -1) {
// ---------------------------------------------------------------------------
// if we have selected the option 'Orphan questions' in the list-box 'Filter'
// ---------------------------------------------------------------------------
$level_where = '';
$from = '';
if (isset($courseCategoryId) && $courseCategoryId > 0) {
$from = ", $TBL_COURSE_REL_CATEGORY crc ";
$level_where .= " AND crc.c_id=$selected_course AND crc.question_id=qu.id AND crc.category_id=$courseCategoryId";
}
if (isset($exerciseLevel) && $exerciseLevel!= -1 ) {
$level_where = ' level='.$exerciseLevel.' AND ';
$level_where = ' AND level='.$exerciseLevel;
}
$answer_where = '';
if (isset($answerType) && $answerType != -1 ) {
$answer_where = ' questions.type='.$answerType.' AND ';
$answer_where = ' AND type='.$answerType;
}
$sql = 'SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id , level, session_id
FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions
ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.' as exercices
ON exercice_id=exercices.id
WHERE '.$answer_where.' '.$level_where.' (quizz_questions.exercice_id IS NULL OR exercices.active = -1 ) '.$type_where.' AND
questions.c_id = '.$course_id.'
LIMIT '.$from.', '.($limitQuestPage + 1);
$result = Database::query($sql);
while($row = Database::fetch_array($result, 'ASSOC')) {
$main_question_list[] = $row;
}
} else {
//All tests
$show_pagination = false;
$sql = "SELECT DISTINCT * FROM `chamilo19_main`.`c_quiz_question` AS qu $from WHERE qu.c_id=$selected_course AND qu.id NOT IN (SELECT question_id FROM `chamilo19_main`.`c_quiz_rel_question` WHERE c_id=$selected_course ) $level_where $answer_where";
$result = Database::query($sql);
while($row = Database::fetch_array($result, 'ASSOC')) {
$main_question_list[] = $row;
}
}
else {
// ---------------------------------
// All tests for selected course
// ---------------------------------
// if we have not selected any option in the list-box 'Filter'
$filter = '';
if (isset($type) && $type==1){
$filter .= ' AND qu.type = 1 ';
}
$from = '';
if (isset($courseCategoryId) && $courseCategoryId > 0) {
$from = ", $TBL_COURSE_REL_CATEGORY crc ";
$filter .= " AND crc.c_id=$selected_course AND crc.question_id=qu.id AND crc.category_id=$courseCategoryId";
}
if (isset($exerciseLevel) && $exerciseLevel != -1) {
$filter .= ' AND level='.$exerciseLevel.' ';
}
if (isset($answerType) && $answerType != -1) {
$filter .= ' AND qu.type='.$answerType.' ';
}
if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
$filter .= ' AND qu.type <> '.HOT_SPOT_DELINEATION.' ';
}
$new_limit_page = $limitQuestPage + 1;
if (!empty($session_id) && $session_id != '-1') {
$main_question_list = array();
if (!empty($course_list))
foreach ($course_list as $course_item) {
if (!empty($selected_course) && $selected_course != '-1') {
if ($selected_course != $course_item['id']) {
}
// // why these lines ?
// if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
// $filter .= ' AND qu.type <> '.HOT_SPOT_DELINEATION.' ';
// }
// // fwhy
// --------------------
// if in session
// --------------------
if (!empty($session_id) && $session_id != '-1') {
$main_question_list = array();
if (!empty($course_list))
foreach ($course_list as $course_item) {
if (!empty($selected_course) && $selected_course != '-1') {
if ($selected_course != $course_item['id']) {
continue;
}
}
$exercise_list = get_all_exercises($course_item, $session_id);
if (!empty($exercise_list)) {
foreach ($exercise_list as $exercise) {
$my_exercise = new Exercise($course_item['id']);
$my_exercise->read($exercise['id']);
if (!empty($my_exercise)) {
if (!empty($my_exercise->questionList)) {
foreach ($my_exercise->questionList as $question_id) {
$question_obj = Question::read($question_id, $course_item['id']);
if ($exerciseLevel != '-1')
if ($exerciseLevel != $question_obj->level) {
continue;
}
}
$exercise_list = get_all_exercises($course_item, $session_id);
if (!empty($exercise_list)) {
foreach ($exercise_list as $exercise) {
$my_exercise = new Exercise($course_item['id']);
$my_exercise->read($exercise['id']);
if (!empty($my_exercise)) {
if (!empty($my_exercise->questionList)) {
foreach ($my_exercise->questionList as $question_id) {
$question_obj = Question::read($question_id, $course_item['id']);
if ($exerciseLevel != '-1')
if ($exerciseLevel != $question_obj->level) {
continue;
}
if ($answerType != '-1')
if ($answerType != $question_obj->type) {
continue;
}
if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
if ($question_obj->type == HOT_SPOT_DELINEATION) {
continue;
}
}
$question_row = array( 'id' => $question_obj->id,
'question' => $question_obj->question,
'type' => $question_obj->type,
'level' => $question_obj->level,
'exercise_id' => $exercise['id'],
'course_id' => $course_item['id'],
);
$main_question_list[] = $question_row;
}
}
}
if ($answerType != '-1')
if ($answerType != $question_obj->type) {
continue;
}
}
}
} else {
//By default
$sql = "SELECT qu.id, question, qu.type, level, q.session_id
FROM $TBL_QUESTIONS as qu, $TBL_EXERCICE_QUESTION as qt, $TBL_EXERCICES as q
WHERE qu.c_id = $course_id AND
qu.c_id = $course_id AND
q.id=qt.exercice_id AND
qu.id=qt.question_id AND
qt.exercice_id <> ".$fromExercise." $filter
ORDER BY session_id ASC
LIMIT $from, $new_limit_page";
$result = Database::query($sql);
while($row = Database::fetch_array($result, 'ASSOC')) {
$main_question_list[] = $row;
}
}
// hub 23-10-2011
if ($courseCategoryId > 0 && Testcategory::getCategoryForQuestion($question_obj->id, $selected_course)) {
continue;
}
if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
if ($question_obj->type == HOT_SPOT_DELINEATION) {
continue;
}
}
$question_row = array( 'id' => $question_obj->id,
'question' => $question_obj->question,
'type' => $question_obj->type,
'level' => $question_obj->level,
'exercise_id' => $exercise['id'],
'course_id' => $course_item['id'],
);
$main_question_list[] = $question_row;
}
}
}
}
}
}
}
else {
// ------------------------------------------------------------
// All tests for the course selected, not in session
// ------------------------------------------------------------
$sql = "SELECT DISTINCT qu.id, question, qu.type, level, q.session_id FROM $TBL_QUESTIONS as qu, $TBL_EXERCICE_QUESTION as qt, $TBL_EXERCICES as q $from WHERE qu.c_id=$selected_course AND qt.c_id=$selected_course AND q.c_id=$selected_course AND qu.id = qt.question_id AND q.id = qt.exercice_id $filter ORDER BY session_id ASC";
$result = Database::query($sql);
while($row = Database::fetch_array($result, 'ASSOC')) {
$main_question_list[] = $row;
}
}
// forces the value to 0
$exerciseId=0;
}
$nbrQuestions = count($main_question_list);
if ($show_pagination) {
echo '<tr>',
'<td colspan="',($fromExercise?4:4),'">',
'<table border="0" cellpadding="0" cellspacing="0" width="100%">',
'<tr><td align="right">';
if(!empty($page)) {
echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&fromExercise=',$fromExercise,'&page=',($page-1),'&session_id='.$session_id.'&selected_course='.$selected_course.'&answerType=',$answerType,'&exerciseLevel='.$exerciseLevel.'">';
echo Display::return_icon('action_prev.png');
echo '&nbsp;';
} elseif($nbrQuestions > $limitQuestPage) {
echo Display::return_icon('action_prev_na.png');
echo '&nbsp;';
// ------------------------------------------------
// build the line of the array to display questions
// Actions are different if you launch the question_pool page
// They are different too if you have displayed questions from your course
// Or from another course you are the admin(or session admin)
// from a test or not
/*
+--------------------------------------------+--------------------------------------------+
| NOT IN A TEST | IN A TEST |
+----------------------+---------------------+---------------------+----------------------+
|IN THE COURSE (*) "x | NOT IN THE COURSE o | IN THE COURSE + | NOT IN THE COURSE o |
+----------------------+---------------------+---------------------+----------------------+
|Edit the question | Do nothing | Add question to test|Clone question in test|
|Delete the question | | | |
|(true delete) | | | |
+----------------------+---------------------+---------------------+----------------------+
(*) this is the only way to delete or modify orphan questions
*/
// ----------------------------------------------------------------------------------------
if ($fromExercise <= 0) { // NOT IN A TEST - IN THE COURSE
if ($selected_course == api_get_course_int_id()) {
$actionLabel = get_lang('Action');
$actionIcon1 = "edit";
$actionIcon2 = "delete";
$questionTagA = 1; // we are in the course, question title can be a link to the question edit page
}
if($nbrQuestions > $limitQuestPage) {
echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&fromExercise=',$fromExercise,'&page=',($page+1),'&session_id='.$session_id.'&selected_course='.$selected_course.'&answerType=',$answerType,'&exerciseLevel='.$exerciseLevel.'">';
echo Display::return_icon('action_next.png');
echo '</a>';
} elseif($page) {
echo Display::return_icon('action_next_na.png');
echo '&nbsp;';
else { // NOT IN A TEST - NOT IN THE COURSE
$actionLabel = get_lang('Reuse');
$actionIcon1 = get_lang('mustBeInATest');
$actionIcon2 = "";
$questionTagA = 0; // we are not in this course, to messy if we link to the question in another course
}
echo '</td>
</tr>
</table>
</td>
</tr>';
}
echo '<tr>';
if (!empty($fromExercise)) {
if (api_get_session_id() == 0 ){
echo '<th width="4%"> </th>';
else { // IN A TEST - IN THE COURSE
if ($selected_course == api_get_course_int_id()) {
$actionLabel = get_lang('Reuse');
$actionIcon1 = "add";
$actionIcon2 = "";
$questionTagA = 1;
}
echo '<th>',get_lang('Question'),'</th>',
'<th>',get_lang('Difficulty'),'</th>',
'<th>',get_lang('Reuse'),'</th>';
} else {
echo '<td width="60%" align="center">',get_lang('Question'),'</td>',
'<td width="20%" align="center">',get_lang('Modify'),'</td>',
'<td width="16%" align="center">',get_lang('Delete'),'</td>';
}
echo '</tr>';
$i=1;
$session_id = api_get_session_id();
if (!empty($main_question_list))
foreach ($main_question_list as $row) {
$my_course_id = 0;
if (isset($row['course_id'])) {
$my_course_id = $row['course_id'];
else { // IN A TEST - NOT IN THE COURSE
$actionLabel = get_lang('Reuse');
$actionIcon1 = "clone";
$actionIcon2 = "";
$questionTagA = 0;
}
}
// -------------------
// display table
// -------------------
$header = array();
$header[] = array(get_lang('Question'), false, array("style"=>"text-align:center"));
$header[] = array(get_lang('Type'), false, array("style"=>"text-align:center"), array("style"=>"text-align:center"));
$header[] = array(get_lang('QuestionCategory'), false, array("style"=>"text-align:center"), array("style"=>"text-align:center"));
$header[] = array(get_lang('Difficulty'), false, array("style"=>"text-align:center"), array("style"=>"text-align:center"));
$header[] = array($actionLabel, false, array("style"=>"text-align:center"), array("style"=>"text-align:center"));
$data = array();
foreach ($main_question_list as $tabQuestion) {
$row = array();
$row[] = get_a_tag_for_question($questionTagA, $fromExercise, $tabQuestion['id'], $tabQuestion['type'], $tabQuestion['question']);
$row[] = get_question_type_for_question($selected_course, $tabQuestion['id']);
$row[] = get_question_categorie_for_question($selected_course, $tabQuestion['id']);
$row[] = $tabQuestion['level'];
$row[] = get_action_icon_for_question($actionIcon1, $fromExercise, $tabQuestion['id'], $tabQuestion['type'], $tabQuestion['question'], $selected_course, $courseCategoryId, $exerciseId, $exerciseLevel, $answerType, $session_id)."&nbsp;".get_action_icon_for_question($actionIcon2, $fromExercise, $tabQuestion['id'], $tabQuestion['type'], $tabQuestion['question'], $selected_course, $courseCategoryId, $exercice_id, $exerciseLevel, $answerType, $session_id);
$data[] = $row;
}
Display :: display_sortable_table($header, $data, array(), array('per_page_default'=>999,'per_page'=>999,'page_nr'=>1));
// if we come from the exercise administration to get a question,
// don't show the questions already used by that exercise
if (!$nbrQuestions) {
echo get_lang('NoQuestion');
}
// original recipe -
//if (!$fromExercise || !isset($objExercise) || !($objExercise instanceOf Exercise) || (!$objExercise->isInList($row['id'])))
if (!$fromExercise || !isset($objExercise) || !($objExercise instanceOf Exercise) || (is_array($objExercise->questionList)) ) {
echo '<tr ',($i%2==0?'class="row_odd"':'class="row_even"'),'>';
if (api_get_session_id() == 0 ){
echo '<td align="center"> <input type="checkbox" value="'.$row['id'].'" name="recup['.$my_course_id.'][]"/></td>';
}
echo ' <td><a href="admin.php?',api_get_cidreq(),'&editQuestion=',$row['id'],'&fromExercise='.$fromExercise.'&answerType='.$row['type'].'">',$row['question'],'</a></td>';
echo ' <td align="center" >';
if (empty($fromExercise)) {
echo '<a href="admin.php?'.api_get_cidreq().'&amp;editQuestion=',$row['id'],'"><img src="../img/edit.gif" border="0" alt="',get_lang('Modify'),'"></a>',
'</td>',
'<td align="center">',
'<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&delete=',$row['id'],'" onclick="javascript:if(!confirm(\'',addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)),'\')) return false;"><img src="../img/delete.gif" border="0" alt="',get_lang('Delete'),'"></a>';
//'<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&delete=',$row['id'],'" onclick="javascript:if(!confirm(\'',addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)),'\')) return false;"><img src="../img/delete.gif" border="0" alt="',get_lang('Delete'),'"></a>';
} else {
echo $row['level'],'</td>',
'<td align="center">';
echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;copy_question='.$row['id'].'&course_id='.$my_course_id.'&fromExercise=',$fromExercise,'">';
echo ' '.Display::return_icon('cd.gif', get_lang('ReUseACopyInCurrentTest'));
echo '</a> ';
if ($row['session_id'] == $session_id) {
if ($selected_course == api_get_course_int_id()) {
//echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&recup=',$row['id'],'&fromExercise=',$fromExercise,'"><img src="../img/view_more_stats.gif" border="0" title="'.get_lang('InsertALinkToThisQuestionInTheExercise').'" alt="'.get_lang('InsertALinkToThisQuestionInTheExercise').'"></a>';
}
}
}
echo '</td>';
echo '</tr>';
if (api_get_session_id() == 0 ){
echo '<div style="width:100%; border-top:1px dotted #4171B5;"><button class="save" type="submit">'.get_lang('Reuse').'</button></div></form>';
}
Display::display_footer();
// skips the last question, that is only used to know if we have or not to create a link "Next page"
if($i == $limitQuestPage) {
break;
}
$i++;
// =========================================================================
// Some functions here, just for question_pool to ease the code
// =========================================================================
/*
Put the menu entry for level and type to default "Choice"
It is usefull if you change the exercice, you need to reset the other menus
hubert.borderiou 13-10-2011
*/
function reset_menu_lvl_type() {
global $exerciseLevel, $answerType;
$answerType = -1;
$exerciseLevel = -1;
}
/*
Put the menu entry for exercice and level and type to default "Choice"
It is usefull if you change the course, you need to reset the other menus
hubert.borderiou 13-10-2011
*/
function reset_menu_exo_lvl_type() {
global $exerciseId, $courseCategoryId;
reset_menu_lvl_type();
$exerciseId = 0;
$courseCategoryId = 0;
}
//
// return the <a> link to admin question, if needed
// hubert.borderiou 13-10-2011
function get_a_tag_for_question($in_addA, $in_fromex, $in_questionid, $in_questiontype, $in_questionname) {
$res = $in_questionname;
if ($in_addA) {
$res = "<a href='admin.php?".api_get_cidreq()."&editQuestion=$in_questionid&type=$in_questiontype&fromExercise=$in_fromex'>".$res."</a>";
}
return $res;
}
if (!$nbrQuestions) {
echo '<tr>',
'<td colspan="',($fromExercise?4:4),'">',get_lang('NoQuestion'),'</td>',
'</tr>';
//
// return the <a> html code for delete, add, clone, edit a question
// hubert.borderiou 13-10-2011
function get_action_icon_for_question($in_action, $from_exercice, $in_questionid, $in_questiontype, $in_questionname, $in_selected_course, $in_courseCategoryId, $in_exercise_id, $in_exerciseLevel, $in_answerType, $in_session_id) {
$res = "";
$getParams = "&selected_course=$in_selected_course&courseCategoryId=$in_courseCategoryId&exerciseId=$in_exercise_id&exerciseLevel=$in_exerciseLevel&answerType=$in_answerType&session_id=$in_session_id";
switch ($in_action) {
case "delete" :
$res = "<a href='".api_get_self()."?".api_get_cidreq()."&exerciseId=$from_exercice&delete=$in_questionid$getParams' onclick='return confirm_your_choice()'>";
$res .= Display::return_icon("delete.gif", get_lang('Delete'));
$res .= "</a>";
break;
case "edit" :
$res = get_a_tag_for_question(1, $from_exercice, $in_questionid, $in_questiontype, Display::return_icon("edit.gif", get_lang('Modify')));
break;
case "add":
// add if question is not already in test
$myObjEx = new Exercise();
$myObjEx->read($from_exercice);
if (!$myObjEx->isInList($in_questionid)) {
$res = "<a href='".api_get_self()."?".api_get_cidreq()."&recup=$in_questionid&fromExercise=$from_exercice$getParams'>";
$res .= Display::return_icon("view_more_stats.gif", get_lang('InsertALinkToThisQuestionInTheExercise'));
$res .= "</a>";
}
else {
$res = "-";
}
unset($myObjEx);
break;
case "clone":
$res = "<a href='".api_get_self()."?".api_get_cidreq()."&amp;copy_question=$in_questionid&course_id=$in_selected_course&fromExercise=$from_exercice$getParams'>";
$res .= Display::return_icon('cd.gif', get_lang('ReUseACopyInCurrentTest'));
$res .= "</a>";
break;
default :
$res = $in_action;
break;
}
return $res;
}
echo '</table>';
if (api_get_session_id() == 0 ){
echo '<div style="width:100%; border-top:1px dotted #4171B5;">
<button class="save" type="submit">'.get_lang('Reuse').'</button>
</div></form>';
//
// return the icon for the question type
// hubert.borderiou 13-10-2011
function get_question_type_for_question($in_selectedcourse, $in_questionid) {
$myObjQuestion = Question::read($in_questionid, $in_selectedcourse);
list($typeImg, $typeExpl) = $myObjQuestion->get_type_icon_html();
$questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), 32), array());
unset($myObjQuestion);
return $questionType;
}
Display::display_footer();
//
// return the name of the category for the question in a course
// hubert.borderiou 13-10-2011
function get_question_categorie_for_question($in_courseid, $in_questionid) {
$cat = Testcategory::getCategoryNameForQuestion($in_questionid, $in_courseid);
return $cat;
}

@ -0,0 +1,421 @@
<?php
// $Id: testcategory.class.php 2010-12-06 hubert.borderiou
if(!class_exists('Testcategory')):
class Testcategory {
public $id;
public $name;
public $description;
/**
* Constructor of the class Category
* @author - Hubert Borderiou
If you give an in_id and no in_name, you get info concerning the category of id=in_id
otherwise, you've got an category objet avec your in_id, in_name, in_descr
*/
function Testcategory($in_id=0, $in_name, $in_description="") {
if ($in_id != 0 && $in_name == "") {
$tmpobj = new Testcategory();
$tmpobj->getCategory($in_id);
$this->id = $tmpobj->id;
$this->name = $tmpobj->name;
$this->description = $tmpobj->description;
}
else {
$this->id = $in_id;
$this->name = $in_name;
$this->description = $in_description;
}
}
/** return the Testcategory object with id=in_id
*/
function getCategory($in_id) {
$t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$in_id = Database::escape_string($in_id);
$sql = "SELECT * FROM $t_cattable WHERE id=$in_id AND c_id=".api_get_course_int_id();
$res = Database::query($sql);
$numrows = Database::num_rows($res);
if ($numrows > 0) {
$row = Database::fetch_array($res);
$this->id = $row['id'];
$this->name = $row['name'];
$this->description = $row['description'];
}
}
/** add Testcategory in the database if name doesn't already exists
*/
function addCategoryInBDD() {
$t_cattable = Database :: get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$v_name = $this->name;
$v_name = Database::escape_string($v_name);
$v_description = $this->description;
$v_description = Database::escape_string($v_description);
// check if name already exists
$sql_verif = "SELECT count(*) AS nb FROM $t_cattable WHERE name = '$v_name' AND c_id=".api_get_course_int_id();
$result_verif = Database::query($sql_verif, __FILE__, __LINE__);
$data_verif = Database::fetch_array($result_verif);
// lets add in BDD if not the same name
if ($data_verif['nb'] <= 0) {
$c_id = api_get_course_int_id();
$sql = "INSERT INTO $t_cattable VALUES ('$c_id', '', '$v_name', '$v_description')";
$res = Database::query($sql, __FILE__, __LINE__);
return true;
}
else {
return false;
}
}
/** remove catagory with id=in_id from the database if no question use this category
*/
function removeCategory($in_id) {
$t_cattable = Database :: get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$v_id = Database::escape_string($this->id);
$sql = "DELETE FROM $t_cattable WHERE id=$v_id AND c_id=".api_get_course_int_id();
$res = Database::query($sql);
if (Database::affected_rows() <= 0) {
return false;
}
else {
return true;
}
}
/** modify category name or description of category with id=in_id
*/
function modifyCategory($in_id, $in_name, $in_description) {
$t_cattable = Database :: get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$v_id = Database::escape_string($this->id);
$v_name = Database::escape_string($this->name);
$v_description = Database::escape_string($this->description);
$sql = "UPDATE $t_cattable SET name='$v_name', description='$v_description' WHERE id='$v_id' AND c_id=".api_get_course_int_id();
$res = Database::query($sql);
if (Database::affected_rows() <= 0) {
return false;
}
else {
return true;
}
}
/** get number of question of category id=in_id
*/
function getCategoryQuestionsNumber($in_id) {
$t_reltable = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$in_id = Database::escape_string($this->id);
$sql = "SELECT count(*) AS nb FROM $t_reltable WHERE category_id=$in_id AND c_id=".api_get_course_int_id();
$res = Database::query($sql, __FILE__, __LINE__);
$row = Database::fetch_array($res);
return $row['nb'];
}
function display($in_color="#E0EBF5") {
echo "<textarea style='background-color:$in_color; width:60%; height:100px;'>";
print_r($this);
echo "</textarea>";
}
/** return an array of all Category objects in the database
If in_field=="" Return an array of all category objects in the database
Otherwise, return an array of all in_field value in the database (in_field = id or name or description)
*/
public function getCategoryListInfo($in_field="", $in_courseid="") {
if (empty($in_courseid) || $in_courseid=="") {
$in_courseid = api_get_course_int_id();
}
$t_cattable = Database :: get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$in_field = Database::escape_string($in_field);
$tabres = array();
if ($in_field=="") {
$sql = "SELECT * FROM $t_cattable WHERE c_id=$in_courseid ORDER BY name ASC";
$res = Database::query($sql);
while ($row = Database::fetch_array($res)) {
$tmpcat = new Testcategory($row['id'], $row['name'], $row['description']);
$tabres[] = $tmpcat;
}
}
else {
$sql = "SELECT $in_field FROM $t_cattable WHERE c_id=$in_courseid ORDER BY $in_field ASC";
$res = Database::query($sql);
while ($row = Database::fetch_array($res)) {
$tabres[] = $row[$in_field];
}
}
return $tabres;
}
/**
Return the testcategory id for question with question_id = $in_questionid
In this version, a question has only 1 testcategory.
Return the testcategory id, 0 if none
*/
public static function getCategoryForQuestion($in_questionid, $in_courseid="") {
$result = 0; // result
if (empty($in_courseid) || $in_courseid=="") {
$in_courseid = api_get_course_int_id();
}
$t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$question_id = Database::escape_string($in_questionid);
$sql = "SELECT category_id FROM $t_cattable WHERE question_id='$question_id' AND c_id=$in_courseid";
$res = Database::query($sql);
$data = Database::fetch_array($res);
if (Database::num_rows($res) > 0) {
$result = $data['category_id'];
}
return $result;
}
/**
* true if question id has a category
*/
public static function isQuestionHasCategory($in_questionid) {
if (Testcategory::getCategoryForQuestion($in_questionid) > 0) {
return true;
}
return false;
}
/**
Return the category name for question with question_id = $in_questionid
In this version, a question has only 1 category.
Return the category id, "" if none
*/
function getCategoryNameForQuestion($in_questionid, $in_courseid="") {
if (empty($in_courseid) || $in_courseid=="") {
$in_courseid = api_get_course_int_id();
}
$catid = Testcategory::getCategoryForQuestion($in_questionid, $in_courseid);
$result = ""; // result
$t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$catid = Database::escape_string($catid);
$sql = "SELECT name FROM $t_cattable WHERE id='$catid' AND c_id=$in_courseid";
$res = Database::query($sql);
$data = Database::fetch_array($res);
if (Database::num_rows($res) > 0) {
$result = $data['name'];
}
return $result;
}
/**
* return the list of differents categories ID for a test
* input : test_id
* return : array of category id (integer)
* hubert.borderiou 07-04-2011
*/
public static function getListOfCategoriesIDForTest($in_testid) {
// parcourir les questions d'un test, recup les categories uniques dans un tableau
$tabcat = array();
$quiz = new Exercise();
$quiz->read($in_testid);
$tabQuestionList = $quiz->selectQuestionList();
for ($i=0; $i < count($tabQuestionList); $i++) {
if (!in_array(Testcategory::getCategoryForQuestion($tabQuestionList[$i]), $tabcat)) {
$tabcat[] = Testcategory::getCategoryForQuestion($tabQuestionList[$i]);
}
}
return $tabcat;
}
/**
* return the list of differents categories NAME for a test
* input : test_id
* return : array of string
* hubert.borderiou 07-04-2011
*/
public static function getListOfCategoriesNameForTest($in_testid) {
$tabcatName = array();
$tabcatID = getListOfCategoriesNameForTest($in_testid);
for ($i=0; $i < count($tabcatID); $i++) {
$cat = new Testcategory($tabcatID[$i]);
$tabcatName[] = $cat->name;
}
return $tabcatName;
}
/**
* return the number of differents categories for a test
* input : test_id
* return : integer
* hubert.borderiou 07-04-2011
*/
public static function getNumberOfCategoriesForTest($in_testid) {
return count(Testcategory::getListOfCategoriesIDForTest($in_testid));
}
/**
* return the number of question of a category id in a test
* input : test_id, category_id
* return : integer
* hubert.borderiou 07-04-2011
*/
public static function getNumberOfQuestionsInCategoryForTest($in_testid, $in_categoryid) {
$nbCatResult = 0;
$quiz = new Exercise();
$quiz->read($in_testid);
$tabQuestionList = $quiz->selectQuestionList();
for ($i=0; $i < count($tabQuestionList); $i++) {
if (Testcategory::getCategoryForQuestion($tabQuestionList[$i]) == $in_categoryid) {
$nbCatResult++;
}
}
return $nbCatResult;
}
/**
* return the number of question for a test using random by category
* input : test_id, number of random question (min 1)
* hubert.borderiou 07-04-2011
* question witout categories are not counted
*/
public static function getNumberOfQuestionRandomByCategory($in_testid, $in_nbrandom) {
$nbquestionresult = 0;
$tabcatid = Testcategory::getListOfCategoriesIDForTest($in_testid);
for ($i=0; $i < count($tabcatid); $i++) {
if ($tabcatid[$i] > 0) { // 0 = no category for this questio
$nbQuestionInThisCat = Testcategory::getNumberOfQuestionsInCategoryForTest($in_testid, $tabcatid[$i]);
if ($nbQuestionInThisCat > $in_nbrandom) {
$nbquestionresult += $in_nbrandom;
}
else {
$nbquestionresult += $nbQuestionInThisCat;
}
}
}
return $nbquestionresult;
}
/**
* Return an array (id=>name)
* tabresult[0] = get_lang('NoCategory');
*
*/
function getCategoriesIdAndName($in_courseid="") {
if (empty($in_courseid) || $in_courseid=="") {
$in_courseid = api_get_course_int_id();
}
$tabcatobject = Testcategory::getCategoryListInfo("", $in_courseid);
$tabresult = array("0"=>get_lang('NoCategory'));
for ($i=0; $i < count($tabcatobject); $i++) {
$tabresult[$tabcatobject[$i]->id] = $tabcatobject[$i]->name;
}
return $tabresult;
}
/**
* return an array of question_id for each category
* tabres[0] = array of question id with category id = 0 (i.e. no category)
* tabres[24] = array of question id with category id = 24
* In this version, a question has 0 or 1 category
*/
function getQuestionsByCat($in_exerciceId) {
$tabres = array();
$TBL_EXERCICE = Database::get_course_table(TABLE_QUIZ_TEST);
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTION_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$sql = "SELECT qrc.question_id, qrc.category_id FROM $TBL_QUESTION_REL_CATEGORY qrc, $TBL_EXERCICE_QUESTION eq WHERE exercice_id=$in_exerciceId AND eq.question_id=qrc.question_id AND eq.c_id=".api_get_course_int_id()." AND eq.c_id=qrc.c_id ORDER BY category_id, question_id";
$res = Database::query($sql);
while ($data = Database::fetch_array($res)) {
if (!is_array($tabres[$data['category_id']])) {
$tabres[$data['category_id']] = array();
}
$tabres[$data['category_id']][] = $data['question_id'];
}
return $tabres;
}
/**
* return a tab of $in_number random elements of $in_tab
*/
function getNElementsFromArray($in_tab, $in_number) {
$tabres = $in_tab;
shuffle($tabres);
if ($in_number < count($tabres)) {
$tabres = array_slice($tabres, 0, $in_number);
}
return $tabres;
}
/**
* display the category
*/
function displayCategoryAndTitle($in_questionID) {
if (Testcategory::getCategoryNameForQuestion($in_questionID) != "") {
echo "<div id=\"question_title\" class=\"sectiontitle\" style='font-size:110%; margin-top:20px; padding-top:10px'>";
echo "<div style='font-size:110%;font-weight:normal; margin-bottom:5px; padding:0px 10px 5px 10px;'>";
echo get_lang('Category').": ".Testcategory::getCategoryNameForQuestion($in_questionID);
echo "</div>";
echo "</div>";
}
}
/**
* Display signs [+] and/or (>0) after question title if question has options
* scoreAlwaysPositive and/or uncheckedMayScore
*/
function displayQuestionOption($in_objQuestion) {
if ($in_objQuestion->type == MULTIPLE_ANSWER && $in_objQuestion->scoreAlwaysPositive) {
echo "<span style='font-size:75%'> (>0)</span>";
}
if ($in_objQuestion->type == MULTIPLE_ANSWER && $in_objQuestion->uncheckedMayScore) {
echo "<span style='font-size:75%'> [+]</span>";
}
}
/**
* sortTabByBracketLabel ($tabCategoryQuestions)
* key of $tabCategoryQuestions are the categopy id (0 for not in a category)
* value is the array of question id of this category
* Sort question by Category
*/
function sortTabByBracketLabel($in_tab) {
$tabResult = array();
$tabCatName = array(); // tab of category name
while (list($cat_id, $tabquestion) = each($in_tab)) {
$catTitle = new Testcategory($cat_id);
$tabCatName[$cat_id] = $catTitle->name;
}
reset($in_tab);
// sort table by value, keeping keys as they are
asort($tabCatName);
// keys of $tabCatName are keys order for $in_tab
while (list($key, $val) = each($tabCatName)) {
$tabResult[$key] = $in_tab[$key];
}
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_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$tbl_question_rel_category = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$query = "SELECT DISTINCT marks, exe_id, user_id, ta.question_id, category_id FROM $tbl_track_attempt ta , $tbl_question_rel_category qrc WHERE ta.question_id=qrc.question_id AND qrc.category_id=$in_cat_id AND exe_id=$in_exe_id AND user_id=$in_user_id";
$res = Database::query($query);
$totalcatscore = "";
while ($data = Database::fetch_array($res)) {
$totalcatscore += $data['marks'];
}
return $totalcatscore;
}
}
endif;
?>

@ -0,0 +1,274 @@
<?php
/**
hubert.borderiou
Manage tests category page
*/
$htmlHeadXtra[] = '
<script type="text/javascript">
function confirmDelete(in_txt, in_id) {
var oldbgcolor = document.getElementById(in_id).style.backgroundColor;
document.getElementById(in_id).style.backgroundColor="#AAFFB0";
if (confirm(in_txt)) {
return true;
}
else {
document.getElementById(in_id).style.backgroundColor = oldbgcolor;
return false;
}
}
</script>
';
// name of the language file that needs to be included
$language_file='exercice';
$nameTools= "";
include('question.class.php');
include('testcategory.class.php');
include('../inc/global.inc.php');
include('exercise.lib.php');
require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
$this_section=SECTION_COURSES;
if(!api_is_allowed_to_edit()) {
api_not_allowed(true);
}
// breadcrumbs
$interbreadcrumb[]=array("url" => "exercice.php","name" => get_lang('Exercices'));
Display::display_header(get_lang('Category'));
// Action handling: add, edit and remove
if (isset($_GET['action']) && $_GET['action'] == 'addcategory')
{
add_category_form(Security::remove_XSS($_GET['action']));
}
else if (isset($_GET['action']) && $_GET['action'] == 'editcategory') {
edit_category_form(Security::remove_XSS($_GET['action']));
}
else if (isset($_GET['action']) && $_GET['action'] == 'deletecategory') {
delete_category_form(Security::remove_XSS($_GET['action']));
}
else {
display_add_category();
display_categories();
}
Display::display_footer();
// **********************************************************************************
// ****** FUNCTIONS ********************
// **********************************************************************************
// ------------------------------------------------------------------------
// form to edit a category
// ------------------------------------------------------------------------
function edit_category_form($in_action) {
if (isset($_GET['category_id']) && is_numeric($_GET['category_id'])) {
$category_id = Security::remove_XSS($_GET['category_id']);
$objcat = new Testcategory($category_id);
// --------------------
// initiate the object
// --------------------
$form = new FormValidator('note','post', api_get_self().'?action='.$in_action.'&category_id='.$category_id);
// --------------------
// settting the form elements
// --------------------
$form->addElement('header', '', get_lang('EditCategory'));
$form->addElement('hidden', 'category_id');
$form->addElement('text', 'category_name', get_lang('CategoryName'),array('size'=>'95'));
$form->addElement('html_editor', 'category_description', get_lang('CategoryDescription'), null, array('ToolbarSet' => 'test_category', 'Width' => '90%', 'Height' => '200'));
$form->addElement('style_submit_button', 'SubmitNote', get_lang('ModifyCategory'), 'class="add"');
// --------------------
// setting the defaults
// --------------------
$defaults = array();
$defaults["category_id"] = $objcat->id;
$defaults["category_name"] = $objcat->name;
$defaults["category_description"] = $objcat->description;
$form->setDefaults($defaults);
// --------------------
// setting the rules
// --------------------
$form->addRule('category_name', '<div class="required">'.get_lang('ThisFieldIsRequired'), 'required');
// --------------------
// The validation or display
// --------------------
if ($form->validate())
{
$check = Security::check_token('post');
if ($check) {
$values = $form->exportValues();
$v_id = Security::remove_XSS($values['category_id']);
$v_name = Security::remove_XSS($values['category_name'], COURSEMANAGER);
$v_description = Security::remove_XSS($values['category_description'], COURSEMANAGER);
$objcat = new Testcategory($v_id, $v_name, $v_description);
if ($objcat->modifyCategory()) {
Display::display_confirmation_message(get_lang('MofidfyCategoryDone'));
}
else {
Display::display_confirmation_message(get_lang('ModifyCategoryError'));
}
}
Security::clear_token();
display_add_category();
display_categories();
}
else
{
display_goback();
$token = Security::get_token();
$form->addElement('hidden','sec_token');
$form->setConstants(array('sec_token' => $token));
$form->display();
display_categories();
}
}
else {
Display::display_error_message(get_lang('CannotEditCategory'));
}
}
// ------------------------------------------------------------------------
// process to delete a category
// ------------------------------------------------------------------------
function delete_category_form($in_action) {
if (isset($_GET['category_id']) && is_numeric($_GET['category_id'])) {
$category_id = Security::remove_XSS($_GET['category_id']);
$catobject = new Testcategory($category_id);
if ($catobject->getCategoryQuestionsNumber() == 0) {
if ($catobject->removeCategory()) {
Display::display_confirmation_message(get_lang('DeleteCategoryDone'));
}
else {
Display::display_error_message(get_lang('CannotDeleteCategoryError'));
}
}
else {
Display::display_error_message(get_lang('CannotDeleteCategory'));
}
}
else {
Display::display_error_message(get_lang('CannotDeleteCategoryError'));
}
display_add_category();
display_categories();
}
// ------------------------------------------------------------------------
// form to add a category
// ------------------------------------------------------------------------
function add_category_form($in_action) {
// initiate the object
$form = new FormValidator('note','post', api_get_self().'?action='.$in_action);
// settting the form elements
$form->addElement('header', '', get_lang('AddACategory'));
$form->addElement('text', 'category_name', get_lang('CategoryName'),array('size'=>'95'));
$form->addElement('html_editor', 'category_description', get_lang('CategoryDescription'), null, array('ToolbarSet' => 'test_category', 'Width' => '90%', 'Height' => '200'));
$form->addElement('style_submit_button', 'SubmitNote', get_lang('AddTestCategory'), 'class="add"');
// setting the rules
$form->addRule('category_name', '<div class="required">'.get_lang('ThisFieldIsRequired'), 'required');
// The validation or display
if ($form->validate())
{
$check = Security::check_token('post');
if ($check) {
$values = $form->exportValues();
$v_name = Security::remove_XSS($values['category_name'], COURSEMANAGER);
$v_description = Security::remove_XSS($values['category_description'], COURSEMANAGER);
$objcat = new Testcategory(0, $v_name, $v_description);
if ($objcat->addCategoryInBDD()) {
Display::display_confirmation_message(get_lang('AddCategoryDone'));
}
else {
Display::display_confirmation_message(get_lang('AddCategoryNameAlreadyExists'));
}
}
Security::clear_token();
display_add_category();
display_categories();
}
else
{
display_goback();
$token = Security::get_token();
$form->addElement('hidden','sec_token');
$form->setConstants(array('sec_token' => $token));
$form->display();
display_categories();
}
}
// ------------------------------------------------------------------------
// Display add category button
// ------------------------------------------------------------------------
function display_add_category() {
echo '<div class="actions">';
echo '<a href="exercice.php?'.api_get_cidreq().'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'',32).'</a>';
echo '<a href="'.api_get_self().'?action=addcategory">'.Display::return_icon('question_category.gif').'</a>';
echo '</div>';
echo "<br/>";
}
// ------------------------------------------------------------------------
// Display category list
// ------------------------------------------------------------------------
function display_categories() {
$t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$sql = "SELECT * FROM $t_cattable ORDER BY name";
$res = Database::query($sql, __FILE__, __LINE__);
while ($row = Database::fetch_array($res)) {
// le titre avec le nombre de questions qui sont dans cette catégorie
$tmpobj = new Testcategory($row['id']);
$nb_question = $tmpobj->getCategoryQuestionsNumber();
echo '<div class="sectiontitle" id="id_cat'.$row['id'].'">';
echo "<span style='float:right'>".$nb_question.get_lang('NbCategory')."</span>";
echo $row['name'];
echo '</div>';
echo '<div class="sectioncomment">';
echo $row['description'];
echo '</div>';
echo '<div>';
echo '<a href="'.api_get_self().'?action=editcategory&amp;category_id='.$row['id'].'">'.Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
if ($nb_question > 0) {
echo '<a href="javascript:void(0)" onclick="alert(\''.protectJSDialogQuote(get_lang('CannotDeleteCategory')).'\')">';
echo Display::return_icon('delete_na.gif', get_lang('CannotDeleteCategory'));
echo '</a>';
}
else {
$rowname = protectJSDialogQuote($row['name']);
echo '<a href="'.api_get_self().'?action=deletecategory&amp;category_id='.$row['id'].'" ';
echo 'onclick="return confirmDelete(\''.protectJSDialogQuote(get_lang('DeleteCategoryAreYouSure').'['.$rowname).'] ?\', \'id_cat'.$row['id'].'\');">';
echo Display::return_icon('delete.gif', get_lang('Delete')).'</a>';
}
echo '</div>';
}
}
// ------------------------------------------------------------------------
// display goback to category list page link
// ------------------------------------------------------------------------
function display_goback() {
echo '<div class="actions">';
echo '<a href="'.api_get_self().'">'.Display::return_icon('back.png', '', 32).' '.get_lang('BackToCategoryList').'</a>';
echo '</div>';
}
// ------------------------------------------------------------------------
// To allowed " in javascript dialog box without bad surprises
// replace " with two '
// ------------------------------------------------------------------------
function protectJSDialogQuote($in_txt) {
$res = $in_txt;
$res = str_replace("'", "\'", $res);
$res = str_replace('"', "\'\'", $res); // super astuce pour afficher les " dans les boite de dialogue
return $res;
}
?>

@ -297,6 +297,9 @@ function update_Db_course($course_db_name = null) {
$TABLEQUIZQUESTIONLIST = $course_db_name . 'quiz_question';
$TABLEQUIZANSWERSLIST = $course_db_name . 'quiz_answer';
$TABLEQUIZQUESTIONOPTION = $course_db_name . 'quiz_question_option';
$table_quiz_question_category = $course_db_name . 'quiz_question_category';
$table_quiz_question_rel_category = $course_db_name . 'quiz_question_rel_category';
// Dropbox
$TABLETOOLDROPBOXPOST = $course_db_name . 'dropbox_post';
@ -646,6 +649,7 @@ function update_Db_course($course_db_name = null) {
session_id smallint default 0,
propagate_neg INT NOT NULL DEFAULT 0,
review_answers INT NOT NULL DEFAULT 0,
random_by_category INT NOT NULL DEFAULT 0,
PRIMARY KEY (c_id, id)
)" . $charset_clause;
Database::query($sql);
@ -693,8 +697,6 @@ function update_Db_course($course_db_name = null) {
)" . $charset_clause;
Database::query($sql);
// Exercise tool - answer options
$sql = "
CREATE TABLE `".$TABLEQUIZQUESTIONOPTION . "` (
@ -718,7 +720,28 @@ function update_Db_course($course_db_name = null) {
PRIMARY KEY (c_id, question_id,exercice_id)
)" . $charset_clause;
Database::query($sql);
$sql = "CREATE TABLE `".$table_quiz_question_category . "` (
$add_to_all_tables
id int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
description text NOT NULL,
PRIMARY KEY (c_id,id)
)" . $charset_clause;
Database::query($sql);
$sql = "CREATE TABLE `".$table_quiz_question_rel_category . "` (
$add_to_all_tables
question_id int NOT NULL,
category_id int NOT NULL,
PRIMARY KEY (c_id,question_id)
)" . $charset_clause;
Database::query($sql);
/* Course description */
$sql = "

@ -15,6 +15,7 @@
*/
//See #3910 defines the default prefix for the single course database
// Modified by hubert.borderiou 2011-10-21 Add course category
define('DB_COURSE_PREFIX', 'c_');
// Main database tables
@ -195,6 +196,8 @@ define('TABLE_QUIZ_TEST', 'quiz');
define('TABLE_QUIZ_ANSWER', 'quiz_answer');
define('TABLE_QUIZ_TEST_QUESTION', 'quiz_rel_question');
define('TABLE_QUIZ_QUESTION_OPTION','quiz_question_option');
define('TABLE_QUIZ_QUESTION_CATEGORY', 'quiz_question_category');
define('TABLE_QUIZ_QUESTION_REL_CATEGORY', 'quiz_question_rel_category');
// Linked resource table
//@todo table exists?

@ -0,0 +1,10 @@
<?php
$config['ToolbarSets']['Normal'] = array(
array('Style','FontFormat','FontName','FontSize'),
'/',
array('Bold','Italic','Underline'),
array('SpecialChar', 'mimetex'),
array('OrderedList','UnorderedList','-','Outdent','Indent','-','TextColor','BGColor'),
array('JustifyLeft','JustifyCenter','JustifyRight','-','Source')
);
?>

@ -128,4 +128,5 @@ INSERT INTO course_setting(variable,value,category) VALUES ('course_grading_mode
ALTER TABLE quiz ADD COLUMN review_answers INT NOT NULL DEFAULT 0;
ALTER TABLE student_publication ADD COLUMN contains_file INTEGER NOT NULL DEFAULT 1;
ALTER TABLE student_publication ADD COLUMN allow_text_assignment INTEGER NOT NULL DEFAULT 0;
ALTER TABLE quiz ADD COLUMN random_by_category INT NOT NULL DEFAULT 0;

Loading…
Cancel
Save