ScormExercise.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CQuiz;
  4. use Symfony\Component\Serializer\Encoder\JsonEncoder;
  5. use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
  6. use Symfony\Component\Serializer\Serializer;
  7. /**
  8. * This class represents an entire exercise to be exported in SCORM.
  9. * It will be represented by a single <section> containing several <item>.
  10. *
  11. * Some properties cannot be exported, as SCORM does not support them :
  12. * - type (one page or multiple pages)
  13. * - start_date and end_date
  14. * - max_attempts
  15. * - show_answer
  16. * - anonymous_attempts
  17. *
  18. * @author Julio Montoya
  19. * @author Amand Tihon <amand@alrj.org>
  20. *
  21. * @package chamilo.exercise.scorm
  22. */
  23. class ScormExercise
  24. {
  25. public $exercise;
  26. public $standalone;
  27. /**
  28. * ScormExercise constructor.
  29. *
  30. * @param Exercise $exe
  31. * @param bool $standalone
  32. */
  33. public function __construct($exe, $standalone)
  34. {
  35. $this->exercise = $exe;
  36. $this->standalone = $standalone;
  37. }
  38. /**
  39. * Start the XML flow.
  40. *
  41. * This opens the <item> block, with correct attributes.
  42. */
  43. public function startPage()
  44. {
  45. $charset = 'UTF-8';
  46. $head = '<?xml version="1.0" encoding="'.$charset.'" standalone="no"?><html>';
  47. return $head;
  48. }
  49. /**
  50. * End the XML flow, closing the </item> tag.
  51. */
  52. public function end_page()
  53. {
  54. return '</html>';
  55. }
  56. /**
  57. * Start document header.
  58. */
  59. public function start_header()
  60. {
  61. return '<head>';
  62. }
  63. /**
  64. * Common JS functions.
  65. */
  66. public function common_js()
  67. {
  68. $js = file_get_contents(api_get_path(SYS_CODE_PATH).'exercise/export/scorm/common.js');
  69. return $js."\n";
  70. }
  71. /**
  72. * End the itemBody part.
  73. */
  74. public function end_js()
  75. {
  76. return '</script>';
  77. }
  78. /**
  79. * Start the itemBody.
  80. */
  81. public function start_body()
  82. {
  83. return '<body>'.
  84. '<h1>'.$this->exercise->selectTitle().'</h1><p>'.$this->exercise->selectDescription()."</p>".
  85. '<form id="chamilo_scorm_form" method="post" action="">'.
  86. '<table width="100%">';
  87. }
  88. /**
  89. * End the itemBody part.
  90. */
  91. public function end_body()
  92. {
  93. $button = '<input
  94. id="chamilo_scorm_submit"
  95. class="btn btn-primary"
  96. type="button"
  97. name="chamilo_scorm_submit"
  98. value="OK" />';
  99. return '</table><br />'.$button.'</form></body>';
  100. }
  101. /**
  102. * Export the question as a SCORM Item.
  103. *
  104. * This is a default behaviour, some classes may want to override this.
  105. *
  106. * @param $standalone: Boolean stating if it should be exported as a stand-alone question
  107. *
  108. * @return string string, the XML flow for an Item
  109. */
  110. public function export()
  111. {
  112. global $charset;
  113. /*$head = '';
  114. if ($this->standalone) {
  115. $head = '<?xml version = "1.0" encoding = "'.$charset.'" standalone = "no"?>'."\n"
  116. .'<!DOCTYPE questestinterop SYSTEM "ims_qtiasiv2p1.dtd">'."\n";
  117. }*/
  118. list($js, $html) = $this->exportQuestions();
  119. $res = $this->startPage()
  120. .$this->start_header()
  121. .$this->css()
  122. .$this->globalAssets()
  123. .$this->start_js()
  124. .$this->common_js()
  125. .$js
  126. .$this->end_js()
  127. .$this->end_header()
  128. .$this->start_body()
  129. .$html
  130. .$this->end_body()
  131. .$this->end_page();
  132. return $res;
  133. }
  134. /**
  135. * Export the questions, as a succession of <items>.
  136. *
  137. * @author Amand Tihon <amand@alrj.org>
  138. */
  139. public function exportQuestions()
  140. {
  141. $js = $html = '';
  142. $encoders = [new JsonEncoder()];
  143. $normalizers = [new ObjectNormalizer()];
  144. $em = Database::getManager();
  145. // Export cquiz data
  146. /** @var CQuiz $exercise */
  147. $exercise = $em->find('ChamiloCourseBundle:CQuiz', $this->exercise->iId);
  148. $exercise->setDescription('');
  149. $exercise->setTextWhenFinished('');
  150. $serializer = new Serializer($normalizers, $encoders);
  151. $jsonContent = $serializer->serialize($exercise, 'json');
  152. $js .= "var exerciseInfo = JSON.parse('".$jsonContent."');\n";
  153. $counter = 0;
  154. $scormQuestion = new ScormQuestion();
  155. foreach ($this->exercise->selectQuestionList() as $q) {
  156. list($jstmp, $htmltmp) = $scormQuestion->exportQuestionToScorm($q, $counter);
  157. $js .= $jstmp."\n";
  158. $html .= $htmltmp."\n";
  159. $counter++;
  160. }
  161. return [$js, $html];
  162. }
  163. /**
  164. * Print CSS inclusion.
  165. */
  166. private function css()
  167. {
  168. return '';
  169. }
  170. /**
  171. * End document header.
  172. */
  173. private function end_header()
  174. {
  175. return '</head>';
  176. }
  177. /**
  178. * Start the itemBody.
  179. */
  180. private function start_js()
  181. {
  182. return '<script>';
  183. }
  184. /**
  185. * @return string
  186. */
  187. private function globalAssets()
  188. {
  189. $assets = '<script type="text/javascript" src="assets/jquery/jquery.min.js"></script>'."\n";
  190. $assets .= '<script type="text/javascript" src="assets/api_wrapper.js"></script>'."\n";
  191. $assets .= '<link href="assets/bootstrap/bootstrap.min.css" rel="stylesheet" media="screen" type="text/css" />';
  192. return $assets;
  193. }
  194. }