CourseBuilder.class.php 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. require_once 'Course.class.php';
  4. require_once 'Event.class.php';
  5. require_once 'Link.class.php';
  6. require_once 'ToolIntro.class.php';
  7. require_once 'Document.class.php';
  8. require_once 'ScormDocument.class.php';
  9. require_once 'LinkCategory.class.php';
  10. require_once 'CourseDescription.class.php';
  11. require_once 'ForumPost.class.php';
  12. require_once 'ForumTopic.class.php';
  13. require_once 'Forum.class.php';
  14. require_once 'ForumCategory.class.php';
  15. require_once 'Quiz.class.php';
  16. require_once 'QuizQuestion.class.php';
  17. require_once 'CourseCopyLearnpath.class.php';
  18. require_once 'Survey.class.php';
  19. require_once 'SurveyQuestion.class.php';
  20. require_once 'Glossary.class.php';
  21. require_once 'CourseSession.class.php';
  22. require_once 'wiki.class.php';
  23. require_once 'Thematic.class.php';
  24. require_once 'Attendance.class.php';
  25. require_once 'Work.class.php';
  26. /**
  27. * Class which can build a course-object from a Chamilo-course.
  28. * @author Bart Mollet <bart.mollet@hogent.be>
  29. * @package chamilo.backup
  30. */
  31. class CourseBuilder
  32. {
  33. /** Course */
  34. public $course;
  35. /* With this array you can filter the tools you want to be parsed by default all tools are included*/
  36. public $tools_to_build = array(
  37. 'announcements',
  38. 'attendance',
  39. 'course_descriptions',
  40. 'documents',
  41. 'events',
  42. 'forum_category',
  43. 'forums',
  44. 'forum_topics',
  45. 'glossary',
  46. 'quizzes',
  47. 'learnpaths',
  48. 'links',
  49. 'surveys',
  50. 'tool_intro',
  51. 'thematic',
  52. 'wiki',
  53. 'works'
  54. );
  55. /* With this array you can filter wich elements of the tools are going to be added in the course obj (only works with LPs) */
  56. public $specific_id_list = array();
  57. /**
  58. * Create a new CourseBuilder
  59. */
  60. public function __construct($type='', $course = null)
  61. {
  62. $_course = api_get_course_info();
  63. if (!empty($course['official_code'])){
  64. $_course = $course;
  65. }
  66. $this->course = new Course();
  67. $this->course->code = $_course['official_code'];
  68. $this->course->type = $type;
  69. $this->course->path = api_get_path(SYS_COURSE_PATH).$_course['path'].'/';
  70. $this->course->backup_path = api_get_path(SYS_COURSE_PATH).$_course['path'];
  71. $this->course->encoding = api_get_system_encoding(); //current platform encoding
  72. $this->course->db_name = $_course['dbName'];
  73. $this->course->info = $_course;
  74. }
  75. /**
  76. *
  77. * @param type $array
  78. */
  79. function set_tools_to_build($array)
  80. {
  81. $this->tools_to_build = $array;
  82. }
  83. /**
  84. *
  85. * @param type $array
  86. */
  87. function set_tools_specific_id_list($array)
  88. {
  89. $this->specific_id_list = $array;
  90. }
  91. /**
  92. * Get the created course
  93. * @return course The course
  94. */
  95. function get_course()
  96. {
  97. return $this->course;
  98. }
  99. /**
  100. * Build the course-object
  101. *
  102. * @param int session_id
  103. * @param string course_code
  104. * @param bool true if you want to get the elements that exists in the course and
  105. * in the session, (session_id = 0 or session_id = X)
  106. */
  107. function build($session_id = 0, $course_code = '', $with_base_content = false)
  108. {
  109. $table_link = Database :: get_course_table(TABLE_LINKED_RESOURCES);
  110. $table_properties = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  111. $course_info = api_get_course_info($course_code);
  112. $course_id = $course_info['real_id'];
  113. foreach ($this->tools_to_build as $tool) {
  114. $function_build = 'build_'.$tool;
  115. $specificIdList = isset($this->specific_id_list[$tool]) ? $this->specific_id_list[$tool] : null;
  116. $this->$function_build($session_id, $course_code, $with_base_content, $specificIdList);
  117. }
  118. //TABLE_LINKED_RESOURCES is the "resource" course table, which is deprecated, apparently
  119. foreach ($this->course->resources as $type => $resources) {
  120. foreach ($resources as $id => $resource) {
  121. $sql = "SELECT * FROM ".$table_link." WHERE c_id = $course_id AND source_type = '".$resource->get_type()."' AND source_id = '".$resource->get_id()."'";
  122. $res = Database::query($sql);
  123. while ($link = Database::fetch_object($res)) {
  124. $this->course->resources[$type][$id]->add_linked_resource($link->resource_type, $link->resource_id);
  125. }
  126. }
  127. }
  128. // Once we've built the resouces array a bit more, try to get items
  129. // from the item_propry table and order them in the "resources" array
  130. foreach ($this->course->resources as $type => $resources) {
  131. foreach ($resources as $id => $resource) {
  132. $tool = $resource->get_tool();
  133. if ($tool != null) {
  134. $sql = "SELECT * FROM $table_properties WHERE c_id = $course_id AND TOOL = '".$tool."' AND ref='".$resource->get_id()."'";
  135. $res = Database::query($sql);
  136. $all_properties = array ();
  137. while ($item_property = Database::fetch_array($res)) {
  138. $all_properties[]= $item_property;
  139. }
  140. $this->course->resources[$type][$id]->item_properties = $all_properties;
  141. }
  142. }
  143. }
  144. return $this->course;
  145. }
  146. /**
  147. * Build the documents
  148. */
  149. function build_documents($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  150. {
  151. $course_info = api_get_course_info($course_code);
  152. $course_id = $course_info['real_id'];
  153. $table_doc = Database::get_course_table(TABLE_DOCUMENT);
  154. $table_prop = Database::get_course_table(TABLE_ITEM_PROPERTY);
  155. //Remove chat_files and shared_folder files
  156. $avoid_paths = " path NOT LIKE '/shared_folder%' AND
  157. path NOT LIKE '/chat_files%' ";
  158. //$avoid_paths = " 1 = 1 ";
  159. if (!empty($course_code) && !empty($session_id)) {
  160. $session_id = intval($session_id);
  161. if ($with_base_content) {
  162. $session_condition = api_get_session_condition($session_id, true, true);
  163. } else {
  164. $session_condition = api_get_session_condition($session_id, true);
  165. }
  166. if (!empty($this->course->type) && $this->course->type=='partial') {
  167. $sql = "SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size FROM $table_doc d, $table_prop p
  168. WHERE d.c_id = $course_id AND
  169. p.c_id = $course_id AND
  170. tool = '".TOOL_DOCUMENT."' AND
  171. p.ref = d.id AND
  172. p.visibility != 2 AND
  173. path NOT LIKE '/images/gallery%' AND
  174. $avoid_paths
  175. $session_condition
  176. ORDER BY path";
  177. } else {
  178. $sql = "SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size FROM $table_doc d, $table_prop p
  179. WHERE d.c_id = $course_id AND
  180. p.c_id = $course_id AND
  181. tool = '".TOOL_DOCUMENT."' AND
  182. $avoid_paths AND
  183. p.ref = d.id AND
  184. p.visibility != 2 $session_condition
  185. ORDER BY path";
  186. }
  187. $db_result = Database::query($sql);
  188. while ($obj = Database::fetch_object($db_result)) {
  189. $doc = new Document($obj->id, $obj->path, $obj->comment, $obj->title, $obj->filetype, $obj->size);
  190. $this->course->add_resource($doc);
  191. }
  192. } else {
  193. if (!empty($this->course->type) && $this->course->type=='partial')
  194. $sql = 'SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size FROM '.$table_doc.' d, '.$table_prop.' p
  195. WHERE d.c_id = '.$course_id.' AND
  196. p.c_id = '.$course_id.' AND
  197. tool = \''.TOOL_DOCUMENT.'\' AND
  198. p.ref = d.id AND
  199. p.visibility != 2 AND
  200. path NOT LIKE \'/images/gallery%\' AND
  201. '.$avoid_paths.'AND
  202. d.session_id = 0
  203. ORDER BY path';
  204. else
  205. $sql = 'SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size
  206. FROM '.$table_doc.' d, '.$table_prop.' p
  207. WHERE d.c_id = '.$course_id.' AND
  208. p.c_id = '.$course_id.' AND
  209. tool = \''.TOOL_DOCUMENT.'\' AND
  210. p.ref = d.id AND
  211. p.visibility != 2 AND
  212. '.$avoid_paths.' AND
  213. d.session_id = 0
  214. ORDER BY path';
  215. $db_result = Database::query($sql);
  216. while ($obj = Database::fetch_object($db_result)) {
  217. $doc = new Document($obj->id, $obj->path, $obj->comment, $obj->title, $obj->filetype, $obj->size);
  218. $this->course->add_resource($doc);
  219. }
  220. }
  221. }
  222. /**
  223. * Build the forums
  224. */
  225. function build_forums($session_id = 0, $course_code = null, $with_base_content = false, $id_list = array())
  226. {
  227. $course_info = api_get_course_info($course_code);
  228. $course_id = $course_info['real_id'];
  229. $table = Database :: get_course_table(TABLE_FORUM);
  230. $sql = "SELECT * FROM $table WHERE c_id = $course_id ";
  231. $sql .= " ORDER BY forum_title, forum_category";
  232. $db_result = Database::query($sql);
  233. while ($obj = Database::fetch_object($db_result)) {
  234. $forum = new Forum($obj);
  235. $this->course->add_resource($forum);
  236. }
  237. }
  238. /**
  239. * Build a forum-category
  240. */
  241. function build_forum_category($session_id = 0, $course_code = null, $with_base_content = false, $id_list = array())
  242. {
  243. $table = Database :: get_course_table(TABLE_FORUM_CATEGORY);
  244. $course_info = api_get_course_info($course_code);
  245. $course_id = $course_info['real_id'];
  246. $sql = "SELECT * FROM $table WHERE c_id = $course_id ORDER BY cat_title";
  247. $db_result = Database::query($sql);
  248. while ($obj = Database::fetch_object($db_result)) {
  249. $forum_category = new ForumCategory($obj);
  250. $this->course->add_resource($forum_category);
  251. }
  252. }
  253. /**
  254. * Build the forum-topics
  255. */
  256. function build_forum_topics($session_id = 0, $course_code = null, $with_base_content = false, $id_list = array())
  257. {
  258. $table = Database :: get_course_table(TABLE_FORUM_THREAD);
  259. $course_info = api_get_course_info($course_code);
  260. $course_id = $course_info['real_id'];
  261. $sql = "SELECT * FROM $table WHERE c_id = $course_id
  262. ORDER BY thread_title ";
  263. $db_result = Database::query($sql);
  264. while ($obj = Database::fetch_object($db_result)) {
  265. $forum_topic = new ForumTopic($obj);
  266. $this->course->add_resource($forum_topic);
  267. $this->build_forum_posts($obj->thread_id, $obj->forum_id, true);
  268. }
  269. }
  270. /**
  271. * Build the forum-posts
  272. * TODO: All tree structure of posts should be built, attachments for example.
  273. */
  274. function build_forum_posts($thread_id = null, $forum_id = null, $only_first_post = false)
  275. {
  276. $table = Database :: get_course_table(TABLE_FORUM_POST);
  277. $course_id = api_get_course_int_id();
  278. $sql = "SELECT * FROM $table WHERE c_id = $course_id ";
  279. if (!empty($thread_id) && !empty($forum_id)) {
  280. $forum_id = intval($forum_id);
  281. $thread_id = intval($thread_id);
  282. $sql .= " AND thread_id = $thread_id AND forum_id = $forum_id ";
  283. }
  284. $sql .= " ORDER BY post_id ASC LIMIT 1";
  285. $db_result = Database::query($sql);
  286. while ($obj = Database::fetch_object($db_result)) {
  287. $forum_post = new ForumPost($obj);
  288. $this->course->add_resource($forum_post);
  289. }
  290. }
  291. /**
  292. * Build the links
  293. */
  294. function build_links($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  295. {
  296. $course_info = api_get_course_info($course_code);
  297. $course_id = $course_info['real_id'];
  298. $table = Database :: get_course_table(TABLE_LINK);
  299. $table_prop = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  300. if (!empty($session_id) && !empty($course_code)) {
  301. $session_id = intval($session_id);
  302. if ($with_base_content) {
  303. $session_condition = api_get_session_condition($session_id, true, true);
  304. } else {
  305. $session_condition = api_get_session_condition($session_id, true);
  306. }
  307. $sql = "SELECT l.id, l.title, l.url, l.description, l.category_id, l.on_homepage
  308. FROM $table l, $table_prop p
  309. WHERE l.c_id = $course_id AND p.c_id = $course_id AND p.ref=l.id AND p.tool = '".TOOL_LINK."' AND p.visibility != 2 $session_condition
  310. ORDER BY l.display_order";
  311. } else {
  312. $sql = "SELECT l.id, l.title, l.url, l.description, l.category_id, l.on_homepage
  313. FROM $table l, $table_prop p
  314. WHERE l.c_id = $course_id AND p.c_id = $course_id AND p.ref=l.id AND p.tool = '".TOOL_LINK."' AND p.visibility != 2 AND l.session_id = 0
  315. ORDER BY l.display_order";
  316. }
  317. $db_result = Database::query($sql);
  318. while ($obj = Database::fetch_object($db_result)) {
  319. $link = new Link($obj->id, $obj->title, $obj->url, $obj->description, $obj->category_id, $obj->on_homepage);
  320. $this->course->add_resource($link);
  321. if (!empty($course_code)) {
  322. $res = $this->build_link_category($obj->category_id,$course_code);
  323. } else {
  324. $res = $this->build_link_category($obj->category_id);
  325. }
  326. if($res > 0) {
  327. $this->course->resources[RESOURCE_LINK][$obj->id]->add_linked_resource(RESOURCE_LINKCATEGORY, $obj->category_id);
  328. }
  329. }
  330. }
  331. /**
  332. * Build tool intro
  333. */
  334. function build_tool_intro($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  335. {
  336. $table = Database :: get_course_table(TABLE_TOOL_INTRO);
  337. $course_id = api_get_course_int_id();
  338. $sql = "SELECT * FROM $table WHERE c_id = $course_id ";
  339. $db_result = Database::query($sql);
  340. while ($obj = Database::fetch_object($db_result)) {
  341. $tool_intro = new ToolIntro($obj->id, $obj->intro_text);
  342. $this->course->add_resource($tool_intro);
  343. }
  344. }
  345. /**
  346. * Build a link category
  347. */
  348. function build_link_category($id, $course_code = '')
  349. {
  350. $course_info = api_get_course_info($course_code);
  351. $course_id = $course_info['real_id'];
  352. $link_cat_table = Database :: get_course_table(TABLE_LINK_CATEGORY);
  353. $sql = "SELECT * FROM $link_cat_table WHERE c_id = $course_id AND id = $id";
  354. $db_result = Database::query($sql);
  355. while ($obj = Database::fetch_object($db_result)) {
  356. $link_category = new LinkCategory($obj->id, $obj->category_title, $obj->description, $obj->display_order);
  357. $this->course->add_resource($link_category);
  358. return $id;
  359. }
  360. return 0;
  361. }
  362. /**
  363. * Build the Quizzes
  364. */
  365. function build_quizzes($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  366. {
  367. $course_info = api_get_course_info($course_code);
  368. $table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
  369. $table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  370. $table_doc = Database :: get_course_table(TABLE_DOCUMENT);
  371. $course_id = $course_info['real_id'];
  372. if (!empty($course_code) && !empty($session_id)) {
  373. $session_id = intval($session_id);
  374. if ($with_base_content) {
  375. $session_condition = api_get_session_condition($session_id, true, true);
  376. } else {
  377. $session_condition = api_get_session_condition($session_id, true);
  378. }
  379. $sql = "SELECT * FROM $table_qui WHERE c_id = $course_id AND active >=0 $session_condition"; //select only quizzes with active = 0 or 1 (not -1 which is for deleted quizzes)
  380. } else {
  381. $sql = "SELECT * FROM $table_qui WHERE c_id = $course_id AND active >=0 AND session_id = 0"; //select only quizzes with active = 0 or 1 (not -1 which is for deleted quizzes)
  382. }
  383. $db_result = Database::query($sql);
  384. while ($obj = Database::fetch_object($db_result)) {
  385. if (strlen($obj->sound) > 0) {
  386. $sql = "SELECT id FROM $table_doc WHERE c_id = $course_id AND path = '/audio/".$obj->sound."'";
  387. $res = Database::query($sql);
  388. $doc = Database::fetch_object($res);
  389. $obj->sound = $doc->id;
  390. }
  391. $exercise_obj = new Exercise($course_id);
  392. $exercise_obj->read($obj->iid);
  393. $categories = $exercise_obj->get_categories_with_name_in_exercise();
  394. $obj->categories = $categories;
  395. $quiz = new Quiz($obj);
  396. $sql = 'SELECT * FROM '.$table_rel.' WHERE c_id = '.$course_id.' AND exercice_id = '.$obj->iid;
  397. $db_result2 = Database::query($sql);
  398. while ($obj2 = Database::fetch_object($db_result2)) {
  399. $quiz->add_question($obj2->question_id, $obj2->question_order);
  400. }
  401. $this->course->add_resource($quiz);
  402. }
  403. if (!empty($course_code)) {
  404. $this->build_quiz_questions($course_code);
  405. } else {
  406. $this->build_quiz_questions();
  407. }
  408. }
  409. /**
  410. * Build the Quiz-Questions
  411. */
  412. function build_quiz_questions($course_code = null)
  413. {
  414. $course_info = api_get_course_info($course_code);
  415. $course_id = $course_info['real_id'];
  416. $table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
  417. $table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  418. $table_que = Database :: get_course_table(TABLE_QUIZ_QUESTION);
  419. $table_ans = Database :: get_course_table(TABLE_QUIZ_ANSWER);
  420. // Building normal tests.
  421. $sql = "SELECT * FROM $table_que WHERE c_id = $course_id ";
  422. $db_result = Database::query($sql);
  423. while ($obj = Database::fetch_object($db_result)) {
  424. $categories = Testcategory::getCategoryForQuestionWithCategoryData($obj->iid, $course_id, true);
  425. $parent_info = array();
  426. if (isset($obj->parent_id) && !empty($obj->parent_id)) {
  427. $parent_info = (array)Question::read($obj->parent_id, $course_id);
  428. }
  429. $question = new QuizQuestion($obj->iid, $obj->question, $obj->description, $obj->ponderation, $obj->type, $obj->position, $obj->picture, $obj->level, $obj->extra, $parent_info, $categories);
  430. $sql = 'SELECT * FROM '.$table_ans.' WHERE question_id = '.$obj->iid;
  431. $db_result2 = Database::query($sql);
  432. while ($obj2 = Database::fetch_object($db_result2)) {
  433. $question->add_answer($obj2->iid, $obj2->answer, $obj2->correct, $obj2->comment, $obj2->ponderation, $obj2->position, $obj2->hotspot_coordinates, $obj2->hotspot_type);
  434. if ($obj->type == MULTIPLE_ANSWER_TRUE_FALSE) {
  435. $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
  436. $sql = 'SELECT * FROM '.$table_options.' WHERE c_id = '.$course_id.' AND question_id = '.$obj->iid;
  437. $db_result3 = Database::query($sql);
  438. while ($obj3 = Database::fetch_object($db_result3)) {
  439. $question_option = new QuizQuestionOption($obj3);
  440. $question->add_option($question_option);
  441. }
  442. }
  443. }
  444. $this->course->add_resource($question);
  445. }
  446. // Building a fictional test for collecting orphan questions.
  447. $build_orphan_questions = !empty($_POST['recycle_option']); // When a course is emptied this option should be activated (true).
  448. //1st union gets the orphan questions from deleted exercises
  449. //2nd union gets the orphan questions from question that were deleted in a exercise.
  450. $sql = " (
  451. SELECT q.* FROM $table_que q INNER JOIN $table_rel r
  452. ON (q.c_id = r.c_id AND q.iid = r.question_id)
  453. INNER JOIN $table_qui ex
  454. ON (ex.iid = r.exercice_id AND ex.c_id = r.c_id )
  455. WHERE ex.c_id = $course_id AND ex.active = '-1'
  456. )
  457. UNION
  458. (
  459. SELECT q.* FROM $table_que q left
  460. OUTER JOIN $table_rel r
  461. ON (q.c_id = r.c_id AND q.iid = r.question_id)
  462. WHERE q.c_id = $course_id AND r.question_id is null
  463. )
  464. UNION
  465. (
  466. SELECT q.* FROM $table_que q
  467. INNER JOIN $table_rel r
  468. ON (q.c_id = r.c_id AND q.iid = r.question_id)
  469. WHERE r.c_id = $course_id AND (r.exercice_id = '-1' OR r.exercice_id = '0')
  470. )
  471. ";
  472. $db_result = Database::query($sql);
  473. if (Database::num_rows($db_result) > 0) {
  474. $build_orphan_questions = true;
  475. $orphanQuestionIds = array();
  476. while ($obj = Database::fetch_object($db_result)) {
  477. $categories = Testcategory::getCategoryForQuestionWithCategoryData($obj->iid, $course_id, true);
  478. $parent_info = array();
  479. if (isset($obj->parent_id) && !empty($obj->parent_id)) {
  480. $parent_info = (array)Question::read($obj->parent_id, $course_id);
  481. }
  482. //Avoid adding the same question twice
  483. if (!isset($this->course->resources[$obj->iid])) {
  484. $question = new QuizQuestion($obj->iid, $obj->question, $obj->description, $obj->ponderation, $obj->type, $obj->position, $obj->picture,$obj->level, $obj->extra, $parent_info, $categories);
  485. $sql = "SELECT * FROM $table_ans WHERE c_id = $course_id AND question_id = ".$obj->iid;
  486. $db_result2 = Database::query($sql);
  487. if (Database::num_rows($db_result2)) {
  488. while ($obj2 = Database::fetch_object($db_result2)) {
  489. $question->add_answer($obj2->iid, $obj2->answer, $obj2->correct, $obj2->comment, $obj2->ponderation, $obj2->position, $obj2->hotspot_coordinates, $obj2->hotspot_type);
  490. }
  491. $orphanQuestionIds[] = $obj->iid;
  492. }
  493. $this->course->add_resource($question);
  494. }
  495. }
  496. }
  497. if ($build_orphan_questions) {
  498. $obj = array(
  499. 'iid' => -1,
  500. 'title' => get_lang('OrphanQuestions', ''),
  501. 'type' => 2
  502. );
  503. $newQuiz = new Quiz((object)$obj);
  504. if (!empty($orphanQuestionIds)) {
  505. foreach ($orphanQuestionIds as $index => $orphanId) {
  506. $order = $index + 1;
  507. $newQuiz->add_question($orphanId, $order);
  508. }
  509. }
  510. $this->course->add_resource($newQuiz);
  511. }
  512. }
  513. /**
  514. * Build the orphan questions
  515. */
  516. function build_quiz_orphan_questions()
  517. {
  518. $table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
  519. $table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  520. $table_que = Database :: get_course_table(TABLE_QUIZ_QUESTION);
  521. $table_ans = Database :: get_course_table(TABLE_QUIZ_ANSWER);
  522. $course_id = api_get_course_int_id();
  523. $sql = 'SELECT *
  524. FROM '.$table_que.' as questions
  525. LEFT JOIN '.$table_rel.' as quizz_questions
  526. ON questions.id=quizz_questions.question_id
  527. LEFT JOIN '.$table_qui.' as exercices
  528. ON exercice_id=exercices.id
  529. WHERE questions.c_id = '.$course_id.' AND
  530. quizz_questions.c_id = '.$course_id.' AND
  531. exercices.c_id = '.$course_id.' AND
  532. (quizz_questions.exercice_id IS NULL OR
  533. exercices.active = -1)';
  534. $db_result = Database::query($sql);
  535. if (Database::num_rows($db_result) > 0) {
  536. // This is the fictional test for collecting orphan questions.
  537. $orphan_questions = new Quiz(-1, get_lang('OrphanQuestions', ''), '', 0, 0, 1, '', 0);
  538. $this->course->add_resource($orphan_questions);
  539. while ($obj = Database::fetch_object($db_result)) {
  540. $question = new QuizQuestion($obj->iid, $obj->question, $obj->description, $obj->ponderation, $obj->type, $obj->position, $obj->picture,$obj->level,$obj->extra);
  541. $sql = 'SELECT * FROM '.$table_ans.' WHERE question_id = '.$obj->iid;
  542. $db_result2 = Database::query($sql);
  543. while ($obj2 = Database::fetch_object($db_result2)) {
  544. $question->add_answer($obj2->iid, $obj2->answer, $obj2->correct, $obj2->comment, $obj2->ponderation, $obj2->position, $obj2->hotspot_coordinates, $obj2->hotspot_type);
  545. }
  546. $this->course->add_resource($question);
  547. }
  548. }
  549. }
  550. /**
  551. * Build the Surveys
  552. */
  553. function build_surveys($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  554. {
  555. $table_survey = Database :: get_course_table(TABLE_SURVEY);
  556. $table_question = Database :: get_course_table(TABLE_SURVEY_QUESTION);
  557. $course_id = api_get_course_int_id();
  558. $sql = 'SELECT * FROM '.$table_survey.' WHERE c_id = '.$course_id.' AND session_id = 0 ';
  559. $db_result = Database::query($sql);
  560. while ($obj = Database::fetch_object($db_result)) {
  561. $survey = new Survey($obj->survey_id, $obj->code,$obj->title,
  562. $obj->subtitle, $obj->author, $obj->lang,
  563. $obj->avail_from, $obj->avail_till, $obj->is_shared,
  564. $obj->template, $obj->intro, $obj->surveythanks,
  565. $obj->creation_date, $obj->invited, $obj->answered,
  566. $obj->invite_mail, $obj->reminder_mail);
  567. $sql = 'SELECT * FROM '.$table_question.' WHERE c_id = '.$course_id.' AND survey_id = '.$obj->survey_id;
  568. $db_result2 = Database::query($sql);
  569. while ($obj2 = Database::fetch_object($db_result2)){
  570. $survey->add_question($obj2->question_id);
  571. }
  572. $this->course->add_resource($survey);
  573. }
  574. $this->build_survey_questions();
  575. }
  576. /**
  577. * Build the Survey Questions
  578. */
  579. function build_survey_questions() {
  580. $table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
  581. $table_opt = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
  582. $course_id = api_get_course_int_id();
  583. $sql = 'SELECT * FROM '.$table_que.' WHERE c_id = '.$course_id.' ';
  584. $db_result = Database::query($sql);
  585. while ($obj = Database::fetch_object($db_result)){
  586. $question = new SurveyQuestion($obj->question_id, $obj->survey_id,
  587. $obj->survey_question, $obj->survey_question_comment,
  588. $obj->type, $obj->display, $obj->sort,
  589. $obj->shared_question_id, $obj->max_value);
  590. $sql = 'SELECT * FROM '.$table_opt.' WHERE c_id = '.$course_id.' AND question_id = '.$obj->question_id;
  591. $db_result2 = Database::query($sql);
  592. while ($obj2 = Database::fetch_object($db_result2)) {
  593. $question->add_answer($obj2->option_text, $obj2->sort);
  594. }
  595. $this->course->add_resource($question);
  596. }
  597. }
  598. /**
  599. * Build the announcements
  600. */
  601. function build_announcements($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  602. $table = Database :: get_course_table(TABLE_ANNOUNCEMENT);
  603. $course_id = api_get_course_int_id();
  604. $sql = 'SELECT * FROM '.$table.' WHERE c_id = '.$course_id.' AND session_id = 0';
  605. $db_result = Database::query($sql);
  606. $table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
  607. while ($obj = Database::fetch_object($db_result)) {
  608. $sql = 'SELECT path, comment, filename, size FROM '.$table_attachment.' WHERE c_id = '.$course_id.' AND announcement_id = '.$obj->id.'';
  609. $result = Database::query($sql);
  610. $attachment_obj = Database::fetch_object($result);
  611. $att_path = $att_filename = $att_size = $atth_comment = '';
  612. if (!empty($attachment_obj)) {
  613. $att_path = $attachment_obj->path;
  614. $att_filename = $attachment_obj->filename;
  615. $att_size = $attachment_obj->size;
  616. $atth_comment = $attachment_obj->comment;
  617. }
  618. $announcement = new Announcement($obj->id, $obj->title, $obj->content, $obj->end_date,$obj->display_order,$obj->email_sent, $att_path, $att_filename, $att_size, $atth_comment);
  619. $this->course->add_resource($announcement);
  620. }
  621. }
  622. /**
  623. * Build the events
  624. */
  625. function build_events($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  626. $table = Database :: get_course_table(TABLE_AGENDA);
  627. $course_id = api_get_course_int_id();
  628. $sql = 'SELECT * FROM '.$table.' WHERE c_id = '.$course_id.' AND session_id = 0';
  629. $db_result = Database::query($sql);
  630. while ($obj = Database::fetch_object($db_result)) {
  631. $table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
  632. $sql = 'SELECT path, comment, filename, size FROM '.$table_attachment.' WHERE c_id = '.$course_id.' AND agenda_id = '.$obj->id.'';
  633. $result = Database::query($sql);
  634. $attachment_obj = Database::fetch_object($result);
  635. $att_path = $att_filename = $att_size = $atth_comment = '';
  636. if (!empty($attachment_obj)) {
  637. $att_path = $attachment_obj->path;
  638. $att_filename = $attachment_obj->filename;
  639. $att_size = $attachment_obj->size;
  640. $atth_comment = $attachment_obj->comment;
  641. }
  642. $event = new Event($obj->id, $obj->title, $obj->content, $obj->start_date, $obj->end_date, $att_path, $att_filename, $att_size, $atth_comment, $obj->all_day);
  643. $this->course->add_resource($event);
  644. }
  645. }
  646. /**
  647. * Build the course-descriptions
  648. */
  649. function build_course_descriptions($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  650. $course_info = api_get_course_info($course_code);
  651. $course_id = $course_info['real_id'];
  652. $table = Database :: get_course_table(TABLE_COURSE_DESCRIPTION);
  653. if (!empty($session_id) && !empty($course_code)) {
  654. $session_id = intval($session_id);
  655. if ($with_base_content) {
  656. $session_condition = api_get_session_condition($session_id, true, true);
  657. } else {
  658. $session_condition = api_get_session_condition($session_id, true);
  659. }
  660. $sql = 'SELECT * FROM '.$table. ' WHERE c_id = '.$course_id.' '.$session_condition;
  661. } else {
  662. $table = Database :: get_course_table(TABLE_COURSE_DESCRIPTION);
  663. $sql = 'SELECT * FROM '.$table. ' WHERE c_id = '.$course_id.' AND session_id = 0';
  664. }
  665. $db_result = Database::query($sql);
  666. while ($obj = Database::fetch_object($db_result)) {
  667. $cd = new CourseDescription($obj->id, $obj->title, $obj->content, $obj->description_type);
  668. $this->course->add_resource($cd);
  669. }
  670. }
  671. /**
  672. * Build the learnpaths
  673. */
  674. function build_learnpaths($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  675. $course_info = api_get_course_info($course_code);
  676. $course_id = $course_info['real_id'];
  677. $table_main = Database::get_course_table(TABLE_LP_MAIN);
  678. $table_item = Database::get_course_table(TABLE_LP_ITEM);
  679. $table_tool = Database::get_course_table(TABLE_TOOL_LIST);
  680. if (!empty($session_id) && !empty($course_code)) {
  681. $session_id = intval($session_id);
  682. if ($with_base_content) {
  683. $session_condition = api_get_session_condition($session_id, true, true);
  684. } else {
  685. $session_condition = api_get_session_condition($session_id, true);
  686. }
  687. $sql = 'SELECT * FROM '.$table_main.' WHERE c_id = '.$course_id.' '.$session_condition;
  688. } else {
  689. $sql = 'SELECT * FROM '.$table_main.' WHERE c_id = '.$course_id.' AND session_id = 0';
  690. }
  691. if (!empty($id_list)) {
  692. $id_list = array_map('intval', $id_list);
  693. $sql .=" AND id IN (".implode(', ', $id_list).") ";
  694. }
  695. $db_result = Database::query($sql);
  696. if ($db_result)
  697. while ($obj = Database::fetch_object($db_result)) {
  698. $items = array();
  699. $sql_items = "SELECT * FROM ".$table_item." WHERE c_id = '$course_id' AND lp_id = ".$obj->id;
  700. $db_items = Database::query($sql_items);
  701. while ($obj_item = Database::fetch_object($db_items)) {
  702. $item['id'] = $obj_item->id;
  703. $item['item_type'] = $obj_item->item_type;
  704. $item['ref'] = $obj_item->ref;
  705. $item['title'] = $obj_item->title;
  706. $item['description'] = $obj_item->description;
  707. $item['path'] = $obj_item->path;
  708. $item['min_score'] = $obj_item->min_score;
  709. $item['max_score'] = $obj_item->max_score;
  710. $item['mastery_score'] = $obj_item->mastery_score;
  711. $item['parent_item_id'] = $obj_item->parent_item_id;
  712. $item['previous_item_id'] = $obj_item->previous_item_id;
  713. $item['next_item_id'] = $obj_item->next_item_id;
  714. $item['display_order'] = $obj_item->display_order;
  715. $item['prerequisite'] = $obj_item->prerequisite;
  716. $item['parameters'] = $obj_item->parameters;
  717. $item['launch_data'] = $obj_item->launch_data;
  718. $item['audio'] = $obj_item->audio;
  719. $items[] = $item;
  720. }
  721. $sql_tool = "SELECT id FROM $table_tool
  722. WHERE c_id = $course_id AND
  723. (link LIKE '%lp_controller.php%lp_id=".$obj->id."%' AND image='scormbuilder.gif') AND
  724. visibility = '1' ";
  725. $db_tool = Database::query($sql_tool);
  726. if (Database::num_rows($db_tool)) {
  727. $visibility = '1';
  728. } else {
  729. $visibility = '0';
  730. }
  731. $lp = new CourseCopyLearnpath(
  732. $obj->id,
  733. $obj->lp_type,
  734. $obj->name,
  735. $obj->path,
  736. $obj->ref,
  737. $obj->description,
  738. $obj->content_local,
  739. $obj->default_encoding,
  740. $obj->default_view_mod,
  741. $obj->prevent_reinit,
  742. $obj->force_commit,
  743. $obj->content_maker,
  744. $obj->display_order,
  745. $obj->js_lib,
  746. $obj->content_license,
  747. $obj->debug,
  748. $visibility,
  749. $obj->author,
  750. $obj->preview_image,
  751. $obj->use_max_score,
  752. $obj->autolunch,
  753. $obj->created_on,
  754. $obj->modified_on,
  755. $obj->publicated_on,
  756. $obj->expired_on,
  757. $obj->session_id,
  758. $items);
  759. $this->course->add_resource($lp);
  760. }
  761. //save scorm directory (previously build_scorm_documents())
  762. $i = 1;
  763. if ($dir=@opendir($this->course->backup_path.'/scorm')) {
  764. while($file=readdir($dir)) {
  765. if(is_dir($this->course->backup_path.'/scorm/'.$file) && !in_array($file,array('.','..'))) {
  766. $doc = new ScormDocument($i++, '/'.$file, $file);
  767. $this->course->add_resource($doc);
  768. }
  769. }
  770. closedir($dir);
  771. }
  772. }
  773. /**
  774. * Build the glossarys
  775. */
  776. function build_glossary($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  777. $course_info = api_get_course_info($course_code);
  778. $table_glossary = Database :: get_course_table(TABLE_GLOSSARY);
  779. $course_id = $course_info['real_id'];
  780. if (!empty($session_id) && !empty($course_code)) {
  781. $session_id = intval($session_id);
  782. if ($with_base_content) {
  783. $session_condition = api_get_session_condition($session_id, true, true);
  784. } else {
  785. $session_condition = api_get_session_condition($session_id, true);
  786. }
  787. //@todo check this queries are the same ...
  788. if (!empty($this->course->type) && $this->course->type=='partial') {
  789. $sql = 'SELECT * FROM '.$table_glossary.' g WHERE g.c_id = '.$course_id.' '.$session_condition;
  790. } else {
  791. $sql = 'SELECT * FROM '.$table_glossary.' g WHERE g.c_id = '.$course_id.' '.$session_condition;
  792. }
  793. } else {
  794. $table_glossary = Database :: get_course_table(TABLE_GLOSSARY);
  795. //@todo check this queries are the same ... ayayay
  796. if (!empty($this->course->type) && $this->course->type=='partial') {
  797. $sql = 'SELECT * FROM '.$table_glossary.' g WHERE g.c_id = '.$course_id.' AND session_id = 0';
  798. } else {
  799. $sql = 'SELECT * FROM '.$table_glossary.' g WHERE g.c_id = '.$course_id.' AND session_id = 0';
  800. }
  801. }
  802. $db_result = Database::query($sql);
  803. while ($obj = Database::fetch_object($db_result)) {
  804. $doc = new Glossary($obj->glossary_id, $obj->name, $obj->description, $obj->display_order);
  805. $this->course->add_resource($doc);
  806. }
  807. }
  808. /*
  809. * build session course by jhon
  810. * */
  811. function build_session_course(){
  812. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  813. $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  814. $list_course = CourseManager::get_course_list();
  815. $list = array();
  816. foreach($list_course as $_course) {
  817. $this->course = new Course();
  818. $this->course->code = $_course['code'];
  819. $this->course->type = 'partial';
  820. $this->course->path = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/';
  821. $this->course->backup_path = api_get_path(SYS_COURSE_PATH).$_course['directory'];
  822. $this->course->encoding = api_get_system_encoding(); //current platform encoding
  823. //$code_course = $_course['code'];
  824. $courseId = $_course['real_id'];
  825. $sql_session = "SELECT id, name, c_id
  826. FROM $tbl_session_course INNER JOIN $tbl_session ON id_session = id
  827. WHERE c_id = '$courseId' ";
  828. $query_session = Database::query($sql_session);
  829. while ($rows_session = Database::fetch_assoc($query_session)) {
  830. $session = new CourseSession($rows_session['id'], $rows_session['name']);
  831. $this->course->add_resource($session);
  832. }
  833. $list[] = $this->course;
  834. }
  835. return $list;
  836. }
  837. function build_wiki($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  838. $course_info = api_get_course_info($course_code);
  839. $tbl_wiki = Database::get_course_table(TABLE_WIKI);
  840. $course_id = $course_info['real_id'];
  841. if (!empty($session_id) && !empty($course_code)) {
  842. $session_id = intval($session_id);
  843. if ($with_base_content) {
  844. $session_condition = api_get_session_condition($session_id, true, true);
  845. } else {
  846. $session_condition = api_get_session_condition($session_id, true);
  847. }
  848. $sql = 'SELECT * FROM ' . $tbl_wiki . ' WHERE c_id = '.$course_id.' '.$session_condition;
  849. } else {
  850. $tbl_wiki = Database::get_course_table(TABLE_WIKI);
  851. $sql = 'SELECT * FROM ' . $tbl_wiki . ' WHERE c_id = '.$course_id.' AND session_id = 0';
  852. }
  853. $db_result = Database::query($sql);
  854. while ($obj = Database::fetch_object($db_result)) {
  855. $wiki = new Wiki($obj->id, $obj->page_id, $obj->reflink, $obj->title, $obj->content, $obj->user_id, $obj->group_id, $obj->dtime, $obj->progress, $obj->version);
  856. $this->course->add_resource($wiki);
  857. }
  858. }
  859. /**
  860. * Build the Surveys
  861. */
  862. function build_thematic($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  863. {
  864. $table_thematic = Database :: get_course_table(TABLE_THEMATIC);
  865. $table_thematic_advance = Database :: get_course_table(TABLE_THEMATIC_ADVANCE);
  866. $table_thematic_plan = Database :: get_course_table(TABLE_THEMATIC_PLAN);
  867. $session_id = intval($session_id);
  868. if ($with_base_content) {
  869. $session_condition = api_get_session_condition($session_id, true, true);
  870. } else {
  871. $session_condition = api_get_session_condition($session_id, true);
  872. }
  873. $course_id = api_get_course_int_id();
  874. $courseInfo = api_get_course_info();
  875. $sql = "SELECT * FROM $table_thematic WHERE c_id = $course_id $session_condition ";
  876. $db_result = Database::query($sql);
  877. while ($row = Database::fetch_array($db_result,'ASSOC')) {
  878. $thematic = new Thematic($courseInfo);
  879. $sql = 'SELECT * FROM '.$table_thematic_advance.' WHERE c_id = '.$course_id.' AND thematic_id = '.$row['id'];
  880. $result = Database::query($sql);
  881. while ($sub_row = Database::fetch_array($result,'ASSOC')) {
  882. $thematic->add_thematic_advance($sub_row);
  883. }
  884. $items = api_get_item_property_by_tool('thematic_plan', api_get_course_id(), $session_id);
  885. //$items_from_session = api_get_item_property_by_tool('thematic_plan', api_get_course_id(), api_get_session_id());
  886. $thematic_plan_id_list = array();
  887. if (!empty($items)) {
  888. foreach($items as $item) {
  889. $thematic_plan_id_list[] = $item['ref'];
  890. //$thematic_plan_complete_list[$item['ref']] = $item;
  891. }
  892. }
  893. //$sql = 'SELECT * FROM '.$table_thematic_plan.' WHERE c_id = '.$course_id.' AND thematic_id = '.$row['id'];
  894. $sql = "SELECT tp.*
  895. FROM $table_thematic_plan tp
  896. INNER JOIN $table_thematic t ON (t.id=tp.thematic_id)
  897. WHERE t.c_id = $course_id AND
  898. tp.c_id = $course_id AND
  899. thematic_id = {$row['id']} AND
  900. tp.id IN (".implode(', ', $thematic_plan_id_list).") ";
  901. $result = Database::query($sql);
  902. while ($sub_row = Database::fetch_array($result,'ASSOC')) {
  903. $thematic->add_thematic_plan($sub_row);
  904. }
  905. $this->course->add_resource($thematic);
  906. }
  907. }
  908. /**
  909. * Build the attendances
  910. */
  911. function build_attendance($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array()) {
  912. $table_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
  913. $table_attendance_calendar = Database :: get_course_table(TABLE_ATTENDANCE_CALENDAR);
  914. $course_id = api_get_course_int_id();
  915. $sql = 'SELECT * FROM '.$table_attendance.' WHERE c_id = '.$course_id.' AND session_id = 0 ';
  916. $db_result = Database::query($sql);
  917. while ($row = Database::fetch_array($db_result,'ASSOC')) {
  918. $obj = new CourseCopyAttendance($row);
  919. $sql = 'SELECT * FROM '.$table_attendance_calendar.' WHERE c_id = '.$course_id.' AND attendance_id = '.$row['id'];
  920. $result = Database::query($sql);
  921. while ($sub_row = Database::fetch_array($result,'ASSOC')) {
  922. $obj->add_attendance_calendar($sub_row);
  923. }
  924. $this->course->add_resource($obj);
  925. }
  926. }
  927. /**
  928. * Build the works (or "student publications", or "assignments")
  929. */
  930. function build_works($session_id = 0, $course_code = '', $with_base_content = false, $id_list = array())
  931. {
  932. $table_work = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
  933. //$table_work_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
  934. $course_id = api_get_course_int_id();
  935. $sql = 'SELECT * FROM '.$table_work.' WHERE c_id = '.$course_id.' AND session_id = 0 AND filetype = \'folder\' AND parent_id = 0 AND active = 1';
  936. $db_result = Database::query($sql);
  937. while ($row = Database::fetch_array($db_result,'ASSOC')) {
  938. $obj = new Work($row);
  939. $this->course->add_resource($obj);
  940. }
  941. }
  942. }