CourseBuilder.class.php 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. require_once 'Resource.class.php';
  4. require_once 'Course.class.php';
  5. require_once 'Event.class.php';
  6. require_once 'Link.class.php';
  7. require_once 'ToolIntro.class.php';
  8. require_once 'Document.class.php';
  9. require_once 'ScormDocument.class.php';
  10. require_once 'LinkCategory.class.php';
  11. require_once 'CourseDescription.class.php';
  12. require_once 'ForumPost.class.php';
  13. require_once 'ForumTopic.class.php';
  14. require_once 'Forum.class.php';
  15. require_once 'ForumCategory.class.php';
  16. require_once 'Quiz.class.php';
  17. require_once 'QuizQuestion.class.php';
  18. require_once 'CourseCopyTestCategory.php';
  19. require_once 'CourseCopyLearnpath.class.php';
  20. require_once 'Survey.class.php';
  21. require_once 'SurveyQuestion.class.php';
  22. require_once 'Glossary.class.php';
  23. require_once 'CourseSession.class.php';
  24. require_once 'wiki.class.php';
  25. require_once 'Thematic.class.php';
  26. require_once 'Attendance.class.php';
  27. require_once 'Work.class.php';
  28. require_once 'QuizQuestionOption.class.php';
  29. /**
  30. * Class CourseBuilder
  31. * Builds a course-object from a Chamilo-course.
  32. * @author Bart Mollet <bart.mollet@hogent.be>
  33. * @package chamilo.backup
  34. */
  35. class CourseBuilder
  36. {
  37. /** @var Course */
  38. public $course;
  39. /* With this array you can filter the tools you want to be parsed by
  40. default all tools are included */
  41. public $tools_to_build = array(
  42. 'announcements',
  43. 'attendance',
  44. 'course_descriptions',
  45. 'documents',
  46. 'events',
  47. 'forum_category',
  48. 'forums',
  49. 'forum_topics',
  50. 'glossary',
  51. 'quizzes',
  52. 'test_category',
  53. 'learnpaths',
  54. 'links',
  55. 'surveys',
  56. 'tool_intro',
  57. 'thematic',
  58. 'wiki',
  59. 'works'
  60. );
  61. /* With this array you can filter wich elements of the tools are going
  62. to be added in the course obj (only works with LPs) */
  63. public $specific_id_list = array();
  64. /**
  65. * Create a new CourseBuilder
  66. * @param string $type
  67. * @param null $course
  68. */
  69. public function __construct($type = '', $course = null)
  70. {
  71. $_course = api_get_course_info();
  72. if (!empty($course['official_code'])) {
  73. $_course = $course;
  74. }
  75. $this->course = new Course();
  76. $this->course->code = $_course['official_code'];
  77. $this->course->type = $type;
  78. $this->course->path = api_get_path(SYS_COURSE_PATH).$_course['path'].'/';
  79. $this->course->backup_path = api_get_path(SYS_COURSE_PATH).$_course['path'];
  80. $this->course->encoding = api_get_system_encoding();
  81. $this->course->info = $_course;
  82. }
  83. /**
  84. * @param array $array
  85. */
  86. public function set_tools_to_build($array)
  87. {
  88. $this->tools_to_build = $array;
  89. }
  90. /**
  91. *
  92. * @param array $array
  93. */
  94. public function set_tools_specific_id_list($array)
  95. {
  96. $this->specific_id_list = $array;
  97. }
  98. /**
  99. * Get the created course
  100. * @return course The course
  101. */
  102. public function get_course()
  103. {
  104. return $this->course;
  105. }
  106. /**
  107. * Build the course-object
  108. *
  109. * @param int $session_id
  110. * @param string $courseCode
  111. * @param bool true if you want to get the elements that exists in the course and
  112. * in the session, (session_id = 0 or session_id = X)
  113. * @return object The course object structure
  114. */
  115. public function build(
  116. $session_id = 0,
  117. $courseCode = '',
  118. $with_base_content = false
  119. ) {
  120. $table_link = Database:: get_course_table(TABLE_LINKED_RESOURCES);
  121. $table_properties = Database:: get_course_table(TABLE_ITEM_PROPERTY);
  122. $course = api_get_course_info($courseCode);
  123. $courseId = $course['real_id'];
  124. foreach ($this->tools_to_build as $tool) {
  125. $function_build = 'build_'.$tool;
  126. $specificIdList = isset($this->specific_id_list[$tool]) ? $this->specific_id_list[$tool] : null;
  127. $this->$function_build(
  128. $session_id,
  129. $courseId,
  130. $with_base_content,
  131. $specificIdList
  132. );
  133. }
  134. //TABLE_LINKED_RESOURCES is the "resource" course table, which is deprecated, apparently
  135. foreach ($this->course->resources as $type => $resources) {
  136. foreach ($resources as $id => $resource) {
  137. $sql = "SELECT * FROM $table_link
  138. WHERE
  139. c_id = $courseId AND
  140. source_type = '".$resource->get_type()."' AND
  141. source_id = '".$resource->get_id()."'";
  142. $res = Database::query($sql);
  143. while ($link = Database::fetch_object($res)) {
  144. $this->course->resources[$type][$id]->add_linked_resource(
  145. $link->resource_type,
  146. $link->resource_id
  147. );
  148. }
  149. }
  150. }
  151. // Once we've built the resources array a bit more, try to get items
  152. // from the item_property table and order them in the "resources" array
  153. foreach ($this->course->resources as $type => $resources) {
  154. foreach ($resources as $id => $resource) {
  155. $tool = $resource->get_tool();
  156. if ($tool != null) {
  157. $sql = "SELECT * FROM $table_properties
  158. WHERE
  159. c_id = $courseId AND
  160. tool = '".$tool."' AND
  161. ref='".$resource->get_id()."'";
  162. $res = Database::query($sql);
  163. $all_properties = array();
  164. while ($item_property = Database::fetch_array($res)) {
  165. $all_properties[] = $item_property;
  166. }
  167. $this->course->resources[$type][$id]->item_properties = $all_properties;
  168. }
  169. }
  170. }
  171. return $this->course;
  172. }
  173. /**
  174. * Build the documents
  175. * @param int $session_id
  176. * @param int $courseId
  177. * @param bool $with_base_content
  178. * @param array $id_list
  179. */
  180. public function build_documents(
  181. $session_id = 0,
  182. $courseId = 0,
  183. $with_base_content = false,
  184. $id_list = array()
  185. ) {
  186. $table_doc = Database::get_course_table(TABLE_DOCUMENT);
  187. $table_prop = Database::get_course_table(TABLE_ITEM_PROPERTY);
  188. //Remove chat_files and shared_folder files
  189. $avoid_paths = " path NOT LIKE '/shared_folder%' AND
  190. path NOT LIKE '/chat_files%' ";
  191. //$avoid_paths = " 1 = 1 ";
  192. if (!empty($courseId) && !empty($session_id)) {
  193. $session_id = intval($session_id);
  194. if ($with_base_content) {
  195. $session_condition = api_get_session_condition(
  196. $session_id,
  197. true,
  198. true,
  199. 'd.session_id'
  200. );
  201. } else {
  202. $session_condition = api_get_session_condition(
  203. $session_id,
  204. true,
  205. false,
  206. 'd.session_id'
  207. );
  208. }
  209. if (!empty($this->course->type) && $this->course->type == 'partial') {
  210. $sql = "SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size
  211. FROM $table_doc d INNER JOIN $table_prop p
  212. ON (p.ref = d.id AND d.c_id = p.c_id)
  213. WHERE
  214. d.c_id = $courseId AND
  215. p.c_id = $courseId AND
  216. tool = '".TOOL_DOCUMENT."' AND
  217. p.visibility != 2 AND
  218. path NOT LIKE '/images/gallery%' AND
  219. $avoid_paths
  220. $session_condition
  221. ORDER BY path";
  222. } else {
  223. $sql = "SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size
  224. FROM $table_doc d INNER JOIN $table_prop p
  225. ON (p.ref = d.id AND d.c_id = p.c_id)
  226. WHERE
  227. d.c_id = $courseId AND
  228. p.c_id = $courseId AND
  229. tool = '".TOOL_DOCUMENT."' AND
  230. $avoid_paths AND
  231. p.visibility != 2 $session_condition
  232. ORDER BY path";
  233. }
  234. $db_result = Database::query($sql);
  235. while ($obj = Database::fetch_object($db_result)) {
  236. $doc = new Document(
  237. $obj->id,
  238. $obj->path,
  239. $obj->comment,
  240. $obj->title,
  241. $obj->filetype,
  242. $obj->size
  243. );
  244. $this->course->add_resource($doc);
  245. }
  246. } else {
  247. if (!empty($this->course->type) && $this->course->type == 'partial') {
  248. $sql = "SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size
  249. FROM $table_doc d INNER JOIN $table_prop p
  250. ON (p.ref = d.id AND d.c_id = p.c_id)
  251. WHERE
  252. d.c_id = $courseId AND
  253. p.c_id = $courseId AND
  254. tool = '".TOOL_DOCUMENT."' AND
  255. p.visibility != 2 AND
  256. path NOT LIKE '/images/gallery%' AND
  257. $avoid_paths AND
  258. d.session_id = 0
  259. ORDER BY path";
  260. } else {
  261. $sql = "SELECT d.id, d.path, d.comment, d.title, d.filetype, d.size
  262. FROM $table_doc d INNER JOIN $table_prop p
  263. ON (p.ref = d.id AND d.c_id = p.c_id)
  264. WHERE
  265. d.c_id = $courseId AND
  266. p.c_id = $courseId AND
  267. tool = '".TOOL_DOCUMENT."' AND
  268. p.visibility != 2 AND
  269. $avoid_paths AND
  270. d.session_id = 0
  271. ORDER BY path";
  272. }
  273. $db_result = Database::query($sql);
  274. while ($obj = Database::fetch_object($db_result)) {
  275. $doc = new Document(
  276. $obj->id,
  277. $obj->path,
  278. $obj->comment,
  279. $obj->title,
  280. $obj->filetype,
  281. $obj->size
  282. );
  283. $this->course->add_resource($doc);
  284. }
  285. }
  286. }
  287. /**
  288. * Build the forums
  289. * @param int $session_id Internal session ID
  290. * @param int $courseId Internal course ID
  291. * @param bool $with_base_content Whether to include content from the course without session or not
  292. * @param array $id_list If you want to restrict the structure to only the given IDs
  293. * @return void
  294. */
  295. public function build_forums(
  296. $session_id = 0,
  297. $courseId = 0,
  298. $with_base_content = false,
  299. $id_list = array()
  300. ) {
  301. $table = Database:: get_course_table(TABLE_FORUM);
  302. $sessionCondition = api_get_session_condition(
  303. $session_id,
  304. true,
  305. $with_base_content
  306. );
  307. $sql = "SELECT * FROM $table WHERE c_id = $courseId $sessionCondition";
  308. $sql .= " ORDER BY forum_title, forum_category";
  309. $db_result = Database::query($sql);
  310. while ($obj = Database::fetch_object($db_result)) {
  311. $forum = new Forum($obj);
  312. $this->course->add_resource($forum);
  313. }
  314. }
  315. /**
  316. * Build a forum-category
  317. * @param int $session_id Internal session ID
  318. * @param int $courseId Internal course ID
  319. * @param bool $with_base_content Whether to include content from the course without session or not
  320. * @param array $id_list If you want to restrict the structure to only the given IDs
  321. * @return void
  322. */
  323. public function build_forum_category(
  324. $session_id = 0,
  325. $courseId = 0,
  326. $with_base_content = false,
  327. $id_list = array()
  328. ) {
  329. $table = Database:: get_course_table(TABLE_FORUM_CATEGORY);
  330. $sessionCondition = api_get_session_condition(
  331. $session_id,
  332. true,
  333. $with_base_content
  334. );
  335. $sql = "SELECT * FROM $table
  336. WHERE c_id = $courseId $sessionCondition
  337. ORDER BY cat_title";
  338. $result = Database::query($sql);
  339. while ($obj = Database::fetch_object($result)) {
  340. $forumCategory = new ForumCategory($obj);
  341. $this->course->add_resource($forumCategory);
  342. }
  343. }
  344. /**
  345. * Build the forum-topics
  346. * @param int $session_id Internal session ID
  347. * @param int $courseId Internal course ID
  348. * @param bool $with_base_content Whether to include content from the course without session or not
  349. * @param array $id_list If you want to restrict the structure to only the given IDs
  350. * @return void
  351. */
  352. public function build_forum_topics(
  353. $session_id = 0,
  354. $courseId = 0,
  355. $with_base_content = false,
  356. $id_list = array()
  357. ) {
  358. $table = Database:: get_course_table(TABLE_FORUM_THREAD);
  359. $sessionCondition = api_get_session_condition(
  360. $session_id,
  361. true,
  362. $with_base_content
  363. );
  364. $sql = "SELECT * FROM $table WHERE c_id = $courseId
  365. $sessionCondition
  366. ORDER BY thread_title ";
  367. $db_result = Database::query($sql);
  368. while ($obj = Database::fetch_object($db_result)) {
  369. $forum_topic = new ForumTopic($obj);
  370. $this->course->add_resource($forum_topic);
  371. $this->build_forum_posts($courseId, $obj->thread_id, $obj->forum_id, true);
  372. }
  373. }
  374. /**
  375. * Build the forum-posts
  376. * TODO: All tree structure of posts should be built, attachments for example.
  377. * @param int $courseId Internal course ID
  378. * @param int $thread_id Internal thread ID
  379. * @param int $forum_id Internal forum ID
  380. * @param bool $only_first_post Whether to only copy the first post or not
  381. */
  382. public function build_forum_posts(
  383. $courseId = 0,
  384. $thread_id = null,
  385. $forum_id = null,
  386. $only_first_post = false
  387. ) {
  388. $table = Database :: get_course_table(TABLE_FORUM_POST);
  389. $sql = "SELECT * FROM $table WHERE c_id = $courseId ";
  390. if (!empty($thread_id) && !empty($forum_id)) {
  391. $forum_id = intval($forum_id);
  392. $thread_id = intval($thread_id);
  393. $sql .= " AND thread_id = $thread_id AND forum_id = $forum_id ";
  394. }
  395. $sql .= " ORDER BY post_id ASC LIMIT 1";
  396. $db_result = Database::query($sql);
  397. while ($obj = Database::fetch_object($db_result)) {
  398. $forum_post = new ForumPost($obj);
  399. $this->course->add_resource($forum_post);
  400. }
  401. }
  402. /**
  403. * Build the links
  404. * @param int $session_id Internal session ID
  405. * @param int $courseId Internal course ID
  406. * @param bool $with_base_content Whether to include content from the course without session or not
  407. * @param array $id_list If you want to restrict the structure to only the given IDs
  408. */
  409. public function build_links(
  410. $session_id = 0,
  411. $courseId = 0,
  412. $with_base_content = false,
  413. $id_list = array()
  414. ) {
  415. $table = Database :: get_course_table(TABLE_LINK);
  416. $table_prop = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  417. if (!empty($session_id) && !empty($courseId)) {
  418. $session_id = intval($session_id);
  419. if ($with_base_content) {
  420. $session_condition = api_get_session_condition(
  421. $session_id,
  422. true,
  423. true,
  424. 'l.session_id'
  425. );
  426. } else {
  427. $session_condition = api_get_session_condition(
  428. $session_id,
  429. true,
  430. false,
  431. 'l.session_id'
  432. );
  433. }
  434. $sql = "SELECT l.id, l.title, l.url, l.description, l.category_id, l.on_homepage
  435. FROM $table l, $table_prop p
  436. WHERE
  437. l.c_id = $courseId AND
  438. p.c_id = $courseId AND
  439. p.ref=l.id AND
  440. p.tool = '".TOOL_LINK."' AND
  441. p.visibility != 2 $session_condition
  442. ORDER BY l.display_order";
  443. } else {
  444. $sql = "SELECT l.id, l.title, l.url, l.description, l.category_id, l.on_homepage
  445. FROM $table l, $table_prop p
  446. WHERE
  447. l.c_id = $courseId AND
  448. p.c_id = $courseId AND
  449. p.ref=l.id AND
  450. p.tool = '".TOOL_LINK."' AND
  451. p.visibility != 2 AND
  452. l.session_id = 0
  453. ORDER BY l.display_order";
  454. }
  455. $db_result = Database::query($sql);
  456. while ($obj = Database::fetch_object($db_result)) {
  457. $link = new Link(
  458. $obj->id,
  459. $obj->title,
  460. $obj->url,
  461. $obj->description,
  462. $obj->category_id,
  463. $obj->on_homepage
  464. );
  465. $this->course->add_resource($link);
  466. if (!empty($courseId)) {
  467. $res = $this->build_link_category($obj->category_id, $courseId);
  468. } else {
  469. $res = $this->build_link_category($obj->category_id);
  470. }
  471. if ($res > 0) {
  472. $this->course->resources[RESOURCE_LINK][$obj->id]->add_linked_resource(
  473. RESOURCE_LINKCATEGORY,
  474. $obj->category_id
  475. );
  476. }
  477. }
  478. }
  479. /**
  480. * Build tool intro
  481. * @param int $session_id Internal session ID
  482. * @param int $courseId Internal course ID
  483. * @param bool $with_base_content Whether to include content from the course without session or not
  484. * @param array $id_list If you want to restrict the structure to only the given IDs
  485. */
  486. public function build_tool_intro(
  487. $session_id = 0,
  488. $courseId = 0,
  489. $with_base_content = false,
  490. $id_list = array()
  491. ) {
  492. $table = Database:: get_course_table(TABLE_TOOL_INTRO);
  493. $sessionCondition = api_get_session_condition(
  494. $session_id,
  495. true,
  496. $with_base_content
  497. );
  498. $sql = "SELECT * FROM $table WHERE c_id = $courseId $sessionCondition";
  499. $db_result = Database::query($sql);
  500. while ($obj = Database::fetch_object($db_result)) {
  501. $tool_intro = new ToolIntro($obj->id, $obj->intro_text);
  502. $this->course->add_resource($tool_intro);
  503. }
  504. }
  505. /**
  506. * Build a link category
  507. * @param int $id Internal link ID
  508. * @param int $courseId Internal course ID
  509. * @return int
  510. */
  511. public function build_link_category($id, $courseId = 0)
  512. {
  513. $link_cat_table = Database :: get_course_table(TABLE_LINK_CATEGORY);
  514. $sql = "SELECT * FROM $link_cat_table
  515. WHERE c_id = $courseId AND id = $id";
  516. $db_result = Database::query($sql);
  517. while ($obj = Database::fetch_object($db_result)) {
  518. $link_category = new LinkCategory(
  519. $obj->id,
  520. $obj->category_title,
  521. $obj->description,
  522. $obj->display_order
  523. );
  524. $this->course->add_resource($link_category);
  525. return $id;
  526. }
  527. return 0;
  528. }
  529. /**
  530. * Build the Quizzes
  531. * @param int $session_id Internal session ID
  532. * @param int $courseId Internal course ID
  533. * @param bool $with_base_content Whether to include content from the course without session or not
  534. * @param array $id_list If you want to restrict the structure to only the given IDs
  535. */
  536. public function build_quizzes(
  537. $session_id = 0,
  538. $courseId = 0,
  539. $with_base_content = false,
  540. $id_list = array()
  541. ) {
  542. $table_qui = Database:: get_course_table(TABLE_QUIZ_TEST);
  543. $table_rel = Database:: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  544. $table_doc = Database:: get_course_table(TABLE_DOCUMENT);
  545. if (!empty($courseId) && !empty($session_id)) {
  546. $session_id = intval($session_id);
  547. if ($with_base_content) {
  548. $session_condition = api_get_session_condition(
  549. $session_id,
  550. true,
  551. true
  552. );
  553. } else {
  554. $session_condition = api_get_session_condition(
  555. $session_id,
  556. true
  557. );
  558. }
  559. $sql = "SELECT * FROM $table_qui
  560. WHERE c_id = $courseId AND active >=0 $session_condition";
  561. //select only quizzes with active = 0 or 1 (not -1 which is for deleted quizzes)
  562. } else {
  563. $sql = "SELECT * FROM $table_qui
  564. WHERE c_id = $courseId AND active >=0 AND session_id = 0";
  565. //select only quizzes with active = 0 or 1 (not -1 which is for deleted quizzes)
  566. }
  567. $db_result = Database::query($sql);
  568. while ($obj = Database::fetch_object($db_result)) {
  569. if (strlen($obj->sound) > 0) {
  570. $sql = "SELECT id FROM $table_doc
  571. WHERE c_id = $courseId AND path = '/audio/".$obj->sound."'";
  572. $res = Database::query($sql);
  573. $doc = Database::fetch_object($res);
  574. $obj->sound = $doc->id;
  575. }
  576. $quiz = new Quiz($obj);
  577. $sql = 'SELECT * FROM '.$table_rel.'
  578. WHERE c_id = '.$courseId.' AND exercice_id = '.$obj->id;
  579. $db_result2 = Database::query($sql);
  580. while ($obj2 = Database::fetch_object($db_result2)) {
  581. $quiz->add_question($obj2->question_id, $obj2->question_order);
  582. }
  583. $this->course->add_resource($quiz);
  584. }
  585. if (!empty($courseId)) {
  586. $this->build_quiz_questions($courseId);
  587. } else {
  588. $this->build_quiz_questions();
  589. }
  590. }
  591. /**
  592. * Build the Quiz-Questions
  593. * @param int $courseId Internal course ID
  594. */
  595. public function build_quiz_questions($courseId = 0)
  596. {
  597. $table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
  598. $table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  599. $table_que = Database :: get_course_table(TABLE_QUIZ_QUESTION);
  600. $table_ans = Database :: get_course_table(TABLE_QUIZ_ANSWER);
  601. // Building normal tests.
  602. $sql = "SELECT * FROM $table_que
  603. WHERE c_id = $courseId ";
  604. $result = Database::query($sql);
  605. while ($obj = Database::fetch_object($result)) {
  606. // find the question category
  607. // @todo : need to be adapted for multi category questions in 1.10
  608. $question_category_id = TestCategory::getCategoryForQuestion(
  609. $obj->id,
  610. $courseId
  611. );
  612. // build the backup resource question object
  613. $question = new QuizQuestion(
  614. $obj->id,
  615. $obj->question,
  616. $obj->description,
  617. $obj->ponderation,
  618. $obj->type,
  619. $obj->position,
  620. $obj->picture,
  621. $obj->level,
  622. $obj->extra,
  623. $question_category_id
  624. );
  625. $sql = 'SELECT * FROM '.$table_ans.'
  626. WHERE c_id = '.$courseId.' AND question_id = '.$obj->id;
  627. $db_result2 = Database::query($sql);
  628. while ($obj2 = Database::fetch_object($db_result2)) {
  629. $question->add_answer(
  630. $obj2->id,
  631. $obj2->answer,
  632. $obj2->correct,
  633. $obj2->comment,
  634. $obj2->ponderation,
  635. $obj2->position,
  636. $obj2->hotspot_coordinates,
  637. $obj2->hotspot_type
  638. );
  639. if ($obj->type == MULTIPLE_ANSWER_TRUE_FALSE) {
  640. $table_options = Database::get_course_table(
  641. TABLE_QUIZ_QUESTION_OPTION
  642. );
  643. $sql = 'SELECT * FROM '.$table_options.'
  644. WHERE c_id = '.$courseId.' AND question_id = '.$obj->id;
  645. $db_result3 = Database::query($sql);
  646. while ($obj3 = Database::fetch_object($db_result3)) {
  647. $question_option = new QuizQuestionOption($obj3);
  648. $question->add_option($question_option);
  649. }
  650. }
  651. }
  652. $this->course->add_resource($question);
  653. }
  654. // Building a fictional test for collecting orphan questions.
  655. // When a course is emptied this option should be activated (true).
  656. $build_orphan_questions = !empty($_POST['recycle_option']);
  657. // 1st union gets the orphan questions from deleted exercises
  658. // 2nd union gets the orphan questions from question that were deleted in a exercise.
  659. $sql = " (
  660. SELECT question_id, q.* FROM $table_que q INNER JOIN $table_rel r
  661. ON (q.c_id = r.c_id AND q.id = r.question_id)
  662. INNER JOIN $table_qui ex
  663. ON (ex.id = r.exercice_id AND ex.c_id = r.c_id )
  664. WHERE ex.c_id = $courseId AND ex.active = '-1'
  665. )
  666. UNION
  667. (
  668. SELECT question_id, q.* FROM $table_que q left
  669. OUTER JOIN $table_rel r
  670. ON (q.c_id = r.c_id AND q.id = r.question_id)
  671. WHERE q.c_id = $courseId AND r.question_id is null
  672. )
  673. UNION
  674. (
  675. SELECT question_id, q.* FROM $table_que q
  676. INNER JOIN $table_rel r
  677. ON (q.c_id = r.c_id AND q.id = r.question_id)
  678. WHERE r.c_id = $courseId AND (r.exercice_id = '-1' OR r.exercice_id = '0')
  679. )
  680. ";
  681. $result = Database::query($sql);
  682. if (Database::num_rows($result) > 0) {
  683. $build_orphan_questions = true;
  684. $orphanQuestionIds = array();
  685. while ($obj = Database::fetch_object($result)) {
  686. // Orphan questions
  687. if (!empty($obj->question_id)) {
  688. $obj->id = $obj->question_id;
  689. }
  690. // Avoid adding the same question twice
  691. if (!isset($this->course->resources[$obj->id])) {
  692. // find the question category
  693. // @todo : need to be adapted for multi category questions in 1.10
  694. $question_category_id = TestCategory::getCategoryForQuestion(
  695. $obj->id,
  696. $courseId
  697. );
  698. $question = new QuizQuestion(
  699. $obj->id,
  700. $obj->question,
  701. $obj->description,
  702. $obj->ponderation,
  703. $obj->type,
  704. $obj->position,
  705. $obj->picture,
  706. $obj->level,
  707. $obj->extra,
  708. $question_category_id
  709. );
  710. $sql = "SELECT * FROM $table_ans
  711. WHERE c_id = $courseId AND question_id = ".$obj->id;
  712. $db_result2 = Database::query($sql);
  713. if (Database::num_rows($db_result2)) {
  714. while ($obj2 = Database::fetch_object($db_result2)) {
  715. $question->add_answer(
  716. $obj2->id,
  717. $obj2->answer,
  718. $obj2->correct,
  719. $obj2->comment,
  720. $obj2->ponderation,
  721. $obj2->position,
  722. $obj2->hotspot_coordinates,
  723. $obj2->hotspot_type
  724. );
  725. }
  726. $orphanQuestionIds[] = $obj->id;
  727. }
  728. $this->course->add_resource($question);
  729. }
  730. }
  731. }
  732. if ($build_orphan_questions) {
  733. $obj = array(
  734. 'id' => -1,
  735. 'title' => get_lang('OrphanQuestions', ''),
  736. 'type' => 2
  737. );
  738. $newQuiz = new Quiz((object)$obj);
  739. if (!empty($orphanQuestionIds)) {
  740. foreach ($orphanQuestionIds as $index => $orphanId) {
  741. $order = $index + 1;
  742. $newQuiz->add_question($orphanId, $order);
  743. }
  744. }
  745. $this->course->add_resource($newQuiz);
  746. }
  747. }
  748. /**
  749. * Build the orphan questions
  750. */
  751. public function build_quiz_orphan_questions()
  752. {
  753. $table_qui = Database:: get_course_table(TABLE_QUIZ_TEST);
  754. $table_rel = Database:: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  755. $table_que = Database:: get_course_table(TABLE_QUIZ_QUESTION);
  756. $table_ans = Database:: get_course_table(TABLE_QUIZ_ANSWER);
  757. $courseId = api_get_course_int_id();
  758. $sql = 'SELECT *
  759. FROM '.$table_que.' as questions
  760. LEFT JOIN '.$table_rel.' as quizz_questions
  761. ON questions.id=quizz_questions.question_id
  762. LEFT JOIN '.$table_qui.' as exercises
  763. ON quizz_questions.exercice_id = exercises.id
  764. WHERE
  765. questions.c_id = quizz_questions.c_id AND
  766. questions.c_id = exercises.c_id AND
  767. exercises.c_id = '.$courseId.' AND
  768. (quizz_questions.exercice_id IS NULL OR
  769. exercises.active = -1)';
  770. $db_result = Database::query($sql);
  771. if (Database::num_rows($db_result) > 0) {
  772. // This is the fictional test for collecting orphan questions.
  773. $orphan_questions = new Quiz(
  774. -1,
  775. get_lang('OrphanQuestions', ''),
  776. '',
  777. 0,
  778. 0,
  779. 1,
  780. '',
  781. 0
  782. );
  783. $this->course->add_resource($orphan_questions);
  784. while ($obj = Database::fetch_object($db_result)) {
  785. $question = new QuizQuestion(
  786. $obj->id,
  787. $obj->question,
  788. $obj->description,
  789. $obj->ponderation,
  790. $obj->type,
  791. $obj->position,
  792. $obj->picture,
  793. $obj->level,
  794. $obj->extra
  795. );
  796. $sql = 'SELECT * FROM '.$table_ans.' WHERE question_id = '.$obj->id;
  797. $db_result2 = Database::query($sql);
  798. while ($obj2 = Database::fetch_object($db_result2)) {
  799. $question->add_answer(
  800. $obj2->id,
  801. $obj2->answer,
  802. $obj2->correct,
  803. $obj2->comment,
  804. $obj2->ponderation,
  805. $obj2->position,
  806. $obj2->hotspot_coordinates,
  807. $obj2->hotspot_type
  808. );
  809. }
  810. $this->course->add_resource($question);
  811. }
  812. }
  813. }
  814. /**
  815. * Build the test category
  816. * @param int $session_id Internal session ID
  817. * @param int $courseId Internal course ID
  818. * @param bool $with_base_content Whether to include content from the course without session or not
  819. * @param array $id_list If you want to restrict the structure to only the given IDs
  820. * @todo add course session
  821. */
  822. public function build_test_category(
  823. $session_id = 0,
  824. $courseId = 0,
  825. $with_base_content = false,
  826. $id_list = array()
  827. ) {
  828. // get all test category in course
  829. $tab_test_categories_id = TestCategory::getCategoryListInfo(
  830. "id",
  831. $courseId
  832. );
  833. foreach ($tab_test_categories_id as $test_category_id) {
  834. $test_category = new TestCategory($test_category_id);
  835. $copy_course_test_category = new CourseCopyTestcategory(
  836. $test_category_id,
  837. $test_category->name,
  838. $test_category->description
  839. );
  840. $this->course->add_resource($copy_course_test_category);
  841. }
  842. }
  843. /**
  844. * Build the Surveys
  845. * @param int $session_id Internal session ID
  846. * @param int $courseId Internal course ID
  847. * @param bool $with_base_content Whether to include content from the course without session or not
  848. * @param array $id_list If you want to restrict the structure to only the given IDs
  849. */
  850. public function build_surveys(
  851. $session_id = 0,
  852. $courseId = 0,
  853. $with_base_content = false,
  854. $id_list = array()
  855. ) {
  856. $table_survey = Database:: get_course_table(TABLE_SURVEY);
  857. $table_question = Database:: get_course_table(TABLE_SURVEY_QUESTION);
  858. $sessionCondition = api_get_session_condition(
  859. $session_id,
  860. true,
  861. $with_base_content
  862. );
  863. $sql = 'SELECT * FROM '.$table_survey.' WHERE c_id = '.$courseId.' '.$sessionCondition;
  864. $db_result = Database::query($sql);
  865. while ($obj = Database::fetch_object($db_result)) {
  866. $survey = new Survey(
  867. $obj->survey_id, $obj->code, $obj->title,
  868. $obj->subtitle, $obj->author, $obj->lang,
  869. $obj->avail_from, $obj->avail_till, $obj->is_shared,
  870. $obj->template, $obj->intro, $obj->surveythanks,
  871. $obj->creation_date, $obj->invited, $obj->answered,
  872. $obj->invite_mail, $obj->reminder_mail
  873. );
  874. $sql = 'SELECT * FROM '.$table_question.'
  875. WHERE c_id = '.$courseId.' AND survey_id = '.$obj->survey_id;
  876. $db_result2 = Database::query($sql);
  877. while ($obj2 = Database::fetch_object($db_result2)) {
  878. $survey->add_question($obj2->question_id);
  879. }
  880. $this->course->add_resource($survey);
  881. }
  882. $this->build_survey_questions($courseId);
  883. }
  884. /**
  885. * Build the Survey Questions
  886. * @param int $courseId Internal course ID
  887. */
  888. public function build_survey_questions($courseId) {
  889. $table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
  890. $table_opt = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
  891. $sql = 'SELECT * FROM '.$table_que.' WHERE c_id = '.$courseId.' ';
  892. $db_result = Database::query($sql);
  893. while ($obj = Database::fetch_object($db_result)) {
  894. $question = new SurveyQuestion(
  895. $obj->question_id,
  896. $obj->survey_id,
  897. $obj->survey_question,
  898. $obj->survey_question_comment,
  899. $obj->type,
  900. $obj->display,
  901. $obj->sort,
  902. $obj->shared_question_id,
  903. $obj->max_value
  904. );
  905. $sql = 'SELECT * FROM '.$table_opt.'
  906. WHERE c_id = '.$courseId.' AND question_id = '.$obj->question_id;
  907. $db_result2 = Database::query($sql);
  908. while ($obj2 = Database::fetch_object($db_result2)) {
  909. $question->add_answer($obj2->option_text, $obj2->sort);
  910. }
  911. $this->course->add_resource($question);
  912. }
  913. }
  914. /**
  915. * Build the announcements
  916. * @param int $session_id Internal session ID
  917. * @param int $courseId Internal course ID
  918. * @param bool $with_base_content Whether to include content from the course without session or not
  919. * @param array $id_list If you want to restrict the structure to only the given IDs
  920. */
  921. public function build_announcements(
  922. $session_id = 0,
  923. $courseId = 0,
  924. $with_base_content = false,
  925. $id_list = array()
  926. ) {
  927. $table = Database:: get_course_table(TABLE_ANNOUNCEMENT);
  928. $sessionCondition = api_get_session_condition(
  929. $session_id,
  930. true,
  931. $with_base_content
  932. );
  933. $sql = 'SELECT * FROM '.$table.'
  934. WHERE c_id = '.$courseId.' '.$sessionCondition;
  935. $db_result = Database::query($sql);
  936. $table_attachment = Database:: get_course_table(
  937. TABLE_ANNOUNCEMENT_ATTACHMENT
  938. );
  939. while ($obj = Database::fetch_object($db_result)) {
  940. if (empty($obj->id)) {
  941. continue;
  942. }
  943. $sql = 'SELECT path, comment, filename, size
  944. FROM '.$table_attachment.'
  945. WHERE c_id = '.$courseId.' AND announcement_id = '.$obj->id.'';
  946. $result = Database::query($sql);
  947. $attachment_obj = Database::fetch_object($result);
  948. $att_path = $att_filename = $att_size = $atth_comment = '';
  949. if (!empty($attachment_obj)) {
  950. $att_path = $attachment_obj->path;
  951. $att_filename = $attachment_obj->filename;
  952. $att_size = $attachment_obj->size;
  953. $atth_comment = $attachment_obj->comment;
  954. }
  955. $announcement = new Announcement(
  956. $obj->id,
  957. $obj->title,
  958. $obj->content,
  959. $obj->end_date,
  960. $obj->display_order,
  961. $obj->email_sent,
  962. $att_path,
  963. $att_filename,
  964. $att_size,
  965. $atth_comment
  966. );
  967. $this->course->add_resource($announcement);
  968. }
  969. }
  970. /**
  971. * Build the events
  972. * @param int $session_id Internal session ID
  973. * @param int $courseId Internal course ID
  974. * @param bool $with_base_content Whether to include content from the course without session or not
  975. * @param array $id_list If you want to restrict the structure to only the given IDs
  976. */
  977. public function build_events(
  978. $session_id = 0,
  979. $courseId = 0,
  980. $with_base_content = false,
  981. $id_list = array()
  982. ) {
  983. $table = Database:: get_course_table(TABLE_AGENDA);
  984. $sessionCondition = api_get_session_condition(
  985. $session_id,
  986. true,
  987. $with_base_content
  988. );
  989. $sql = 'SELECT * FROM '.$table.'
  990. WHERE c_id = '.$courseId.' '.$sessionCondition;
  991. $db_result = Database::query($sql);
  992. while ($obj = Database::fetch_object($db_result)) {
  993. $table_attachment = Database:: get_course_table(
  994. TABLE_AGENDA_ATTACHMENT
  995. );
  996. $sql = 'SELECT path, comment, filename, size
  997. FROM '.$table_attachment.'
  998. WHERE c_id = '.$courseId.' AND agenda_id = '.$obj->id.'';
  999. $result = Database::query($sql);
  1000. $attachment_obj = Database::fetch_object($result);
  1001. $att_path = $att_filename = $att_size = $atth_comment = '';
  1002. if (!empty($attachment_obj)) {
  1003. $att_path = $attachment_obj->path;
  1004. $att_filename = $attachment_obj->filename;
  1005. $att_size = $attachment_obj->size;
  1006. $atth_comment = $attachment_obj->comment;
  1007. }
  1008. $event = new CalendarEvent(
  1009. $obj->id,
  1010. $obj->title,
  1011. $obj->content,
  1012. $obj->start_date,
  1013. $obj->end_date,
  1014. $att_path,
  1015. $att_filename,
  1016. $att_size,
  1017. $atth_comment,
  1018. $obj->all_day
  1019. );
  1020. $this->course->add_resource($event);
  1021. }
  1022. }
  1023. /**
  1024. * Build the course-descriptions
  1025. * @param int $session_id Internal session ID
  1026. * @param int $courseId Internal course ID
  1027. * @param bool $with_base_content Whether to include content from the course without session or not
  1028. * @param array $id_list If you want to restrict the structure to only the given IDs
  1029. */
  1030. public function build_course_descriptions(
  1031. $session_id = 0,
  1032. $courseId = 0,
  1033. $with_base_content = false,
  1034. $id_list = array()
  1035. ) {
  1036. $table = Database:: get_course_table(TABLE_COURSE_DESCRIPTION);
  1037. if (!empty($session_id) && !empty($courseId)) {
  1038. $session_id = intval($session_id);
  1039. if ($with_base_content) {
  1040. $session_condition = api_get_session_condition(
  1041. $session_id,
  1042. true,
  1043. true
  1044. );
  1045. } else {
  1046. $session_condition = api_get_session_condition(
  1047. $session_id,
  1048. true
  1049. );
  1050. }
  1051. $sql = 'SELECT * FROM '.$table.'
  1052. WHERE c_id = '.$courseId.' '.$session_condition;
  1053. } else {
  1054. $table = Database:: get_course_table(TABLE_COURSE_DESCRIPTION);
  1055. $sql = 'SELECT * FROM '.$table.'
  1056. WHERE c_id = '.$courseId.' AND session_id = 0';
  1057. }
  1058. $db_result = Database::query($sql);
  1059. while ($obj = Database::fetch_object($db_result)) {
  1060. $cd = new CourseDescription(
  1061. $obj->id,
  1062. $obj->title,
  1063. $obj->content,
  1064. $obj->description_type
  1065. );
  1066. $this->course->add_resource($cd);
  1067. }
  1068. }
  1069. /**
  1070. * Build the learnpaths
  1071. * @param int $session_id Internal session ID
  1072. * @param int $courseId Internal course ID
  1073. * @param bool $with_base_content Whether to include content from the course without session or not
  1074. * @param array $id_list If you want to restrict the structure to only the given IDs
  1075. */
  1076. public function build_learnpaths(
  1077. $session_id = 0,
  1078. $courseId = 0,
  1079. $with_base_content = false,
  1080. $id_list = array()
  1081. ) {
  1082. $table_main = Database::get_course_table(TABLE_LP_MAIN);
  1083. $table_item = Database::get_course_table(TABLE_LP_ITEM);
  1084. $table_tool = Database::get_course_table(TABLE_TOOL_LIST);
  1085. if (!empty($session_id) && !empty($courseId)) {
  1086. $session_id = intval($session_id);
  1087. if ($with_base_content) {
  1088. $session_condition = api_get_session_condition(
  1089. $session_id,
  1090. true,
  1091. true
  1092. );
  1093. } else {
  1094. $session_condition = api_get_session_condition(
  1095. $session_id,
  1096. true
  1097. );
  1098. }
  1099. $sql = 'SELECT * FROM '.$table_main.'
  1100. WHERE c_id = '.$courseId.' '.$session_condition;
  1101. } else {
  1102. $sql = 'SELECT * FROM '.$table_main.'
  1103. WHERE c_id = '.$courseId.' AND session_id = 0';
  1104. }
  1105. if (!empty($id_list)) {
  1106. $id_list = array_map('intval', $id_list);
  1107. $sql .= " AND id IN (".implode(', ', $id_list).") ";
  1108. }
  1109. $db_result = Database::query($sql);
  1110. if ($db_result) {
  1111. while ($obj = Database::fetch_object($db_result)) {
  1112. $items = array();
  1113. $sql_items = "SELECT * FROM ".$table_item." WHERE c_id = '$courseId' AND lp_id = ".$obj->id;
  1114. $db_items = Database::query($sql_items);
  1115. while ($obj_item = Database::fetch_object($db_items)) {
  1116. $item['id'] = $obj_item->id;
  1117. $item['item_type'] = $obj_item->item_type;
  1118. $item['ref'] = $obj_item->ref;
  1119. $item['title'] = $obj_item->title;
  1120. $item['description'] = $obj_item->description;
  1121. $item['path'] = $obj_item->path;
  1122. $item['min_score'] = $obj_item->min_score;
  1123. $item['max_score'] = $obj_item->max_score;
  1124. $item['mastery_score'] = $obj_item->mastery_score;
  1125. $item['parent_item_id'] = $obj_item->parent_item_id;
  1126. $item['previous_item_id'] = $obj_item->previous_item_id;
  1127. $item['next_item_id'] = $obj_item->next_item_id;
  1128. $item['display_order'] = $obj_item->display_order;
  1129. $item['prerequisite'] = $obj_item->prerequisite;
  1130. $item['parameters'] = $obj_item->parameters;
  1131. $item['launch_data'] = $obj_item->launch_data;
  1132. $item['audio'] = $obj_item->audio;
  1133. $items[] = $item;
  1134. }
  1135. $sql_tool = "SELECT id FROM $table_tool
  1136. WHERE
  1137. c_id = $courseId AND
  1138. (link LIKE '%lp_controller.php%lp_id=".$obj->id."%' AND image='scormbuilder.gif') AND
  1139. visibility = '1' ";
  1140. $db_tool = Database::query($sql_tool);
  1141. if (Database::num_rows($db_tool)) {
  1142. $visibility = '1';
  1143. } else {
  1144. $visibility = '0';
  1145. }
  1146. $lp = new CourseCopyLearnpath(
  1147. $obj->id,
  1148. $obj->lp_type,
  1149. $obj->name,
  1150. $obj->path,
  1151. $obj->ref,
  1152. $obj->description,
  1153. $obj->content_local,
  1154. $obj->default_encoding,
  1155. $obj->default_view_mod,
  1156. $obj->prevent_reinit,
  1157. $obj->force_commit,
  1158. $obj->content_maker,
  1159. $obj->display_order,
  1160. $obj->js_lib,
  1161. $obj->content_license,
  1162. $obj->debug,
  1163. $visibility,
  1164. $obj->author,
  1165. $obj->preview_image,
  1166. $obj->use_max_score,
  1167. $obj->autolaunch,
  1168. $obj->created_on,
  1169. $obj->modified_on,
  1170. $obj->publicated_on,
  1171. $obj->expired_on,
  1172. $obj->session_id,
  1173. $items
  1174. );
  1175. $this->course->add_resource($lp);
  1176. }
  1177. }
  1178. // Save scorm directory (previously build_scorm_documents())
  1179. $i = 1;
  1180. if ($dir = @opendir($this->course->backup_path.'/scorm')) {
  1181. while ($file = readdir($dir)) {
  1182. if (is_dir($this->course->backup_path.'/scorm/'.$file) &&
  1183. !in_array($file, array('.', '..'))
  1184. ) {
  1185. $doc = new ScormDocument($i++, '/'.$file, $file);
  1186. $this->course->add_resource($doc);
  1187. }
  1188. }
  1189. closedir($dir);
  1190. }
  1191. }
  1192. /**
  1193. * Build the glossaries
  1194. * @param int $session_id Internal session ID
  1195. * @param int $courseId Internal course ID
  1196. * @param bool $with_base_content Whether to include content from the course without session or not
  1197. * @param array $id_list If you want to restrict the structure to only the given IDs
  1198. */
  1199. public function build_glossary(
  1200. $session_id = 0,
  1201. $courseId = 0,
  1202. $with_base_content = false,
  1203. $id_list = array()
  1204. ) {
  1205. $table_glossary = Database :: get_course_table(TABLE_GLOSSARY);
  1206. if (!empty($session_id) && !empty($courseId)) {
  1207. $session_id = intval($session_id);
  1208. if ($with_base_content) {
  1209. $session_condition = api_get_session_condition(
  1210. $session_id,
  1211. true,
  1212. true
  1213. );
  1214. } else {
  1215. $session_condition = api_get_session_condition(
  1216. $session_id,
  1217. true
  1218. );
  1219. }
  1220. //@todo check this queries are the same ...
  1221. if (!empty($this->course->type) && $this->course->type == 'partial') {
  1222. $sql = 'SELECT * FROM '.$table_glossary.' g WHERE g.c_id = '.$courseId.' '.$session_condition;
  1223. } else {
  1224. $sql = 'SELECT * FROM '.$table_glossary.' g WHERE g.c_id = '.$courseId.' '.$session_condition;
  1225. }
  1226. } else {
  1227. $table_glossary = Database:: get_course_table(TABLE_GLOSSARY);
  1228. //@todo check this queries are the same ... ayayay
  1229. if (!empty($this->course->type) && $this->course->type == 'partial') {
  1230. $sql = 'SELECT * FROM '.$table_glossary.' g
  1231. WHERE g.c_id = '.$courseId.' AND session_id = 0';
  1232. } else {
  1233. $sql = 'SELECT * FROM '.$table_glossary.' g
  1234. WHERE g.c_id = '.$courseId.' AND session_id = 0';
  1235. }
  1236. }
  1237. $db_result = Database::query($sql);
  1238. while ($obj = Database::fetch_object($db_result)) {
  1239. $doc = new Glossary(
  1240. $obj->glossary_id,
  1241. $obj->name,
  1242. $obj->description,
  1243. $obj->display_order
  1244. );
  1245. $this->course->add_resource($doc);
  1246. }
  1247. }
  1248. /*
  1249. * Build session course by jhon
  1250. */
  1251. public function build_session_course()
  1252. {
  1253. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1254. $tbl_session_course = Database::get_main_table(
  1255. TABLE_MAIN_SESSION_COURSE
  1256. );
  1257. $list_course = CourseManager::get_course_list();
  1258. $list = array();
  1259. foreach ($list_course as $_course) {
  1260. $this->course = new Course();
  1261. $this->course->code = $_course['code'];
  1262. $this->course->type = 'partial';
  1263. $this->course->path = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/';
  1264. $this->course->backup_path = api_get_path(SYS_COURSE_PATH).$_course['directory'];
  1265. $this->course->encoding = api_get_system_encoding(); //current platform encoding
  1266. $code_course = $_course['code'];
  1267. $courseId = $_course['real_id'];
  1268. $sql_session = "SELECT s.id, name, c_id
  1269. FROM $tbl_session_course sc
  1270. INNER JOIN $tbl_session s
  1271. ON sc.session_id = s.id
  1272. WHERE sc.c_id = '$courseId' ";
  1273. $query_session = Database::query($sql_session);
  1274. while ($rows_session = Database::fetch_assoc($query_session)) {
  1275. $session = new CourseSession(
  1276. $rows_session['id'],
  1277. $rows_session['name']
  1278. );
  1279. $this->course->add_resource($session);
  1280. }
  1281. $list[] = $this->course;
  1282. }
  1283. return $list;
  1284. }
  1285. /**
  1286. * @param int $session_id Internal session ID
  1287. * @param int $courseId Internal course ID
  1288. * @param bool $with_base_content Whether to include content from the course without session or not
  1289. * @param array $id_list If you want to restrict the structure to only the given IDs
  1290. */
  1291. public function build_wiki(
  1292. $session_id = 0,
  1293. $courseId = 0,
  1294. $with_base_content = false,
  1295. $id_list = array()
  1296. ) {
  1297. $tbl_wiki = Database::get_course_table(TABLE_WIKI);
  1298. if (!empty($session_id) && !empty($courseId)) {
  1299. $session_id = intval($session_id);
  1300. if ($with_base_content) {
  1301. $session_condition = api_get_session_condition(
  1302. $session_id,
  1303. true,
  1304. true
  1305. );
  1306. } else {
  1307. $session_condition = api_get_session_condition(
  1308. $session_id,
  1309. true
  1310. );
  1311. }
  1312. $sql = 'SELECT * FROM '.$tbl_wiki.'
  1313. WHERE c_id = '.$courseId.' '.$session_condition;
  1314. } else {
  1315. $tbl_wiki = Database::get_course_table(TABLE_WIKI);
  1316. $sql = 'SELECT * FROM '.$tbl_wiki.'
  1317. WHERE c_id = '.$courseId.' AND session_id = 0';
  1318. }
  1319. $db_result = Database::query($sql);
  1320. while ($obj = Database::fetch_object($db_result)) {
  1321. $wiki = new Wiki(
  1322. $obj->id,
  1323. $obj->page_id,
  1324. $obj->reflink,
  1325. $obj->title,
  1326. $obj->content,
  1327. $obj->user_id,
  1328. $obj->group_id,
  1329. $obj->dtime,
  1330. $obj->progress,
  1331. $obj->version
  1332. );
  1333. $this->course->add_resource($wiki);
  1334. }
  1335. }
  1336. /**
  1337. * Build the Surveys
  1338. * @param int $session_id Internal session ID
  1339. * @param int $courseId Internal course ID
  1340. * @param bool $with_base_content Whether to include content from the course without session or not
  1341. * @param array $id_list If you want to restrict the structure to only the given IDs
  1342. */
  1343. public function build_thematic(
  1344. $session_id = 0,
  1345. $courseId = 0,
  1346. $with_base_content = false,
  1347. $id_list = array()
  1348. ) {
  1349. $table_thematic = Database :: get_course_table(TABLE_THEMATIC);
  1350. $table_thematic_advance = Database :: get_course_table(TABLE_THEMATIC_ADVANCE);
  1351. $table_thematic_plan = Database :: get_course_table(TABLE_THEMATIC_PLAN);
  1352. $session_id = intval($session_id);
  1353. if ($with_base_content) {
  1354. $session_condition = api_get_session_condition(
  1355. $session_id,
  1356. true,
  1357. true
  1358. );
  1359. } else {
  1360. $session_condition = api_get_session_condition($session_id, true);
  1361. }
  1362. $sql = "SELECT * FROM $table_thematic
  1363. WHERE c_id = $courseId $session_condition ";
  1364. $db_result = Database::query($sql);
  1365. while ($row = Database::fetch_array($db_result, 'ASSOC')) {
  1366. $thematic = new Thematic($row);
  1367. $sql = 'SELECT * FROM '.$table_thematic_advance.'
  1368. WHERE c_id = '.$courseId.' AND thematic_id = '.$row['id'];
  1369. $result = Database::query($sql);
  1370. while ($sub_row = Database::fetch_array($result, 'ASSOC')) {
  1371. $thematic->add_thematic_advance($sub_row);
  1372. }
  1373. $items = api_get_item_property_by_tool(
  1374. 'thematic_plan',
  1375. api_get_course_id(),
  1376. $session_id
  1377. );
  1378. $thematic_plan_id_list = array();
  1379. if (!empty($items)) {
  1380. foreach ($items as $item) {
  1381. $thematic_plan_id_list[] = $item['ref'];
  1382. //$thematic_plan_complete_list[$item['ref']] = $item;
  1383. }
  1384. }
  1385. if (count($thematic_plan_id_list) > 0) {
  1386. $sql = "SELECT tp.*
  1387. FROM $table_thematic_plan tp
  1388. INNER JOIN $table_thematic t ON (t.id=tp.thematic_id)
  1389. WHERE
  1390. t.c_id = $courseId AND
  1391. tp.c_id = $courseId AND
  1392. thematic_id = {$row['id']} AND
  1393. tp.id IN (".implode(
  1394. ', ',
  1395. $thematic_plan_id_list
  1396. ).") ";
  1397. $result = Database::query($sql);
  1398. while ($sub_row = Database::fetch_array($result, 'ASSOC')) {
  1399. $thematic->add_thematic_plan($sub_row);
  1400. }
  1401. }
  1402. $this->course->add_resource($thematic);
  1403. }
  1404. }
  1405. /**
  1406. * Build the attendances
  1407. * @param int $session_id Internal session ID
  1408. * @param int $courseId Internal course ID
  1409. * @param bool $with_base_content Whether to include content from the course without session or not
  1410. * @param array $id_list If you want to restrict the structure to only the given IDs
  1411. */
  1412. public function build_attendance(
  1413. $session_id = 0,
  1414. $courseId = 0,
  1415. $with_base_content = false,
  1416. $id_list = array()
  1417. ) {
  1418. $table_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
  1419. $table_attendance_calendar = Database :: get_course_table(TABLE_ATTENDANCE_CALENDAR);
  1420. $sessionCondition = api_get_session_condition($session_id, true, $with_base_content);
  1421. $sql = 'SELECT * FROM '.$table_attendance.'
  1422. WHERE c_id = '.$courseId.' '.$sessionCondition;
  1423. $db_result = Database::query($sql);
  1424. while ($row = Database::fetch_array($db_result, 'ASSOC')) {
  1425. $obj = new Attendance($row);
  1426. $sql = 'SELECT * FROM '.$table_attendance_calendar.'
  1427. WHERE c_id = '.$courseId.' AND attendance_id = '.$row['id'];
  1428. $result = Database::query($sql);
  1429. while ($sub_row = Database::fetch_array($result, 'ASSOC')) {
  1430. $obj->add_attendance_calendar($sub_row);
  1431. }
  1432. $this->course->add_resource($obj);
  1433. }
  1434. }
  1435. /**
  1436. * Build the works (or "student publications", or "assignments")
  1437. * @param int $session_id Internal session ID
  1438. * @param int $courseId Internal course ID
  1439. * @param bool $with_base_content Whether to include content from the course without session or not
  1440. * @param array $id_list If you want to restrict the structure to only the given IDs
  1441. */
  1442. public function build_works(
  1443. $session_id = 0,
  1444. $courseId = 0,
  1445. $with_base_content = false,
  1446. $id_list = array()
  1447. ) {
  1448. $table_work = Database:: get_course_table(TABLE_STUDENT_PUBLICATION);
  1449. $sessionCondition = api_get_session_condition(
  1450. $session_id,
  1451. true,
  1452. $with_base_content
  1453. );
  1454. $sql = "SELECT * FROM $table_work
  1455. WHERE
  1456. c_id = $courseId
  1457. $sessionCondition AND
  1458. filetype = 'folder' AND
  1459. parent_id = 0 AND
  1460. active = 1";
  1461. $db_result = Database::query($sql);
  1462. while ($row = Database::fetch_array($db_result, 'ASSOC')) {
  1463. $obj = new Work($row);
  1464. $this->course->add_resource($obj);
  1465. }
  1466. }
  1467. }