question_pool.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Question Pool
  5. * This script allows administrators to manage questions and add them into their exercises.
  6. * One question can be in several exercises
  7. * @package chamilo.exercise
  8. * @author Olivier Brouckaert
  9. * @author Julio Montoya adding support to query all questions from all session, courses, exercises
  10. * @author Modify by hubert borderiou 2011-10-21 Question's category
  11. */
  12. /**
  13. * Code
  14. */
  15. // name of the language file that needs to be included
  16. use \ChamiloSession as Session;
  17. $language_file = 'exercice';
  18. require_once 'exercise.class.php';
  19. require_once 'question.class.php';
  20. require_once 'answer.class.php';
  21. require_once '../inc/global.inc.php';
  22. require_once 'exercise.lib.php';
  23. $this_section = SECTION_COURSES;
  24. $is_allowedToEdit=api_is_allowed_to_edit(null,true);
  25. if (empty($delete)) {
  26. $delete = intval($_GET['delete']);
  27. }
  28. if ( empty ( $recup ) ) {
  29. $recup = intval($_GET['recup']);
  30. }
  31. if ( empty ( $fromExercise ) ) {
  32. $fromExercise = intval($_REQUEST['fromExercise']);
  33. }
  34. if(isset($_GET['exerciseId'])){
  35. $exerciseId = intval($_GET['exerciseId']);
  36. }
  37. if (isset($_GET['courseCategoryId'])) {
  38. $courseCategoryId = intval($_GET['courseCategoryId']);
  39. }
  40. $exerciseLevel = -1;
  41. if(isset($_REQUEST['exerciseLevel'])){
  42. $exerciseLevel = intval($_REQUEST['exerciseLevel']);
  43. }
  44. if(isset($_GET['answerType'])){
  45. $answerType = intval($_REQUEST['answerType']);
  46. }
  47. $page = 0;
  48. if(!empty($_GET['page'])){
  49. $page = intval($_GET['page']);
  50. }
  51. $copy_question = 0;
  52. if(!empty($_GET['copy_question'])){
  53. $copy_question = intval($_GET['copy_question']);
  54. }
  55. $session_id = intval($_GET['session_id']);
  56. $selected_course = intval($_GET['selected_course']);
  57. $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
  58. $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
  59. // by default when we go to the page for the first time, we select the current course
  60. if (!isset($_GET['selected_course']) && !isset($_GET['exerciseId'])) {
  61. $selected_course = api_get_course_int_id();
  62. }
  63. // document path
  64. $documentPath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
  65. // picture path
  66. $picturePath = $documentPath.'/images';
  67. if(!($objExcercise instanceOf Exercise) && !empty($fromExercise)) {
  68. $objExercise = new Exercise();
  69. $objExercise->read($fromExercise);
  70. }
  71. $nameTools = get_lang('QuestionPool');
  72. $interbreadcrumb[] = array("url" => "exercice.php","name" => get_lang('Exercices'));
  73. $interbreadcrumb[] = array("url" => "admin.php?exerciseId=".$objExercise->id, "name" => $objExercise->name);
  74. $displayMessage = ""; // messag to be displayed if actions succesfull
  75. if ($is_allowedToEdit) {
  76. //Duplicating a Question
  77. if (!isset($_POST['recup']) && $copy_question != 0 && isset($fromExercise)) {
  78. $origin_course_id = intval($_GET['course_id']);
  79. $origin_course_info = api_get_course_info_by_id($origin_course_id);
  80. $current_course = api_get_course_info();
  81. $old_question_id = $copy_question;
  82. //Reading the source question
  83. $old_question_obj = Question::read($old_question_id, $origin_course_id);
  84. if ($old_question_obj) {
  85. $old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));
  86. //Duplicating the source question, in the current course
  87. $new_id = $old_question_obj->duplicate($current_course);
  88. //Reading new question
  89. $new_question_obj = Question::read($new_id);
  90. $new_question_obj->addToList($fromExercise);
  91. //Reading Answers obj of the current course
  92. $new_answer_obj = new Answer($old_question_id, $origin_course_id);
  93. $new_answer_obj->read();
  94. //Duplicating the Answers in the current course
  95. $new_answer_obj->duplicate($new_id, $current_course);
  96. // destruction of the Question object
  97. unset($new_question_obj);
  98. unset($old_question_obj);
  99. if (!$objExcercise instanceOf Exercise) {
  100. $objExercise = new Exercise();
  101. $objExercise->read($fromExercise);
  102. }
  103. Session::write('objExercise', $objExercise);
  104. }
  105. $displayMessage = get_lang('ItemAdded');
  106. }
  107. // deletes a question from the database and all exercises
  108. if ($delete) {
  109. // Construction of the Question object
  110. $objQuestionTmp = Question::read($delete);
  111. // if the question exists
  112. if ($objQuestionTmp) {
  113. // deletes the question from all exercises
  114. $objQuestionTmp->delete();
  115. }
  116. // destruction of the Question object
  117. unset($objQuestionTmp);
  118. } elseif($recup && $fromExercise) {
  119. // gets an existing question and copies it into a new exercise
  120. $objQuestionTmp = Question :: read($recup);
  121. // if the question exists
  122. if ($objQuestionTmp) {
  123. // adds the exercise ID represented by $fromExercise into the list of exercises for the current question
  124. $objQuestionTmp->addToList($fromExercise);
  125. }
  126. // destruction of the Question object
  127. unset($objQuestionTmp);
  128. if (!$objExcercise instanceOf Exercise) {
  129. $objExercise = new Exercise();
  130. $objExercise->read($fromExercise);
  131. }
  132. // adds the question ID represented by $recup into the list of questions for the current exercise
  133. $objExercise->addToList($recup);
  134. Session::write('objExercise',$objExercise);
  135. // header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
  136. // exit();
  137. }
  138. else if( isset($_POST['recup']) && is_array($_POST['recup']) && $fromExercise) {
  139. $list_recup = $_POST['recup'];
  140. foreach ($list_recup as $course_id => $question_data) {
  141. $origin_course_id = intval($course_id);
  142. $origin_course_info = api_get_course_info_by_id($origin_course_id);
  143. $current_course = api_get_course_info();
  144. foreach ($question_data as $old_question_id) {
  145. /*
  146. $recup = intval($recup);
  147. // if the question exists
  148. if($objQuestionTmp = Question :: read($recup)) {
  149. // adds the exercise ID represented by $fromExercise into the list of exercises for the current question
  150. $objQuestionTmp->addToList($fromExercise);
  151. }
  152. // destruction of the Question object
  153. unset($objQuestionTmp);
  154. if(!$objExcercise instanceOf Exercise) {
  155. $objExercise = new Exercise();
  156. $objExercise->read($fromExercise);
  157. }
  158. // adds the question ID represented by $recup into the list of questions for the current exercise
  159. $objExercise->addToList($recup);
  160. */
  161. //Reading the source question
  162. $old_question_obj = Question::read($old_question_id, $origin_course_id);
  163. if ($old_question_obj) {
  164. $old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));
  165. //Duplicating the source question, in the current course
  166. $new_id = $old_question_obj->duplicate($current_course);
  167. //Reading new question
  168. $new_question_obj = Question::read($new_id);
  169. $new_question_obj->addToList($fromExercise);
  170. //Reading Answers obj of the current course
  171. $new_answer_obj = new Answer($old_question_id, $origin_course_id);
  172. $new_answer_obj->read();
  173. //Duplicating the Answers in the current course
  174. $new_answer_obj->duplicate($new_id, $current_course);
  175. // destruction of the Question object
  176. unset($new_question_obj);
  177. unset($old_question_obj);
  178. if (!$objExcercise instanceOf Exercise) {
  179. $objExercise = new Exercise();
  180. $objExercise->read($fromExercise);
  181. }
  182. }
  183. }
  184. }
  185. Session::write('objExercise',$objExercise);
  186. // header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
  187. // exit();
  188. }
  189. }
  190. if (isset($_SESSION['gradebook'])){
  191. $gradebook= $_SESSION['gradebook'];
  192. }
  193. if (!empty($gradebook) && $gradebook=='view') {
  194. $interbreadcrumb[]= array ('url' => '../gradebook/'.Security::remove_XSS($_SESSION['gradebook_dest']),'name' => get_lang('ToolGradebook'));
  195. }
  196. // if admin of course
  197. if (!$is_allowedToEdit) {
  198. api_not_allowed(true);
  199. }
  200. $confirmYourChoice = addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset));
  201. $htmlHeadXtra[] = "
  202. <script>
  203. function submit_form(obj) {
  204. document.question_pool.submit();
  205. }
  206. function mark_course_id_changed() {
  207. $('#course_id_changed').val('1');
  208. }
  209. function mark_exercice_id_changed() {
  210. $('#exercice_id_changed').val('1');
  211. }
  212. function confirm_your_choice() {
  213. return confirm('$confirmYourChoice');
  214. }
  215. </script>";
  216. Display::display_header($nameTools,'Exercise');
  217. // Menu
  218. echo '<div class="actions">';
  219. if (isset($type)) {
  220. $url = api_get_self().'?type=1';
  221. } else {
  222. $url = api_get_self();
  223. }
  224. if (isset($fromExercise) && $fromExercise > 0) {
  225. echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$fromExercise.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'',ICON_SIZE_MEDIUM).'</a>';
  226. $titleAdd = get_lang('AddQuestionToTest');
  227. }
  228. else {
  229. echo '<a href="exercice.php?'.api_get_cidReq().'">'.Display::return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
  230. echo "<a href='admin.php?exerciseId=0'>".Display::return_icon('add_question.gif', get_lang('NewQu'), '', 32)."</a>";
  231. $titleAdd = get_lang('ManageAllQuestions');
  232. }
  233. echo '</div>';
  234. if ($displayMessage != "") {
  235. Display::display_confirmation_message($displayMessage);
  236. $displayMessage = "";
  237. }
  238. //Form
  239. echo '<form class="form-horizontal" name="question_pool" method="GET" action="'.$url.'">';
  240. //Title
  241. echo '<legend>'.$nameTools.' - '.$titleAdd.'</legend>';
  242. if (isset($type)) {
  243. echo '<input type="hidden" name="type" value="1">';
  244. }
  245. echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
  246. // Session list, if sessions are used.
  247. $session_list = SessionManager::get_sessions_by_general_coach(api_get_user_id());
  248. $tabAttrParam = array('class'=>'chzn-select', 'onchange'=>'submit_form(this)'); // when sessions are used
  249. $labelFormRow = get_lang('Session');
  250. $session_select_list = array();
  251. foreach($session_list as $item) {
  252. $session_select_list[$item['id']] = $item['name'];
  253. }
  254. $select_session_html = Display::select('session_id', $session_select_list, $session_id, $tabAttrParam);
  255. echo Display::form_row($labelFormRow, $select_session_html); // hub 13-10-2011
  256. // Course list, get course list of session, or for course where user is admin
  257. if (!empty($session_id) && $session_id != '-1') {
  258. $course_list = SessionManager::get_course_list_by_session_id($session_id);
  259. } else {
  260. $course_list = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
  261. }
  262. $course_select_list = array();
  263. foreach ($course_list as $item) {
  264. $course_select_list[$item['id']] = "";
  265. if ($item['id'] == api_get_course_int_id()) {
  266. $course_select_list[$item['id']] = ">&nbsp;&nbsp;&nbsp;&nbsp;";
  267. }
  268. $course_select_list[$item['id']] .= $item['title'];
  269. }
  270. $select_course_html = Display::select('selected_course', $course_select_list, $selected_course, array('class'=>'chzn-select','onchange'=>'mark_course_id_changed(); submit_form(this);'));
  271. echo Display::form_row(get_lang('Course'), $select_course_html);
  272. if (empty($selected_course) || $selected_course == '-1') {
  273. $course_info = api_get_course_info();
  274. reset_menu_exo_lvl_type(); // no course selected, reset menu test / difficult� / type de reponse // hub 13-10-2011
  275. }
  276. else {
  277. $course_info = CourseManager::get_course_information_by_id($selected_course);
  278. }
  279. // If course has changed, reset the menu default
  280. if ($course_id_changed) {
  281. reset_menu_exo_lvl_type();
  282. }
  283. $course_id = $course_info['real_id'];
  284. //Redefining table calls
  285. $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
  286. $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
  287. $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
  288. $TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
  289. $TBL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY); // hub 13-10-2011
  290. $TBL_COURSE_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY); // hub 13-10-2011
  291. // Get course categories for the selected course
  292. // get category list for the course $selected_course
  293. $tabCatList = Testcategory::getCategoriesIdAndName($selected_course);
  294. $selectCourseCateogry = Display::select('courseCategoryId', $tabCatList, $courseCategoryId, array('class'=>'chzn-select','onchange'=>'submit_form(this);'), false);
  295. echo Display::form_row(get_lang("QuestionCategory"), $selectCourseCateogry);
  296. // Get exercice list for this course
  297. $exercise_list = get_all_exercises_for_course_id($course_info, $session_id, $selected_course);
  298. //Exercise List
  299. $my_exercise_list = array();
  300. $my_exercise_list['0'] = get_lang('AllExercises');
  301. $my_exercise_list['-1'] = get_lang('OrphanQuestions');
  302. if (is_array($exercise_list)) {
  303. foreach($exercise_list as $row) {
  304. $my_exercise_list[$row['id']] = "";
  305. if ($row['id'] == $fromExercise && $selected_course == api_get_course_int_id()) {
  306. $my_exercise_list[$row['id']] = ">&nbsp;&nbsp;&nbsp;&nbsp;"; // hub 13-10-2011
  307. }
  308. $my_exercise_list[$row['id']] .= $row['title'];
  309. }
  310. }
  311. if ($exercice_id_changed == 1) {
  312. reset_menu_lvl_type();
  313. }
  314. $select_exercise_html = Display::select('exerciseId', $my_exercise_list, $exerciseId, array('class'=>'chzn-select','onchange'=>'mark_exercice_id_changed(); submit_form(this);'), false);
  315. echo Display::form_row(get_lang('Exercise'), $select_exercise_html);
  316. // Difficulty list (only from 0 to 5)
  317. $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);
  318. echo Display::form_row(get_lang('Difficulty'), $select_difficulty_html);
  319. // Answer type
  320. $question_list = Question::get_question_type_list();
  321. $new_question_list = array();
  322. $new_question_list['-1'] = get_lang('All');
  323. $objExercise = new Exercise();
  324. $objExercise->read($fromExercise);
  325. foreach ($question_list as $key=>$item) {
  326. if ($objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) {
  327. if (!in_array($key, array(HOT_SPOT_DELINEATION, UNIQUE_ANSWER))) {
  328. continue;
  329. }
  330. $new_question_list[$key] = get_lang($item[1]);
  331. } else {
  332. if ($key == HOT_SPOT_DELINEATION) {
  333. continue;
  334. }
  335. $new_question_list[$key] = get_lang($item[1]);
  336. }
  337. }
  338. //Answer type list
  339. $select_answer_html = Display::select('answerType', $new_question_list, $answerType, array('class'=>'chzn-select','onchange'=>'submit_form(this);'), false);
  340. echo Display::form_row(get_lang('AnswerType'), $select_answer_html);
  341. $button = '<button class="save" type="submit" name="name" value="'.get_lang('Filter').'">'.get_lang('Filter').'</button>';
  342. echo Display::form_row('', $button);
  343. echo "<input type='hidden' id='course_id_changed' name='course_id_changed' value='0' />";
  344. echo "<input type='hidden' id='exercice_id_changed' name='exercice_id_changed' value='0' />";
  345. ?>
  346. </form>
  347. <div class="clear"></div>
  348. <form method="post" action="<?php echo $url.'?'.api_get_cidreq().'&fromExercise='.$fromExercise; ?>" >
  349. <?php
  350. echo '<input type="hidden" name="course_id" value="'.$selected_course.'">';
  351. // if we have selected an exercise in the list-box 'Filter'
  352. if ($exerciseId > 0) {
  353. $where = '';
  354. $from = '';
  355. if (isset($courseCategoryId) && $courseCategoryId > 0) {
  356. $from = ", $TBL_COURSE_REL_CATEGORY crc ";
  357. $where .= " AND crc.c_id = $selected_course AND crc.question_id=qu.id AND crc.category_id=$courseCategoryId";
  358. }
  359. if (isset($exerciseLevel) && $exerciseLevel != -1) {
  360. $where .= ' AND level='.$exerciseLevel;
  361. }
  362. if (isset($answerType) && $answerType > 0) {
  363. $where .= ' AND type='.$answerType;
  364. }
  365. $sql = "SELECT DISTINCT
  366. id,question,
  367. type,
  368. level
  369. FROM
  370. $TBL_EXERCICE_QUESTION qt,
  371. $TBL_QUESTIONS qu
  372. $from
  373. WHERE
  374. qt.question_id=qu.id
  375. AND qt.exercice_id = $exerciseId
  376. AND qt.c_id = $selected_course
  377. AND qu.c_id = $selected_course
  378. $where
  379. ORDER BY
  380. question_order";
  381. $result=Database::query($sql);
  382. while($row = Database::fetch_array($result, 'ASSOC')) {
  383. $main_question_list[] = $row;
  384. }
  385. } elseif ($exerciseId == -1) {
  386. // If we have selected the option 'Orphan questions' in the list-box 'Filter'
  387. $level_where = '';
  388. $from = '';
  389. if (isset($courseCategoryId) && $courseCategoryId > 0) {
  390. $from = ", $TBL_COURSE_REL_CATEGORY crc ";
  391. $level_where .= " AND crc.c_id=$selected_course AND crc.question_id=qu.id AND crc.category_id = $courseCategoryId";
  392. }
  393. if (isset($exerciseLevel) && $exerciseLevel!= -1 ) {
  394. $level_where = ' AND level = '.$exerciseLevel;
  395. }
  396. $answer_where = '';
  397. if (isset($answerType) && $answerType >0 -1 ) {
  398. $answer_where = ' AND q.type = '.$answerType;
  399. }
  400. /*$sql = "SELECT DISTINCT * FROM $TBL_QUESTIONS qu $from
  401. WHERE qu.c_id = $selected_course AND qu.id NOT IN (
  402. SELECT question_id FROM $TBL_EXERCICE_QUESTION
  403. WHERE c_id=$selected_course
  404. ) $level_where $answer_where";*/
  405. $sql = " (
  406. SELECT q.* FROM $TBL_QUESTIONS q INNER JOIN $TBL_EXERCICE_QUESTION r
  407. ON (q.c_id = r.c_id AND q.id = r.question_id)
  408. INNER JOIN $TBL_EXERCICES ex
  409. ON (ex.id = r.exercice_id AND ex.c_id =r.c_id ) $from
  410. WHERE ex.c_id = '$selected_course' AND ex.active = '-1' $level_where $answer_where
  411. )
  412. UNION
  413. (
  414. SELECT q.* FROM $TBL_QUESTIONS q
  415. LEFT OUTER JOIN $TBL_EXERCICE_QUESTION r
  416. ON (q.c_id = r.c_id AND q.id = r.question_id)
  417. WHERE q.c_id = '$selected_course' AND r.question_id is null $level_where $answer_where
  418. )
  419. UNION
  420. (
  421. SELECT q.* FROM $TBL_QUESTIONS q
  422. INNER JOIN $TBL_EXERCICE_QUESTION r
  423. ON (q.c_id = r.c_id AND q.id = r.question_id)
  424. WHERE r.c_id = '$selected_course' AND r.exercice_id = '-1' OR r.exercice_id = '0' $level_where $answer_where
  425. )";
  426. $result = Database::query($sql);
  427. while($row = Database::fetch_array($result, 'ASSOC')) {
  428. $main_question_list[] = $row;
  429. }
  430. } else {
  431. //
  432. // All tests for selected course
  433. //
  434. // if we have not selected any option in the list-box 'Filter'
  435. $filter = '';
  436. $from = '';
  437. if (isset($courseCategoryId) && $courseCategoryId > 0) {
  438. $from = ", $TBL_COURSE_REL_CATEGORY crc ";
  439. $filter .= " AND crc.c_id=$selected_course AND crc.question_id=qu.id AND crc.category_id=$courseCategoryId";
  440. }
  441. if (isset($exerciseLevel) && $exerciseLevel != -1) {
  442. $filter .= ' AND level='.$exerciseLevel.' ';
  443. }
  444. if (isset($answerType) && $answerType > 0) {
  445. $filter .= ' AND qu.type='.$answerType.' ';
  446. }
  447. if (!empty($session_id) && $session_id != '-1') {
  448. $main_question_list = array();
  449. if (!empty($course_list))
  450. foreach ($course_list as $course_item) {
  451. if (!empty($selected_course) && $selected_course != '-1') {
  452. if ($selected_course != $course_item['id']) {
  453. continue;
  454. }
  455. }
  456. $exercise_list = get_all_exercises($course_item, $session_id);
  457. if (!empty($exercise_list)) {
  458. foreach ($exercise_list as $exercise) {
  459. $my_exercise = new Exercise($course_item['id']);
  460. $my_exercise->read($exercise['id']);
  461. if (!empty($my_exercise)) {
  462. if (!empty($my_exercise->questionList)) {
  463. foreach ($my_exercise->questionList as $question_id) {
  464. $question_obj = Question::read($question_id, $course_item['id']);
  465. if ($exerciseLevel != '-1')
  466. if ($exerciseLevel != $question_obj->level) {
  467. continue;
  468. }
  469. if ($answerType > 0)
  470. if ($answerType != $question_obj->type) {
  471. continue;
  472. }
  473. $category_list = Testcategory::getCategoryForQuestion($question_obj->id, $selected_course);
  474. if ($courseCategoryId > 0 && !empty($category_list)) {
  475. continue;
  476. }
  477. if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) {
  478. if ($question_obj->type == HOT_SPOT_DELINEATION) {
  479. continue;
  480. }
  481. }
  482. $question_row = array( 'id' => $question_obj->id,
  483. 'question' => $question_obj->question,
  484. 'type' => $question_obj->type,
  485. 'level' => $question_obj->level,
  486. 'exercise_id' => $exercise['id'],
  487. 'course_id' => $course_item['id'],
  488. );
  489. $main_question_list[] = $question_row;
  490. }
  491. }
  492. }
  493. }
  494. }
  495. }
  496. }
  497. else {
  498. //
  499. // All tests for the course selected, not in session
  500. //
  501. $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";
  502. $result = Database::query($sql);
  503. while($row = Database::fetch_array($result, 'ASSOC')) {
  504. $main_question_list[] = $row;
  505. }
  506. }
  507. // forces the value to 0
  508. $exerciseId=0;
  509. }
  510. $nbrQuestions = count($main_question_list);
  511. // build the line of the array to display questions
  512. // Actions are different if you launch the question_pool page
  513. // They are different too if you have displayed questions from your course
  514. // Or from another course you are the admin(or session admin)
  515. // from a test or not
  516. /*
  517. +--------------------------------------------+--------------------------------------------+
  518. | NOT IN A TEST | IN A TEST |
  519. +----------------------+---------------------+---------------------+----------------------+
  520. |IN THE COURSE (*) "x | NOT IN THE COURSE o | IN THE COURSE + | NOT IN THE COURSE o |
  521. +----------------------+---------------------+---------------------+----------------------+
  522. |Edit the question | Do nothing | Add question to test|Clone question in test|
  523. |Delete the question | | | |
  524. |(true delete) | | | |
  525. +----------------------+---------------------+---------------------+----------------------+
  526. (*) this is the only way to delete or modify orphan questions
  527. */
  528. //
  529. if ($fromExercise <= 0) { // NOT IN A TEST - IN THE COURSE
  530. if ($selected_course == api_get_course_int_id()) {
  531. $actionLabel = get_lang('Modify');
  532. $actionIcon1 = "edit";
  533. $actionIcon2 = "delete";
  534. $questionTagA = 1; // we are in the course, question title can be a link to the question edit page
  535. }
  536. else { // NOT IN A TEST - NOT IN THE COURSE
  537. $actionLabel = get_lang('Reuse');
  538. $actionIcon1 = get_lang('MustBeInATest');
  539. $actionIcon2 = "";
  540. $questionTagA = 0; // we are not in this course, to messy if we link to the question in another course
  541. }
  542. }
  543. else { // IN A TEST - IN THE COURSE
  544. if ($selected_course == api_get_course_int_id()) {
  545. $actionLabel = get_lang('Reuse');
  546. $actionIcon1 = "add";
  547. $actionIcon2 = "";
  548. $questionTagA = 1;
  549. }
  550. else { // IN A TEST - NOT IN THE COURSE
  551. $actionLabel = get_lang('Reuse');
  552. $actionIcon1 = "clone";
  553. $actionIcon2 = "";
  554. $questionTagA = 0;
  555. }
  556. }
  557. //
  558. // display table
  559. //
  560. $header = array();
  561. $header[] = array(get_lang('QuestionUpperCaseFirstLetter'), false, array("style"=>"text-align:center"), '');
  562. $header[] = array(get_lang('Type'), false, array("style"=>"text-align:center"), array("style"=>"text-align:center"), '');
  563. $header[] = array(get_lang('QuestionCategory'), false, array("style"=>"text-align:center"), array("style"=>"text-align:center"), '');
  564. $header[] = array(get_lang('Difficulty'), false, array("style"=>"text-align:center"), array("style"=>"text-align:center"), '');
  565. $header[] = array($actionLabel, false, array("style"=>"text-align:center"), array("style"=>"text-align:center"), '');
  566. $data = array();
  567. if (is_array($main_question_list)) {
  568. $all_category_list = Testcategory::getCategoryListName($selected_course);
  569. foreach ($main_question_list as $tabQuestion) {
  570. $row = array();
  571. //This function checks if the question can be read
  572. $question_type = get_question_type_for_question($selected_course, $tabQuestion['id']);
  573. if (empty($question_type)) {
  574. continue;
  575. }
  576. $row[] = get_a_tag_for_question($questionTagA, $fromExercise, $tabQuestion['id'], $tabQuestion['type'], $tabQuestion['question']);
  577. $row[] = $question_type;
  578. $row[] = get_question_categorie_for_question($selected_course, $tabQuestion['id']);
  579. $row[] = $tabQuestion['level'];
  580. $row[] = get_action_icon_for_question($actionIcon1,
  581. $fromExercise,
  582. $tabQuestion['id'],
  583. $tabQuestion['type'],
  584. $tabQuestion['question'],
  585. $selected_course,
  586. $courseCategoryId,
  587. $exerciseLevel,
  588. $answerType,
  589. $session_id, $exerciseId).
  590. "&nbsp;".
  591. get_action_icon_for_question($actionIcon2, $fromExercise, $tabQuestion['id'], $tabQuestion['type'],
  592. $tabQuestion['question'], $selected_course, $courseCategoryId, $exerciseLevel, $answerType,
  593. $session_id, $exerciseId);
  594. $data[] = $row;
  595. }
  596. }
  597. Display :: display_sortable_table($header, $data, '', array('per_page_default'=>999,'per_page'=>999,'page_nr'=>1));
  598. if (!$nbrQuestions) {
  599. echo get_lang('NoQuestion');
  600. }
  601. // The (+) system as now make this button useless
  602. // Hubert Borderiou 27-10-2011
  603. //if (api_get_session_id() == 0){
  604. // echo '<div style="width:100%; border-top:1px dotted #4171B5;"><button class="save" type="submit">'.get_lang('Reuse').'</button></div></form>';
  605. //}
  606. Display::display_footer();
  607. // Some functions here, just for question_pool to ease the code
  608. /*
  609. Put the menu entry for level and type to default "Choice"
  610. It is usefull if you change the exercice, you need to reset the other menus
  611. hubert.borderiou 13-10-2011
  612. */
  613. function reset_menu_lvl_type() {
  614. global $exerciseLevel, $answerType;
  615. $answerType = -1;
  616. $exerciseLevel = -1;
  617. }
  618. /*
  619. Put the menu entry for exercice and level and type to default "Choice"
  620. It is usefull if you change the course, you need to reset the other menus
  621. hubert.borderiou 13-10-2011
  622. */
  623. function reset_menu_exo_lvl_type() {
  624. global $exerciseId, $courseCategoryId;
  625. reset_menu_lvl_type();
  626. $exerciseId = 0;
  627. $courseCategoryId = 0;
  628. }
  629. //
  630. // return the <a> link to admin question, if needed
  631. // hubert.borderiou 13-10-2011
  632. function get_a_tag_for_question($in_addA, $in_fromex, $in_questionid, $in_questiontype, $in_questionname) {
  633. $res = $in_questionname;
  634. if ($in_addA) {
  635. $res = "<a href='admin.php?".api_get_cidreq()."&editQuestion=$in_questionid&type=$in_questiontype&fromExercise=$in_fromex'>".$res."</a>";
  636. }
  637. return $res;
  638. }
  639. /*
  640. $row[] = get_action_icon_for_question(
  641. $actionIcon1, --
  642. $fromExercise, --
  643. $tabQuestion['id'], --
  644. $tabQuestion['type'],
  645. $tabQuestion['question'],
  646. $selected_course,
  647. $courseCategoryId,
  648. $exerciseLevel,
  649. $answerType,
  650. $session_id,
  651. $exerciseId).
  652. "&nbsp;".
  653. get_action_icon_for_question($actionIcon2, $fromExercise, $tabQuestion['id'], $tabQuestion['type'],
  654. $tabQuestion['question'], $selected_course, $courseCategoryId, $exerciseLevel, $answerType,
  655. $session_id, $exerciseId);
  656. */
  657. //
  658. // return the <a> html code for delete, add, clone, edit a question
  659. // hubert.borderiou 13-10-2011
  660. // in_action = the code of the action triggered by the button
  661. // from_exercice = the id of the current exercice from which we click on question pool
  662. // in_questionid = the id of the current question
  663. // in_questiontype = the code of the type of the current question
  664. // in_questionname = the name of the question
  665. // in_selected_course = the if of the course chosen in the FILTERING MENU
  666. // in_courseCategoryId = the id of the category chosen in the FILTERING MENU
  667. // in_exerciseLevel = the level of the exercice chosen in the FILTERING MENU
  668. // in_answerType = the code of the type of the question chosen in the FILTERING MENU
  669. // in_session_id = the id of the session_id chosen in the FILTERING MENU
  670. // in_exercice_id = the id of the exercice chosen in the FILTERING MENU
  671. function get_action_icon_for_question($in_action, $from_exercice, $in_questionid, $in_questiontype, $in_questionname,
  672. $in_selected_course, $in_courseCategoryId, $in_exerciseLevel, $in_answerType, $in_session_id, $in_exercice_id
  673. ) {
  674. $res = "";
  675. $getParams = "&selected_course=$in_selected_course&courseCategoryId=$in_courseCategoryId&exerciseId=$in_exercice_id&exerciseLevel=$in_exerciseLevel&answerType=$in_answerType&session_id=$in_session_id";
  676. switch ($in_action) {
  677. case "delete" :
  678. $res = "<a href='".api_get_self()."?".api_get_cidreq()."&delete=$in_questionid$getParams' onclick='return confirm_your_choice()'>";
  679. $res .= Display::return_icon("delete.gif", get_lang('Delete'));
  680. $res .= "</a>";
  681. break;
  682. case "edit" :
  683. $res = get_a_tag_for_question(1, $from_exercice, $in_questionid, $in_questiontype, Display::return_icon("edit.gif", get_lang('Modify')));
  684. break;
  685. case "add":
  686. // add if question is not already in test
  687. $myObjEx = new Exercise();
  688. $myObjEx->read($from_exercice);
  689. if (!$myObjEx->isInList($in_questionid)) {
  690. $res = "<a href='".api_get_self()."?".api_get_cidreq()."&recup=$in_questionid&fromExercise=$from_exercice$getParams'>";
  691. $res .= Display::return_icon("view_more_stats.gif", get_lang('InsertALinkToThisQuestionInTheExercise'));
  692. $res .= "</a>";
  693. }
  694. else {
  695. $res = "-";
  696. }
  697. unset($myObjEx);
  698. break;
  699. case "clone":
  700. $res = "<a href='".api_get_self()."?".api_get_cidreq()."&amp;copy_question=$in_questionid&course_id=$in_selected_course&fromExercise=$from_exercice$getParams'>";
  701. $res .= Display::return_icon('cd.gif', get_lang('ReUseACopyInCurrentTest'));
  702. $res .= "</a>";
  703. break;
  704. default :
  705. $res = $in_action;
  706. break;
  707. }
  708. return $res;
  709. }
  710. // return the icon for the question type
  711. // hubert.borderiou 13-10-2011
  712. function get_question_type_for_question($in_selectedcourse, $in_questionid) {
  713. $myObjQuestion = Question::read($in_questionid, $in_selectedcourse);
  714. $questionType = null;
  715. if (!empty($myObjQuestion)) {
  716. list($typeImg, $typeExpl) = $myObjQuestion->get_type_icon_html();
  717. $questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), 32), array());
  718. unset($myObjQuestion);
  719. }
  720. return $questionType;
  721. }
  722. // return the name of the category for the question in a course
  723. // hubert.borderiou 13-10-2011
  724. function get_question_categorie_for_question($course_id, $question_id) {
  725. global $all_category_list;
  726. $objQuestionTmp = Question :: read($question_id, $course_id);
  727. return Testcategory::return_category_labels($objQuestionTmp->category_list, $all_category_list);
  728. }