exerciselink.class.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. /*
  3. ==============================================================================
  4. Dokeos - elearning and course management software
  5. Copyright (c) 2008 Dokeos Latinoamerica SAC
  6. Copyright (c) 2006 Dokeos SPRL
  7. Copyright (c) 2006 Ghent University (UGent)
  8. Copyright (c) various contributors
  9. For a full list of contributors, see "credits.txt".
  10. The full license can be read in "license.txt".
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15. See the GNU General Public License for more details.
  16. Contact address: Dokeos, rue du Corbeau, 108, B-1030 Brussels, Belgium
  17. Mail: info@dokeos.com
  18. ==============================================================================
  19. */
  20. /**
  21. * Defines a gradebook ExerciseLink object.
  22. * @author Bert Steppé
  23. * @package dokeos.gradebook
  24. */
  25. class ExerciseLink extends AbstractLink
  26. {
  27. // INTERNAL VARIABLES
  28. private $course_info = null;
  29. private $exercise_table = null;
  30. private $exercise_data = null;
  31. // CONSTRUCTORS
  32. function ExerciseLink() {
  33. $this->set_type(LINK_EXERCISE);
  34. }
  35. // FUNCTIONS IMPLEMENTING ABSTRACTLINK
  36. /**
  37. * Generate an array of exercises that a teacher hasn't created a link for.
  38. * @return array 2-dimensional array - every element contains 2 subelements (id, name)
  39. */
  40. public function get_not_created_links() {
  41. if (empty($this->course_code)) {
  42. die('Error in get_not_created_links() : course code not set');
  43. }
  44. $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
  45. $sql = 'SELECT id,title from '.$this->get_exercise_table()
  46. .' exe WHERE id NOT IN'
  47. .' (SELECT ref_id FROM '.$tbl_grade_links
  48. .' WHERE type = '.LINK_EXERCISE
  49. ." AND course_code = '".$this->get_course_code()."'"
  50. .') AND exe.session_id='.api_get_session_id().'';
  51. $result = Database::query($sql, __FILE__, __LINE__);
  52. $cats=array();
  53. while ($data=Database::fetch_array($result)) {
  54. $cats[] = array ($data['id'], $data['title']);
  55. }
  56. return $cats;
  57. }
  58. /**
  59. * Generate an array of all exercises available.
  60. * @return array 2-dimensional array - every element contains 2 subelements (id, name)
  61. */
  62. public function get_all_links() {
  63. if (empty($this->course_code)) {
  64. die('Error in get_not_created_links() : course code not set');
  65. }
  66. $course_info = api_get_course_info($this->course_code);
  67. $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK,$course_info['dbName']);
  68. $sql = 'SELECT id,title from '.$this->get_exercise_table().' WHERE active=1 AND session_id='.api_get_session_id().'';
  69. $result = Database::query($sql, __FILE__, __LINE__);
  70. $cats=array();
  71. while ($data=Database::fetch_array($result)) {
  72. $cats[] = array ($data['id'], $data['title']);
  73. }
  74. return $cats;
  75. }
  76. /**
  77. * Has anyone done this exercise yet ?
  78. */
  79. public function has_results() {
  80. $tbl_stats = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
  81. $sql = 'SELECT count(exe_id) AS number FROM '.$tbl_stats
  82. ." WHERE exe_cours_id = '".$this->get_course_code()."'"
  83. .' AND exe_exo_id = '.$this->get_ref_id();
  84. $result = Database::query($sql, __FILE__, __LINE__);
  85. $number=Database::fetch_row($result);
  86. return ($number[0] != 0);
  87. }
  88. /**
  89. * Get the score of this exercise. Only the first attempts are taken into account.
  90. * @param $stud_id student id (default: all students who have results - then the average is returned)
  91. * @return array (score, max) if student is given
  92. * array (sum of scores, number of scores) otherwise
  93. * or null if no scores available
  94. */
  95. public function calc_score($stud_id = null) {
  96. $tbl_stats = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
  97. $tbl_stats_e_attempt_recording = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
  98. $sql = 'SELECT * FROM '.$tbl_stats.' WHERE exe_exo_id = '.$this->get_ref_id().' AND orig_lp_id = 0 AND orig_lp_item_id = 0';
  99. if (isset($stud_id)){
  100. $currect_course=api_get_course_id();
  101. $course_code_exe=(strlen($currect_course)===0) ? $this->get_course_code() : api_get_course_id();
  102. $sql .= ' AND exe_cours_id="'.$course_code_exe.'" AND exe_user_id = '."'".$stud_id."'";
  103. }
  104. $sql .= ' ORDER BY exe_id DESC';
  105. $scores = Database::query($sql, __FILE__, __LINE__);
  106. if (isset($stud_id)) {
  107. // for 1 student
  108. if ($data=Database::fetch_array($scores)) {
  109. return array ($data['exe_result'], $data['exe_weighting']);
  110. } else {
  111. return null;
  112. }
  113. } else {// all students -> get average
  114. // normal way of getting the info
  115. $students=array(); // user list, needed to make sure we only
  116. // take first attempts into account
  117. $rescount = 0;
  118. $sum = 0;
  119. while ($data=Database::fetch_array($scores)) {
  120. if (!(array_key_exists($data['exe_user_id'],$students))) {
  121. if ($data['exe_weighting'] != 0) {
  122. $students[$data['exe_user_id']] = $data['exe_result'];
  123. $rescount++;
  124. $sum += ($data['exe_result'] / $data['exe_weighting']);
  125. }
  126. }
  127. }
  128. if ($rescount == 0) {
  129. return null;
  130. } else {
  131. return array ($sum , $rescount);
  132. }
  133. }
  134. }
  135. /**
  136. * Get URL where to go to if the user clicks on the link.
  137. * First we go to exercise_jump.php and then to the result page.
  138. * Check this php file for more info.
  139. */
  140. public function get_link() {
  141. //status student
  142. $user_id=api_get_user_id();
  143. $course_code=$this->get_course_code();
  144. $status_user=api_get_status_of_user_in_course ($user_id,$course_code);
  145. $url = api_get_path(WEB_PATH)
  146. .'main/gradebook/exercise_jump.php?cidReq='.$this->get_course_code().'&gradebook=view&exerciseId='.$this->get_ref_id();
  147. if ((!api_is_allowed_to_create_course()
  148. && $this->calc_score(api_get_user_id()) == null) || $status_user!=1) {
  149. $url .= '&amp;doexercise='.$this->get_ref_id();
  150. }
  151. return $url;
  152. }
  153. /**
  154. * Get name to display: same as exercise title
  155. */
  156. public function get_name() {
  157. $data = $this->get_exercise_data();
  158. return $data['title'];
  159. }
  160. /**
  161. * Get description to display: same as exercise description
  162. */
  163. public function get_description() {
  164. $data = $this->get_exercise_data();
  165. return $data['description'];
  166. }
  167. /**
  168. * Check if this still links to an exercise
  169. */
  170. public function is_valid_link() {
  171. $sql = 'SELECT count(id) from '.$this->get_exercise_table()
  172. .' WHERE id = '.$this->get_ref_id().' AND session_id='.api_get_session_id().'';
  173. $result = Database::query($sql, __FILE__, __LINE__);
  174. $number=Database::fetch_row($result);
  175. return ($number[0] != 0);
  176. }
  177. public function get_type_name() {
  178. return get_lang('DokeosExercises');
  179. }
  180. public function needs_name_and_description() {
  181. return false;
  182. }
  183. public function needs_max() {
  184. return false;
  185. }
  186. public function needs_results() {
  187. return false;
  188. }
  189. public function is_allowed_to_change_name() {
  190. return false;
  191. }
  192. // INTERNAL FUNCTIONS
  193. /**
  194. * Lazy load function to get the database table of the exercise
  195. */
  196. private function get_exercise_table () {
  197. $course_info = Database :: get_course_info($this->get_course_code());
  198. $database_name = isset($course_info['db_name']) ? $course_info['db_name'] : '';
  199. if ($database_name!='') {
  200. if (!isset($this->exercise_table)) {
  201. $this->exercise_table = Database :: get_course_table(TABLE_QUIZ_TEST, $database_name);
  202. }
  203. return $this->exercise_table;
  204. } else {
  205. return '';
  206. }
  207. }
  208. /**
  209. * Lazy load function to get the database contents of this exercise
  210. */
  211. private function get_exercise_data () {
  212. $tbl_exercise=$this->get_exercise_table();
  213. if ($tbl_exercise=='') {
  214. return false;
  215. } elseif (!isset($this->exercise_data)) {
  216. $sql = 'SELECT * from '.$this->get_exercise_table()
  217. .' WHERE id = '.$this->get_ref_id().' AND session_id ='.api_get_session_id().'';
  218. $result = Database::query($sql, __FILE__, __LINE__);
  219. $this->exercise_data=Database::fetch_array($result);
  220. }
  221. return $this->exercise_data;
  222. }
  223. }