html5.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. <?php
  2. /**
  3. * Class that implements ilm_handle, in order to allow manipulation and management of HTML5 iLM
  4. *
  5. * @author Igor Moreira Félix
  6. * @author Patricia Alves Rodrigues
  7. * @author Leônidas O. Brandão
  8. * @version v 1 2017/17/10
  9. * @package mod_iassign_ilm_handlers
  10. * @copyright iMatica (<a href="http://www.matematica.br">iMath</a>) - Computer Science Dep. of IME-USP (Brazil)
  11. *
  12. * <b>License</b>
  13. * - http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  14. */
  15. global $CFG;
  16. require_once $CFG->dirroot . '/mod/iassign/ilm_handle.php';
  17. class html5 implements ilm_handle {
  18. /// Produce HTML code to load iLM
  19. public static function build_ilm_tags ($ilm_id, $options = array()) {
  20. global $DB, $OUTPUT;
  21. global $CONF_WWW; //TODO 1 => use iLM under WWW; otherwise use under MoodleData
  22. $html = "";
  23. if (empty($options['Proposition']))
  24. $options['Proposition'] = "";
  25. if (empty($options['addresPOST']))
  26. $options['addresPOST'] = "";
  27. if (empty($options['student_answer']))
  28. $options['student_answer'] = "";
  29. if (empty($options['notSEND']))
  30. $options['notSEND'] = "";
  31. else // Case it is authoring put 'notSEND' (important to iVProgH5 to present authoring tool)
  32. if ($options['type'] == "editor_update")
  33. $options['notSEND'] = "true";
  34. if (empty($options['id_iLM_security'])) // if defined, it is from 'iassign_security'
  35. $options['id_iLM_security'] = "";
  36. $id_iLM_security = $options['id_iLM_security'];
  37. $iassign_ilm = $DB->get_record('iassign_ilm', array('id' => $ilm_id));
  38. if ($iassign_ilm) {
  39. // md_files : filename
  40. $ilm_extension = $iassign_ilm->extension; // use local variavel to efficiency (several use)
  41. if ($ilm_extension) { // avoid problems
  42. $ilm_extension = strtolower($ilm_extension);
  43. }
  44. // Attention: in iAssign 2014 on, all the iLM is located on the Moodle filesystem (usually /var/moodledata/filedir/).
  45. // This means that '$iassign_ilm->file_jar' = '*_files.id'
  46. $file_url = array();
  47. $fs = get_file_storage();
  48. $files_jar = explode(",", $iassign_ilm->file_jar);
  49. $url = $iassign_ilm->file_class; // to HTML5 package, this 'file_class' must have the main HTML file
  50. array_push($file_url, $url);
  51. $lang = substr(current_language(), 0, 2);
  52. if ($options['type'] == "filter") { //leo
  53. $iassign_ilm_width = $options['width']; // or use? $iassign_ilm->width
  54. $iassign_ilm_height = $options['height']; // or use? $iassign_ilm->height
  55. } else { //leo
  56. $iassign_ilm_width = $iassign_ilm->width;
  57. $iassign_ilm_height = $iassign_ilm->height; // or use? $iassign_ilm->height
  58. }
  59. if (!empty($file_url)) { // There is an iLM file
  60. //TODO iLM_HTML5 :: Change to 'object', tag 'applet' was deprecated.
  61. $paramsStr = "?1=1";
  62. switch ($options['type']) {
  63. case "view":
  64. $paramsStr .= "&iLM_PARAM_Assignment=" . urlencode($options['Proposition']); //leo
  65. $paramsStr .= "&iLM_PARAM_SendAnswer=true";
  66. //TODO: REVIEW: this code is to insert iLM as HTML5 and to allow general parameter to any iLM
  67. //TODO: For now, 'iassign_ilm_config' is empty... let comment these lines
  68. //n $iassign_ilm_config = $DB->get_records('iassign_ilm_config', array('iassign_ilmid' => $ilm_id));
  69. //n foreach ($iassign_ilm_config as $ilm_config) {
  70. //n if (array_key_exists($ilm_config->param_name, $options)) {
  71. //n $ilm_config->param_value = $options[$ilm_config->param_name];
  72. //n $paramsStr .= "&" . $ilm_config->param_name . "=" . urlencode($ilm_config->param_value);
  73. //n }
  74. //n }
  75. break;
  76. case "filter":
  77. if ($options['toolbar'] == "disable")
  78. $paramsStr .= "&SOH_ADD=ADD";
  79. $paramsStr .= "&iLM_PARAM_AssignmentURL=true";
  80. $paramsStr .= "&iLM_PARAM_Assignment=" . urlencode($options['Proposition']);
  81. $paramsStr .= "&iLM_PARAM_SendAnswer=" . urlencode($options['notSEND']);
  82. $paramsStr .= "&iLM_PARAM_ServerToGetAnswerURL=" . urlencode($ilm_config->param_value);
  83. break; // static function build_ilm_tags($ilm_id, $options=array())
  84. case "activity": // build_ilm_tags
  85. //TODO To generalize to any HTML5 iLM, it is necessary to use 'iLM_PARAM_Assignment' and 'iLM_PARAM_SendAnswer'
  86. //TODO iLM_PARAM_Assignment=Proposition ; iLM_PARAM_SendAnswer=notSEND
  87. $paramsStr .= "&iLM_PARAM_AssignmentURL=true";
  88. // if ($options['special_param'] == 1) { }
  89. $paramsStr .= "&iLM_PARAM_Assignment=" . urlencode($options['Proposition']);
  90. $paramsStr .= "&iLM_PARAM_SendAnswer=" . urlencode($options['notSEND']);
  91. $paramsStr .= "&iLM_PARAM_ServerToGetAnswerURL=" . urlencode($options['addresPOST']);
  92. //TODO iLM_HTML5 :: To extend to any iLM in HTML5
  93. //TODO iLM_HTML5 :: it will allow to load dynamic parameters
  94. //T $iassign_activity_item_configs = $DB->get_records('iassign_statement_config', array('iassign_statementid' => $options['iassign_statement'] ));
  95. //T if ($iassign_activity_item_configs) {
  96. //T foreach ($iassign_activity_item_configs as $iassign_activity_item_config)
  97. //T $paramsStr .= "&" . $iassign_activity_item_config->param_name . "=" . urlencode($iassign_activity_item_config->param_value);
  98. //T }
  99. break;
  100. case "editor_new":
  101. $paramsStr .= "&iLM_PARAM_AssignmentURL=true";
  102. $paramsStr .= "&iLM_PARAM_SendAnswer=" . urlencode($options['notSEND']);
  103. break;
  104. case "editor_update":
  105. $paramsStr .= "&iLM_PARAM_AssignmentURL=true";
  106. $paramsStr .= "&iLM_PARAM_Assignment=" . urlencode($options['Proposition']);
  107. $paramsStr .= "&iLM_PARAM_SendAnswer=" . urlencode($options['notSEND']);
  108. break;
  109. default:
  110. $html .= iassign::warning_message_iassign('error_view_without_actiontype'); // $OUTPUT->notification(get_string('error_view_without_actiontype', 'iassign'), 'notifyproblem'); // The API allows for creation of four types of notification: error, warning, info, and success.
  111. } // switch($options['type'])
  112. $paramsStr .= "&lang=" . $lang; // get the language defined in Moodle
  113. $parameters = ' style="width: ' . $iassign_ilm_width . 'px; height: ' . $iassign_ilm_height . 'px;" ';
  114. $html .= '<iframe frameborder="0" name="iLM" src="' . $iassign_ilm->file_jar . $iassign_ilm->file_class . $paramsStr . '" ' . $parameters . ' id="iLM">' . "\n";
  115. $html .= '</iframe>' . "\n";
  116. } // if (!empty($file_url))
  117. } // if ($iassign_ilm)
  118. return $html;
  119. } // public static function build_ilm_tags($ilm_id, $options = array())
  120. /// Exibe a atividade no iLM
  121. public static function show_activity_in_ilm ($iassign_statement_activity_item, $student_answer, $enderecoPOST, $view_teacherfileversion) {
  122. global $USER, $CFG, $COURSE, $DB, $OUTPUT;
  123. $special_param1 = $iassign_statement_activity_item->special_param1;
  124. $ilm = $DB->get_record('iassign_ilm', array('id' => $iassign_statement_activity_item->iassign_ilmid));
  125. $context = context_module::instance($USER->cm);
  126. //TODO Given an activity => find its correspondent file in Moodle data. Bad solution!
  127. //TODO Change the meaning of 'iassign_statement.file' from insertion order to the ID in table 'files'.
  128. //TODO This demands update to each 'iassign_statement', find its corresponding on in 'files', and update 'iassign_statement.file = files.id'
  129. if ($view_teacherfileversion) { // get the exercise in Moodle data (teacher file)
  130. $fileid = "";
  131. $fs = get_file_storage();
  132. $files = $fs->get_area_files($context->id, 'mod_iassign', 'exercise', $iassign_statement_activity_item->file); // iassign_statement_activity_item = table 'iassign_statement'
  133. if ($files) {
  134. foreach ($files as $value) {
  135. if ($value->get_filename() != '.')
  136. $fileid = $value->get_id();
  137. }
  138. }
  139. if (!$fileid) { // 'Something is wrong. Maybe your teacher withdrew this exercise file. Please, inform your teacher.';
  140. print iassign::warning_message_iassign('error_exercise_removed') . "<br/>\n"; // I couldn't find the file in table 'files'!
  141. }
  142. }
  143. $ilm_name = strtolower($ilm->name);
  144. $extension = iassign_utils::filename_extension($ilm_name);
  145. if ($view_teacherfileversion) { // $view_teacherfileversion==1 => load the exercise ('activity') from the 'moodledata' (id in 'files')
  146. // $content_or_id_from_ilm_security = $this->context->id;
  147. $content_or_id_from_ilm_security = $fileid; // $iassign_statement_activity_item->file;
  148. } else { // $view_teacherfileversion==null => load the learner answer from the data base (iassign_submission)
  149. $content_or_id_from_ilm_security = $student_answer;
  150. }
  151. $allow_submission = false; // There is permission to 'submission' button?
  152. //VERIFICAR ESTE IF
  153. if ($USER->iassignEdit == 1 && $student_answer) { // for now, only iVProg2 and iVProgH5 allows editions of exercise already sent
  154. $allow_submission = true; // yes!
  155. $write_solution = 1;
  156. $enderecoPOST .= "&write_solution=1"; // complement POST address indicating that the learner could send edited solution
  157. }
  158. // Security: this avoid the student get a second access to the file content (usually an exercise)
  159. // Data are registered in the table '*_iassign_security' bellow and is erased by function 'view()' above.
  160. // IMPORTANT: the '$end_file' will receive the iLM content URL using the security filter './mod/iassign/ilm_security.php'
  161. // the iLM must request the content using this URL. Data are registered in the table '*_iassign_security'.
  162. // Attention : using iVProgH5 there are lot of " and the use of slashes (as '\"') will imply in iVProgH5 do not read the file!
  163. // do not use: $id_iLM_security = $this->write_iLM_security($iassign_statement_activity_item->id, addslashes($content_or_id_from_ilm_security));
  164. //2017 $id_iLM_security = $this->write_iLM_security($iassign_statement_activity_item->id, $content_or_id_from_ilm_security); // insert in 'iassign_security'
  165. //2017 $this->remove_old_iLM_security_entries($USER->id, $iassign_statement_activity_item->id); // additional security: erase eventually old entries
  166. require_once ($CFG->dirroot . '/mod/iassign/ilm_security.php');
  167. $timecreated = time();
  168. $token = md5($timecreated); // iassign_iLM_security->timecreated);
  169. $id_iLM_security = ilm_security::write_iLM_security($USER->id, $timecreated, $iassign_statement_activity_item->id, $content_or_id_from_ilm_security); // insert in 'iassign_security'
  170. // $iassign_iLM_security = $DB->get_record("iassign_security", array("id" => $id_iLM_security));
  171. $end_file = $CFG->wwwroot . '/mod/iassign/ilm_security.php?id=' . $id_iLM_security . '&token=' . $token . '&view=' . $view_teacherfileversion; // need full path...
  172. $iassign = "
  173. <script type='text/javascript'>
  174. //<![CDATA[
  175. var strAnswer = '';
  176. var evaluationResult = '';
  177. var comment = '';
  178. function jsAnalyseAnswer () {
  179. // iVProgH5 will call function 'getEvaluationCallback(...)': /var/www/html/ivprogh5/js/services.js
  180. // 'getEvaluation()' calls 'js/services.js : endTest function(index)' that calls 'getEvaluationCallback(apro/100);'
  181. window.frames.iLM.getEvaluation(); // in './mod/iassign/ilm/ivprog-html/js/services.js'; './mod/iassign/ilm/ivprog-html/main.html'
  182. //alert('jsAnalyseAnswer(): evaluationResult=' + evaluationResult);
  183. // alert('jsAnalyseAnswer(): evaluationResult=' + evaluationResult + ', content=' + window.frames.iLM.getAnswer());
  184. // var comment = document.formEnvio.submission_comment.value;
  185. }
  186. // ./mod/iassign/ilm/ivprog-html/js/services.js : call this to define the variable 'evaluationResult'
  187. function getEvaluationCallback (evaluation) {
  188. evaluationResult = evaluation;
  189. strAnswer = window.frames.iLM.getAnswer();
  190. // alert('getEvaluationCallback(...)' + evaluation + ', strAnswer=' + strAnswer);
  191. comment = document.formEnvio.submission_comment.value;
  192. //leo
  193. if ((strAnswer==null || strAnswer=='' || strAnswer==-1) && (comment==null || comment=='')) { // undefined
  194. alert('" . get_string('activity_empty', 'iassign') . "'); // 'Activity sent without content.'
  195. return false; // error...
  196. }
  197. else {
  198. //leo alert('getEvaluationCallback: enviando evaluationResult=' + evaluation + ', strAnswer=' + strAnswer);
  199. document.formEnvio.iLM_PARAM_ArchiveContent.value = strAnswer;
  200. document.formEnvio.iLM_PARAM_ActivityEvaluation.value = evaluationResult;
  201. document.formEnvio.submit();
  202. return true; // success
  203. }
  204. }
  205. //]]>
  206. </script>\n";
  207. $iassign .= "\n<center>\n<form name='formEnvio' id='formEnvio' method='post' action='$enderecoPOST' enctype='multipart/form-data'>\n";
  208. // Attention: The actual iLM content will be provided by the indirect access in './mod/iassign/ilm_security.php',
  209. // bellow only the 'token' to the content will be shown in URL (by security reason). The iLM must use this URL on
  210. // 'MA_PARAM_Proposition' to request the content.
  211. // Calls static function bellow: parameters are data to store in table '*_iassign_submission'
  212. //leo $iassign .= ilm_settings::build_ilm_tags($this->ilm->id, array(
  213. $iassign .= ilm_settings::build_ilm_tags($ilm->id, array(//leo para testar 'iassign_security'
  214. "type" => "activity",
  215. "notSEND" => "false",
  216. "addresPOST" => $enderecoPOST,
  217. "Proposition" => $end_file,
  218. "special_param" => $special_param1,
  219. "student_answer" => $student_answer,
  220. "id_iLM_security" => $id_iLM_security,
  221. "iassign_statement" => $iassign_statement_activity_item->id // MOOC 2016
  222. ));
  223. if (!isguestuser() && $iassign_statement_activity_item->type_iassign != 1) {
  224. $iassign .= " <input type='hidden' name='iLM_PARAM_ArchiveContent' value=''>\n";
  225. $iassign .= " <input type='hidden' name='iLM_PARAM_ActivityEvaluation' value=''>\n";
  226. if (!has_capability('mod/iassign:evaluateiassign', $USER->context, $USER->id))
  227. $iassign .= "<p><textarea rows='2' cols='60' name='submission_comment'></textarea></p>\n";
  228. else
  229. $iassign .= "<input type='hidden' name='submission_comment'>\n";
  230. if ($allow_submission) { // it is not iGeom
  231. $iassign .= "<center>\n<!-- load button -->\n" .
  232. " <input type=button value='" . get_string('submit_iassign', 'iassign') . "' onClick = 'javascript:window.jsAnalyseAnswer();' title='" .
  233. get_string('message_submit_iassign', 'iassign') . "'>\n" . "</center>\n";
  234. } else {
  235. // Works with 'javascript:window.jsAnalyseAnswer()' or simply 'jsAnalyseAnswer()'
  236. $iassign .= "<center>\n<!-- load button -->\n" .
  237. " <input type=button value='" . get_string('submit_iassign', 'iassign') . "' onClick = 'javascript:window.jsAnalyseAnswer();' title='" .
  238. get_string('message_submit_iassign', 'iassign') . "'>\n" . "</center>\n";
  239. }
  240. } // if (!isguestuser() && $iassign_statement_activity_item->type_iassign != 1)
  241. $iassign .= "</form></center>\n\n";
  242. return $iassign;
  243. }
  244. /// Presents iLM information
  245. public static function view_ilm ($ilmid, $from) {
  246. global $DB;
  247. $url = new moodle_url('/admin/settings.php', array('section' => 'modsettingiassign'));
  248. $iassign_ilm = $DB->get_record('iassign_ilm', array('id' => $ilmid));
  249. $str = "";
  250. $str .= '<table id="outlinetable" cellpadding="5" width="100%" >' . "\n";
  251. $str .= '<tr>';
  252. $str .= '<td colspan=3 align=right>';
  253. if ($from != 'admin') {
  254. $str .= '<input type=button value="' . get_string('return', 'iassign') . '" onclick="javascript:window.location = \'' . $_SERVER['HTTP_REFERER'] . '\';">' . "\n";
  255. }
  256. $str .= '<input type=button value="' . get_string('close', 'iassign') . '" onclick="javascript:window.close();">';
  257. $str .= '</td>' . "\n";
  258. $str .= '</tr>' . "\n";
  259. if ($iassign_ilm) {
  260. $iassign_statement_activity_item = $DB->get_records('iassign_statement', array("iassign_ilmid" => $iassign_ilm->id));
  261. if ($iassign_statement_activity_item) {
  262. $total = count($iassign_statement_activity_item);
  263. } else {
  264. $total = 0;
  265. }
  266. if ($from == 'admin') {
  267. $str .= '<tr><td colspan=2>' . "\n";
  268. $str .= '<table width="100%" class="generaltable boxaligncenter" >' . "\n";
  269. $str .= '<tr>' . "\n";
  270. $str .= '<td class=\'cell c0 actvity\' ><strong>' . get_string('activities', 'iassign') . ':</strong>&nbsp;' . $total . '</td>' . "\n";
  271. $str .= '<td><strong>' . get_string('url_ilm', 'iassign') . '</strong>&nbsp;<a href="' . $iassign_ilm->url . '">' . $iassign_ilm->url . '</a></td>' . "\n";
  272. $str .= '</tr>' . "\n";
  273. $str .= '<tr><td colspan=2><strong>' . get_string('description', 'iassign') . ':</strong>&nbsp;' . iassign_language::get_description_lang(current_language(), $iassign_ilm->description) . '</td></tr>' . "\n";
  274. $str .= '<tr><td width="50%"><strong>' . get_string('type_ilm', 'iassign') . ':</strong>&nbsp;' . $iassign_ilm->type . '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>' . get_string('extension', 'iassign') . ':</strong>&nbsp;' . $iassign_ilm->extension . '</td>' . "\n";
  275. $str .= '<td width="50%"><strong>' . get_string('width', 'iassign') . ':</strong>&nbsp;' . $iassign_ilm->width;
  276. $str .= '&nbsp;&nbsp;<strong>' . get_string('height', 'iassign') . ':</strong>&nbsp;' . $iassign_ilm->height . '</td></tr>' . "\n";
  277. $date_jar = $iassign_ilm->file_jar;
  278. $str .= '<tr><td><strong>' . get_string('file_jar', 'iassign') . '</strong>&nbsp;' . $date_jar . '</td>' . "\n";
  279. $str .= '<td ><strong>' . get_string('file_class', 'iassign') . ':</strong>&nbsp;' . $iassign_ilm->file_class . '</td></tr>' . "\n";
  280. if ($iassign_ilm->evaluate == 1) {
  281. $evaluate = get_string('yes', 'iassign');
  282. } else {
  283. $evaluate = get_string('no', 'iassign');
  284. }
  285. $str .= '<tr><td width="50%"><strong>' . get_string('evaluate', 'iassign') . ':</strong>&nbsp;' . $evaluate . '</td>' . "\n";
  286. if ($iassign_ilm->enable == 1) {
  287. $enable = get_string('yes', 'iassign');
  288. } else {
  289. $enable = get_string('no', 'iassign');
  290. }
  291. $str .= '<td width="50%"><strong>' . get_string('enable', 'iassign') . ':</strong>&nbsp;' . $enable . '</td></tr>' . "\n";
  292. $str .= '<tr>' . "\n";
  293. $str .= '<td width="50%"><strong>' . get_string('file_created', 'iassign') . ':</strong>&nbsp;' . userdate($iassign_ilm->timecreated) . '</td>' . "\n";
  294. $str .= '<td width="50%"><strong>' . get_string('file_modified', 'iassign') . ':</strong>&nbsp;' . userdate($iassign_ilm->timemodified) . '</td>' . "\n";
  295. $str .= '</tr>' . "\n";
  296. $user_ilm = $DB->get_record('user', array('id' => $iassign_ilm->author));
  297. if ($user_ilm) {
  298. $str .= '<tr>' . "\n";
  299. $str .= '<td colspan=2><strong>' . get_string('author', 'iassign') . ':</strong>&nbsp;' . $user_ilm->firstname . '&nbsp;' . $user_ilm->lastname . '</td>' . "\n";
  300. $str .= '</tr>' . "\n";
  301. }
  302. $str .= '</table>' . "\n";
  303. $str .= '</td></tr>' . "\n";
  304. }
  305. if (!empty($iassign_ilm->file_jar)) {
  306. //TODO: REVIEW: to be used for parameters of "applet" from DB
  307. $options = array("type" => "view"); //MOOC2014: start
  308. $str .= '<tr class=\'cell c0 actvity\'><td colspan=3 align=center bgcolor="#F5F5F5">' . "\n";
  309. // Second parameter null since 'iassign_security' are not define yet
  310. $str .= ilm_settings::build_ilm_tags($iassign_ilm->id, $options);
  311. //TODO: REVIEW: missing code to manage parameters
  312. //MOOC2014: tem este codigo!
  313. } else {
  314. $str .= '<tr class=\'cell c0 actvity\'>' . "\n";
  315. $str .= '<td colspan=2 align=center>' . get_string('null_file', 'iassign') . '</td>' . "\n";
  316. $str .= '<td align=center><a href="' . $url . '</a></td>' . "\n";
  317. $str .= '</tr>' . "\n";
  318. }
  319. $str .= '</td></tr>' . "\n";
  320. }
  321. $str .= '</table>' . "\n";
  322. return $str;
  323. } // public static function view_ilm($ilmid, $from)
  324. /// Make a copy or produce a new version of an iLM
  325. public static function copy_new_version_ilm ($param, $files_extract) {
  326. global $DB, $CFG;
  327. $iassign_ilm = new stdClass();
  328. $iassign_ilm->name = $param->name;
  329. $iassign_ilm->version = $param->version;
  330. $iassign_ilm->file_jar = null;
  331. $file_jar = self::save_ilm_by_xml($application_xml, $files_extract);
  332. if ($file_jar == null) {
  333. return false;
  334. }
  335. $file_jar = str_replace("./", "", $file_jar) . "/";
  336. $description = json_decode($param->description_lang);
  337. $description->{$param->set_lang } = $param->description;
  338. $newentry = new stdClass();
  339. $newentry->name = $param->name;
  340. $newentry->version = $param->version;
  341. $newentry->type = 'HTML5';
  342. $newentry->url = $param->url;
  343. $newentry->description = strip_tags(json_encode($description));
  344. $newentry->extension = strtolower($param->extension);
  345. $newentry->file_jar = $file_jar;
  346. $newentry->file_class = $param->file_class;
  347. $newentry->width = $param->width;
  348. $newentry->height = $param->height;
  349. $newentry->enable = 0;
  350. $newentry->timemodified = $param->timemodified;
  351. $newentry->timecreated = $param->timecreated;
  352. $newentry->evaluate = $param->evaluate;
  353. $newentry->author = $param->author;
  354. $newentry->parent = $param->parent;
  355. $newentry->id = $DB->insert_record("iassign_ilm", $newentry);
  356. // log event --------------------------------------------------------------------------------------
  357. iassign_log::add_log('copy_iassign_ilm', 'name: ' . $param->name . ' ' . $param->version, 0, $newentry->id);
  358. // log event --------------------------------------------------------------------------------------
  359. }
  360. /// Export the iLM to the IPZ package
  361. public static function export_ilm ($ilm_id) {
  362. global $DB, $CFG;
  363. $iassign_ilm = $DB->get_record('iassign_ilm', array('id' => $ilm_id));
  364. $iassign_ilm_configs = $DB->get_records('iassign_ilm_config', array('iassign_ilmid' => $ilm_id)); //MOOC 2016
  365. $files_jar = $iassign_ilm->file_jar;
  366. $zip_filename = $CFG->dataroot . '/temp/ilm-' . iassign_utils::format_pathname($iassign_ilm->name . '-v' . $iassign_ilm->version) . '_' . date("Ymd-Hi") . '.ipz';
  367. $zip = new zip_archive;
  368. $zip->open($zip_filename);
  369. $rootdir = $CFG->dirroot . '/mod/iassign/' . $files_jar;
  370. $first_folder = str_replace($CFG->dirroot . '/mod/iassign/ilm/', "", $rootdir);
  371. $zip->add_directory($first_folder);
  372. $allfiles = self::list_directory($rootdir);
  373. $i = 0;
  374. foreach ($allfiles as $file) {
  375. $mini = str_replace($CFG->dirroot . '/mod/iassign/ilm/', "", $file);
  376. $mini = str_replace('//', "/", $mini);
  377. if (is_dir($file)) {
  378. $zip->add_directory($mini);
  379. } else {
  380. $zip->add_file_from_pathname($mini, $file);
  381. }
  382. }
  383. $folder = str_replace('ilm/', "", $files_jar);
  384. $application_descriptor = '<?xml version="1.0" encoding="utf-8"?>' . "\n";
  385. $application_descriptor .= '<application xmlns="http://line.ime.usp.br/application/1.5">' . "\n";
  386. $application_descriptor .= ' <name>' . $iassign_ilm->name . '</name>' . "\n";
  387. $application_descriptor .= ' <url>' . $iassign_ilm->url . '</url>' . "\n";
  388. $application_descriptor .= ' <version>' . $iassign_ilm->version . '</version>' . "\n";
  389. $application_descriptor .= ' <type>' . $iassign_ilm->type . '</type>' . "\n";
  390. $application_descriptor .= ' <description>' . html_entity_decode(str_replace(array('<p>', '</p>'), array('', ''), $iassign_ilm->description)) . '</description>' . "\n";
  391. $application_descriptor .= ' <extension>' . $iassign_ilm->extension . '</extension>' . "\n";
  392. $application_descriptor .= ' <file_jar>' . $folder . '</file_jar>' . "\n";
  393. $application_descriptor .= ' <file_class>' . $iassign_ilm->file_class . '</file_class>' . "\n";
  394. $application_descriptor .= ' <width>' . $iassign_ilm->width . '</width>' . "\n";
  395. $application_descriptor .= ' <height>' . $iassign_ilm->height . '</height>' . "\n";
  396. $application_descriptor .= ' <evaluate>' . $iassign_ilm->evaluate . '</evaluate>' . "\n";
  397. if ($iassign_ilm_configs) { //MOOC 2016
  398. $application_descriptor .= ' <params>' . "\n";
  399. foreach ($iassign_ilm_configs as $iassign_ilm_config) {
  400. $application_descriptor .= ' <param>' . "\n";
  401. $application_descriptor .= ' <type>' . $iassign_ilm_config->param_type . '</type>' . "\n";
  402. $application_descriptor .= ' <name>' . $iassign_ilm_config->param_name . '</name>' . "\n";
  403. $application_descriptor .= ' <value>' . $iassign_ilm_config->param_value . '</value>' . "\n";
  404. $application_descriptor .= ' <description>' . htmlentities(str_replace("\n", "", $iassign_ilm_config->description)) . '</description>' . "\n";
  405. $application_descriptor .= ' <visible>' . $iassign_ilm_config->visible . '</visible>' . "\n";
  406. $application_descriptor .= ' </param>' . "\n";
  407. }
  408. $application_descriptor .= ' </params>' . "\n";
  409. } //MOOC 2016
  410. $application_descriptor .= '</application>' . "\n";
  411. $zip->add_file_from_string('ilm-application.xml', $application_descriptor);
  412. $zip->close();
  413. header("Pragma: public");
  414. header("Expires: 0");
  415. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  416. header("Cache-Control: private", false);
  417. header("Content-Type: application/zip");
  418. header("Content-Disposition: attachment; filename=\"" . basename($zip_filename) . "\";");
  419. header("Content-Transfer-Encoding: binary");
  420. header("Content-Length: " . (filesize($zip_filename) + 1000));
  421. set_time_limit(0);
  422. readfile($zip_filename) || die("File not found.");
  423. unlink($zip_filename);
  424. exit;
  425. } // public static function export_ilm($ilm_id)
  426. /// Function for list the directory where iLM is allocated.
  427. // @param type $dir
  428. // @return type
  429. static function list_directory ($dir) {
  430. $files = array();
  431. $cont = 0;
  432. $ffs = scandir($dir);
  433. unset($ffs[array_search('.', $ffs, true)]);
  434. unset($ffs[array_search('..', $ffs, true)]);
  435. if (count($ffs) < 1) {
  436. return;
  437. }
  438. foreach ($ffs as $ff) {
  439. $files[$cont] = $dir . "/" . $ff;
  440. $cont++;
  441. if (is_dir($dir . '/' . $ff)) {
  442. $temp = self::list_directory($dir . '/' . $ff);
  443. foreach ($temp as $t) {
  444. $files[$cont] = $t;
  445. $cont++;
  446. }
  447. }
  448. }
  449. return $files;
  450. }
  451. public static function delete_ilm($ilm_id) {
  452. global $DB, $CFG, $OUTPUT;
  453. $iassign_ilm = $DB->get_record('iassign_ilm', array('id' => $ilm_id));
  454. // Check if the iLM directory is writable
  455. if (!is_writable($iassign_ilm->file_jar)) {
  456. return null;
  457. }
  458. self::delete_dir($iassign_ilm->file_jar);
  459. $DB->delete_records("iassign_ilm", array('id' => $ilm_id));
  460. $DB->delete_records("iassign_ilm_config", array('iassign_ilmid' => $ilm_id)); //MOOC 2016
  461. // log event --------------------------------------------------------------------------------------
  462. iassign_log::add_log('delete_iassign_ilm', 'name: ' . $iassign_ilm->name . ' ' . $iassign_ilm->version, 0, $iassign_ilm->id);
  463. // log event --------------------------------------------------------------------------------------
  464. return $iassign_ilm->parent;
  465. }
  466. /// Receive the updated data from an iLM to process it
  467. public static function edit_ilm ($param, $itemid, $files_extract, $contextuser) {
  468. global $DB, $CFG;
  469. $iassign_ilm = new stdClass();
  470. $iassign_ilm->name = $param->name;
  471. $iassign_ilm->version = $param->version;
  472. $iassign_ilm->file_jar = $param->file_jar;
  473. $file_jar = null;
  474. if (!is_null($files_extract)) {
  475. $file_jar = self::save_ilm_by_xml(null, $files_extract);
  476. if ($file_jar == null) {
  477. return false;
  478. }
  479. $file_jar = str_replace("./", "", $file_jar) . "/";
  480. }
  481. $description = json_decode($param->description_lang);
  482. $description->{$param->set_lang } = $param->description;
  483. $updentry = new stdClass();
  484. $updentry->id = $param->id;
  485. $updentry->version = $param->version;
  486. $updentry->url = $param->url;
  487. $updentry->description = strip_tags(json_encode($description));
  488. $updentry->extension = strtolower($param->extension);
  489. if (!is_null($file_jar)) {
  490. $updentry->file_jar = $file_jar;
  491. }
  492. $updentry->file_class = $param->file_class;
  493. $updentry->width = $param->width;
  494. $updentry->height = $param->height;
  495. $updentry->enable = $param->enable;
  496. $updentry->timemodified = $param->timemodified;
  497. $updentry->evaluate = $param->evaluate;
  498. $DB->update_record("iassign_ilm", $updentry);
  499. // log event --------------------------------------------------------------------------------------
  500. iassign_log::add_log('update_iassign_ilm', 'name: ' . $param->name . ' ' . $param->version, 0, $param->id);
  501. // log event --------------------------------------------------------------------------------------
  502. } // public static function edit_ilm($param, $itemid, $files_extract, $contextuser)
  503. /// Function for save iLM file in moodledata
  504. // @param int $itemid Itemid of file save in draft (upload file)
  505. // @param int $ilm_id Id of iLM
  506. // @return string Return an string with ids of iLM files
  507. static function new_file_ilm ($itemid, $fs, $contextuser, $contextsystem, $files_ilm) {
  508. global $CFG, $USER, $DB;
  509. if ($files_ilm) {
  510. foreach ($files_ilm as $value) {
  511. // Check if it is an HTML5 iLM
  512. // Copy:
  513. $destination = 'ilm_debug/' . $value->get_filename();
  514. $value->copy_content_to($destination);
  515. // Extract the content:
  516. $zip = new ZipArchive();
  517. $extracted = './ilm';
  518. $dir = "";
  519. if ($zip->open($destination) === TRUE) {
  520. $dir = './ilm/' . trim($zip->getNameIndex(0));
  521. if (is_dir($dir)) {
  522. $i = 1;
  523. $previous = str_replace("/", "", $zip->getNameIndex(0));
  524. while (file_exists('./ilm/' . $previous . "_" . $i)) {
  525. $i ++;
  526. }
  527. $name = $previous . "_" . $i;
  528. $dir = './ilm/' . $name . "/";
  529. $j = 0;
  530. while ($item_name = $zip->getNameIndex($j)) {
  531. $zip->renameIndex($j, str_replace($previous, $name, $item_name));
  532. $j++;
  533. }
  534. $zip->close();
  535. }
  536. $zip->open($destination);
  537. $zip->extractTo($extracted);
  538. $zip->close();
  539. // After extract, remove from debug:
  540. unlink($destination);
  541. } else { // if ($zip->open($destination) === TRUE)
  542. // After trying to extract, occurring error, erase ZIP file:
  543. unlink($destination);
  544. print_error('error_add_ilm_zip', 'iassign');
  545. }
  546. return $dir;
  547. } // foreach ($files_ilm as $value)
  548. } // if ($files_ilm)
  549. } // static function new_file_ilm($itemid, $fs, $contextuser, $contextsystem, $files_ilm)
  550. /// Register data to the new iLM (in database and in proper directory)
  551. public static function new_ilm ($itemid, $files_extract, $application_xml, $contextuser, $fs) {
  552. global $DB, $CFG, $USER, $OUTPUT;
  553. $description_str = str_replace(array('<description>', '</description>'), array('', ''), $application_xml->description->asXML());
  554. $iassign_ilm = $DB->get_record('iassign_ilm', array("name" => (String) $application_xml->name, "version" => (String) $application_xml->version));
  555. if ($iassign_ilm) {
  556. foreach ($files_extract as $key => $value) {
  557. $rootfolder = $CFG->dataroot . '/temp/' . $key;
  558. self::delete_dir($rootfolder);
  559. break;
  560. }
  561. print($OUTPUT->notification(get_string('error_import_ilm_version', 'iassign'), 'notifyproblem'));
  562. return false;
  563. } else {
  564. $file_jar = self::save_ilm_by_xml($application_xml, $files_extract);
  565. if ($file_jar == null) {
  566. return false;
  567. }
  568. $file_jar = str_replace("./", "", $file_jar);
  569. if (empty($file_jar))
  570. print_error('error_add_ilm', 'iassign');
  571. else { // if (empty($file_jar))
  572. $iassign_ilm = $DB->get_record('iassign_ilm', array("parent" => 0, "name" => (String) $application_xml->name));
  573. if (!$iassign_ilm) {
  574. $iassign_ilm = new stdClass(); //MOOC 2016
  575. $iassign_ilm->id = 0;
  576. }
  577. $newentry = new stdClass();
  578. $newentry->name = (String) $application_xml->name;
  579. $newentry->version = (String) $application_xml->version;
  580. $newentry->type = (String) $application_xml->type;
  581. $newentry->url = (String) $application_xml->url;
  582. $newentry->description = strip_tags($description_str);
  583. $newentry->extension = strtolower((String) $application_xml->extension);
  584. $newentry->file_jar = $file_jar . "/";
  585. $newentry->file_class = (String) $application_xml->file_class;
  586. $newentry->width = (String) $application_xml->width;
  587. $newentry->height = (String) $application_xml->height;
  588. $newentry->enable = 0;
  589. $newentry->timemodified = time();
  590. $newentry->author = $USER->id;
  591. $newentry->timecreated = time();
  592. $newentry->evaluate = (String) $application_xml->evaluate;
  593. $newentry->parent = $iassign_ilm->id;
  594. //MOOC 2016 $newentry->id = $DB->insert_record("iassign_ilm", $newentry);
  595. $newentry->id = $DB->insert_record("iassign_ilm", $newentry);
  596. // log event --------------------------------------------------------------------------------------
  597. iassign_log::add_log('add_iassign_ilm', 'name: ' . $newentry->name . ' ' . $newentry->version, 0, $newentry->id);
  598. // log event --------------------------------------------------------------------------------------
  599. if ($application_xml->params->param) {
  600. foreach ($application_xml->params->param as $value) {
  601. $newentry = new stdClass();
  602. $newentry->iassign_ilmid = $iassign_ilmid;
  603. $newentry->param_type = (String) $value->type;
  604. $newentry->param_name = (String) $value->name;
  605. $newentry->param_value = (String) $value->value;
  606. $newentry->description = html_entity_decode((String) $value->description);
  607. $newentry->visible = (String) $value->visible;
  608. $newentry->id = $DB->insert_record("iassign_ilm", $newentry);
  609. if (!$newentry->id) {
  610. print_error('error_add_param', 'iassign');
  611. }
  612. }
  613. }
  614. }
  615. }
  616. $fs->delete_area_files($contextuser->id, 'user', 'draft', $itemid);
  617. return true;
  618. }
  619. /// Import an iLM
  620. public static function import_ilm ($itemid, $files_extract, $application_xml, $contextuser, $fs) {
  621. global $DB, $CFG, $USER, $OUTPUT;
  622. $description_str = str_replace(array('<description>', '</description>'), array('', ''), $application_xml->description->asXML());
  623. $iassign_ilm = $DB->get_record('iassign_ilm', array("name" => (String) $application_xml->name, "version" => (String) $application_xml->version));
  624. if ($iassign_ilm) {
  625. foreach ($files_extract as $key => $value) {
  626. $rootfolder = $CFG->dataroot . '/temp/' . $key;
  627. self::delete_dir($rootfolder);
  628. break;
  629. }
  630. print($OUTPUT->notification(get_string('error_import_ilm_version', 'iassign'), 'notifyproblem'));
  631. } else {
  632. $file_jar = self::save_ilm_by_xml($application_xml, $files_extract);
  633. if ($file_jar == null) {
  634. return false;
  635. }
  636. $file_jar = str_replace("./", "", $file_jar);
  637. if (empty($file_jar))
  638. print_error('error_add_ilm', 'iassign');
  639. else { // if (empty($file_jar))
  640. $iassign_ilm = $DB->get_record('iassign_ilm', array("parent" => 0, "name" => (String) $application_xml->name));
  641. if (!$iassign_ilm) {
  642. $iassign_ilm = new stdClass(); //MOOC 2016
  643. $iassign_ilm->id = 0;
  644. }
  645. $newentry = new stdClass();
  646. $newentry->name = (String) $application_xml->name;
  647. $newentry->version = (String) $application_xml->version;
  648. $newentry->type = (String) $application_xml->type;
  649. $newentry->url = (String) $application_xml->url;
  650. $newentry->description = strip_tags($description_str);
  651. $newentry->extension = strtolower((String) $application_xml->extension);
  652. $newentry->file_jar = $file_jar . "/";
  653. $newentry->file_class = (String) $application_xml->file_class;
  654. $newentry->width = (String) $application_xml->width;
  655. $newentry->height = (String) $application_xml->height;
  656. $newentry->enable = 0;
  657. $newentry->timemodified = time();
  658. $newentry->author = $USER->id;
  659. $newentry->timecreated = time();
  660. $newentry->evaluate = (String) $application_xml->evaluate;
  661. $newentry->parent = $iassign_ilm->id;
  662. //MOOC 2016 $newentry->id = $DB->insert_record("iassign_ilm", $newentry);
  663. $iassign_ilmid = $DB->insert_record("iassign_ilm", $newentry);
  664. if ($application_xml->params->param) {
  665. foreach ($application_xml->params->param as $value) {
  666. $newentry = new stdClass();
  667. $newentry->iassign_ilmid = $iassign_ilmid;
  668. $newentry->param_type = (String) $value->type;
  669. $newentry->param_name = (String) $value->name;
  670. $newentry->param_value = (String) $value->value;
  671. $newentry->description = html_entity_decode((String) $value->description);
  672. $newentry->visible = (String) $value->visible;
  673. $newentry->id = $DB->insert_record("iassign_ilm", $newentry);
  674. if (!$newentry->id) {
  675. print_error('error_add_param', 'iassign');
  676. }
  677. }
  678. } // if ($application_xml->params->param)
  679. } // else if (empty($file_jar))
  680. print($OUTPUT->notification(get_string('ok_import_ilm_version', 'iassign'), 'notifysuccess'));
  681. }
  682. $fs->delete_area_files($contextuser->id, 'user', 'draft', $itemid);
  683. } // public static function import_ilm($itemid, $files_extract, $application_xml, $contextuser, $fs)
  684. // static function export_update_ilm($ilm_id) //MOOC 2016
  685. /// Function for save iLM from XML descriptor
  686. // @param array $application_xml Data of XML descriptor
  687. // @param array $files_extract Filenames of extract files
  688. // @return array Return an array content id of JAR files
  689. static function save_ilm_by_xml ($application_xml, $files_extract) {
  690. global $CFG, $USER, $OUTPUT;
  691. $source = "";
  692. $diretorio = "";
  693. // Check if the iLM directory is writable
  694. if (!is_writable("ilm/")) {
  695. print($OUTPUT->notification(get_string('error_folder_permission_denied', 'iassign'), 'notifyproblem'));
  696. return null;
  697. }
  698. foreach ($files_extract as $key => $value) {
  699. $file = $CFG->dataroot . '/temp/' . $key;
  700. // Check if the directory already exists in iLM directory
  701. if (is_dir($file)) {
  702. $source = $file;
  703. if (file_exists("ilm/" . basename($file))) {
  704. $j = 1;
  705. while (file_exists('ilm/' . basename($file) . "_" . $j)) {
  706. $j ++;
  707. }
  708. $diretorio = 'ilm/' . basename($file) . "_" . $j;
  709. mkdir($diretorio, 0777, true);
  710. } else {
  711. $diretorio = 'ilm/' . basename($file);
  712. mkdir($diretorio, 0777, true);
  713. }
  714. break;
  715. }
  716. } // foreach ($files_extract as $key => $value)
  717. // Write in the MoodleData 'temp' directory, also in the WWW 'mod/iassign/ilm/'
  718. //D foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item
  719. foreach ($iterator = new RecursiveIteratorIterator(
  720. new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
  721. ) {
  722. if ($item->isDir()) {
  723. mkdir($diretorio . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
  724. } else {
  725. copy($item, $diretorio . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
  726. }
  727. }
  728. self::delete_dir($source);
  729. return "./" . $diretorio;
  730. } // static function save_ilm_by_xml($application_xml, $files_extract)
  731. /// Function for delete directory where the iLM is allocated.
  732. // @param string $dirPath
  733. // @throws InvalidArgumentException
  734. public static function delete_dir ($dirPath) {
  735. if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
  736. $dirPath .= '/';
  737. }
  738. $files = glob($dirPath . '*', GLOB_MARK);
  739. foreach ($files as $file) {
  740. if (is_dir($file)) {
  741. self::delete_dir($file);
  742. } else {
  743. unlink($file);
  744. }
  745. }
  746. rmdir($dirPath);
  747. }
  748. } // class html5 implements ilm_handle
  749. ?>