lib.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. <?php
  2. /**
  3. * Library of functions and constants for module of activities iAssign.
  4. *
  5. * - v 1.3.1 2022/09/19
  6. * + Changes in comments (erased accents)
  7. * - v 1.3 2014/01/10
  8. * + Insert comment unread in course module (iassign_cm_info_view).
  9. * - v 1.2 2013/12/13
  10. * + Insert log in iAssign actions.
  11. *
  12. * @author Patricia Alves Rodrigues
  13. * @author Leônidas O. Brandão
  14. * @version v 1.3 2014/01/10
  15. * @package mod_iassign_lib
  16. * @since 2010/09/27
  17. * @copyright iMath (http://www.matematica.br) and LInE (http://line.ime.usp.br) - Computer Science Dep. of IME-USP (Brazil)
  18. *
  19. * <b>License</b>
  20. * - http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21. */
  22. require_once($CFG->dirroot . "/mod/iassign/locallib.php");
  23. function iassign_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $iassignnode) {
  24. global $USER, $PAGE, $CFG, $DB, $OUTPUT;
  25. if (optional_param('iassign_current', 0, PARAM_INT)) {
  26. $childnode = $iassignnode->create(get_string('edit_iassign', 'iassign'), new moodle_url('/mod/iassign/view.php', array('action' => 'edit', 'id' => optional_param('id', 0, PARAM_INT), 'iassign_current' => optional_param('iassign_current', 0, PARAM_INT) )), navigation_node::TYPE_SETTING);
  27. // 2019/02/12
  28. $children_key_list = $iassignnode->get_children_key_list();
  29. if (is_array($children_key_list) && count($children_key_list)>0)
  30. $iassignnode->add_node($childnode, $children_key_list[0]); //TODO: verify...
  31. // else $iassignnode->add_node($childnode, "");
  32. }
  33. }
  34. /// List of features supported in iAssign module
  35. // @param string $feature FEATURE_xx constant for requested feature
  36. // @return mixed True if module supports feature, false if not, null if doesn't know
  37. function iassign_supports ($feature) {
  38. switch ($feature) {
  39. case FEATURE_GROUPS: return false;
  40. case FEATURE_GROUPINGS: return false;
  41. case FEATURE_GROUPMEMBERSONLY: return false;
  42. case FEATURE_MOD_INTRO: return true;
  43. case FEATURE_SHOW_DESCRIPTION: return true;
  44. case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
  45. case FEATURE_GRADE_HAS_GRADE: return true;
  46. case FEATURE_GRADE_OUTCOMES: return true;
  47. case FEATURE_GRADE_HAS_GRADE: return true;
  48. case FEATURE_BACKUP_MOODLE2: return true;
  49. default: return null;
  50. }
  51. }
  52. /// Function for insert a link with messages in iassigns for students and teacher.
  53. // @param cm_info $cm_info array Informations of module course.
  54. // @see http://docs.moodle.org/dev/Module_visibility_and_display
  55. function iassign_cm_info_view (cm_info $cm_info) {
  56. global $CFG, $DB, $USER, $COURSE;
  57. $comment_unread = "";
  58. $sum_comment = 0;
  59. $iassign_statements = $DB->get_records("iassign_statement", array("iassignid" => $cm_info->instance));
  60. foreach ($iassign_statements as $iassign_statement) {
  61. $cm = get_coursemodule_from_instance("iassign", $iassign_statement->id, optional_param('id', 0, PARAM_INT));
  62. if ($cm) {
  63. $contextuser = context_module::instance($cm->id);
  64. $teacher_access = has_capability('mod/iassign:evaluateiassign', $contextuser, $USER->id);
  65. $student_access = has_capability('mod/iassign:submitiassign', $contextuser, $USER->id);
  66. $iassign_submissions = array();
  67. if ($teacher_access) {
  68. $receiver = '1';
  69. $iassign_submissions = $DB->get_records("iassign_submission", array("iassign_statementid" => $iassign_statement->id));
  70. }
  71. else
  72. if ($student_access) {
  73. $receiver = '2';
  74. $iassign_submissions = $DB->get_records("iassign_submission", array("iassign_statementid" => $iassign_statement->id, "userid" => $USER->id));
  75. }
  76. foreach ($iassign_submissions as $iassign_submission) {
  77. $params = array('iassign_submissionid' => $iassign_submission->id, 'return_status' => '0', 'receiver' => $receiver);
  78. $strQuery = 'SELECT COUNT(iassign_submissionid) FROM {iassign_submission_comment} WHERE ' .
  79. ' iassign_submissionid = :iassign_submissionid AND return_status= :return_status AND receiver= :receiver';
  80. $verify_message = $DB->get_record_sql($strQuery, $params);
  81. if ($verify_message)
  82. foreach ($verify_message as $tmp)
  83. $sum_comment += $tmp;
  84. }
  85. }
  86. }
  87. if ($sum_comment != 0) {
  88. $comment_unread_message = get_string('comment_unread', 'iassign');
  89. if ($sum_comment == 1)
  90. $comment_unread_message = get_string('comment_unread_one', 'iassign');
  91. if ($teacher_access)
  92. $comment_unread = "&nbsp;&nbsp;<a href='" . $CFG->wwwroot . "/mod/iassign/view.php?id=" . $cm_info->id . "&action=report&iassignid=" . $cm_info->instance . "'><font color='red'>" . iassign_icons::insert('comment_unread') . "&nbsp;($sum_comment&nbsp;" . $comment_unread_message . ")</font></a>";
  93. else if ($student_access) //http://localhost/moodle24/mod/iassign/view.php?id=463&userid_iassign=4&action=view&iassign_current=1
  94. $comment_unread = "&nbsp;&nbsp;<font color='red'>" . iassign_icons::insert('comment_unread') . "&nbsp;($sum_comment&nbsp;" . get_string('comment_unread', 'iassign') . ")</font>";
  95. }
  96. $cm_info->set_after_link($comment_unread);
  97. }
  98. /// This function is used by the reset_course_userdata function in moodlelib.
  99. // @param $data the data submitted from the reset course.
  100. // @return array status array
  101. function iassign_reset_userdata ($data) {
  102. return array();
  103. }
  104. /// List of view style log actions
  105. // @return array
  106. function iassign_get_view_actions () {
  107. return array('view', 'view submission');
  108. }
  109. /// List of update style log actions
  110. // @return array
  111. function iassign_get_post_actions () {
  112. return array('update', 'add', 'upload', 'update comment', 'update submission', 'delete iassign', 'add comment', 'add submission');
  113. }
  114. /// Adds an iAssign instance
  115. // @param object $iassign An object from the form in mod_form.php
  116. // @return Fail / id number of the new instance
  117. function iassign_add_instance ($data, $mform) {
  118. global $DB;
  119. $cmid = $data->coursemodule;
  120. $iassignid = $DB->insert_record("iassign", $data);
  121. $data->id = $iassignid;
  122. $context = context_module::instance($cmid);
  123. $iassign = $DB->get_record('iassign', array('id' => $iassignid), '*', MUST_EXIST);
  124. iassign_grade_item($iassign);
  125. // log event -----------------------------------------------------
  126. iassign_log::add_log('add_iassign', 'name: ' . $data->name, $cmid);
  127. // log event -----------------------------------------------------
  128. return $iassign->id;
  129. }
  130. /// Display an item in grade of activities iAssign.
  131. // @param object $iassign An object from the form.
  132. function iassign_grade_item ($iassign) {
  133. global $DB, $CFG;
  134. require_once($CFG->libdir . '/gradelib.php');
  135. /// @todo Ver código comentado
  136. // if (!$iassign->id = $DB->insert_record("iassign", $iassign))
  137. // return false;
  138. // $iassign=(stripslashes_recursive($iassign));
  139. $iassign->grade = 0;
  140. $grades = NULL;
  141. //RR if (array_key_exists('cmidnumber', $iassign)) //it may not be always present
  142. if (isset($iassign->cmidnumber)) { //it may not be always present
  143. $params = array('itemname' => $iassign->name, 'idnumber' => $iassign->cmidnumber);
  144. }
  145. else {
  146. $params = array('itemname' => $iassign->name);
  147. }
  148. if ($iassign->grade > 0) {
  149. $params['gradetype'] = GRADE_TYPE_VALUE;
  150. $params['gradiLMx'] = $iassign->grade;
  151. $params['grademin'] = 0;
  152. }
  153. else {
  154. $params['gradetype'] = GRADE_TYPE_NONE;
  155. }
  156. if ($grades === 'reset') {
  157. $params['reset'] = true;
  158. $grades = NULL;
  159. }
  160. else if (!empty($grades)) {
  161. // Need to calculate raw grade (Note: $grades has many forms)
  162. if (is_object($grades)) {
  163. $grades = array($grades->userid => $grades);
  164. }
  165. else if (array_key_exists('userid', $grades)) {
  166. $grades = array($grades['userid'] => $grades);
  167. }
  168. foreach ($grades as $key => $grade) {
  169. $grades[$key] = $grade = (array) $grade;
  170. }
  171. $grades[$key]['rawgrade'] = ($grade['rawgrade'] * $iassign->grade / 100);
  172. }
  173. grade_update('mod/iassign', $iassign->course, 'mod', 'iassign', $iassign->id, 0, $grades, $params);
  174. }
  175. /// This function will update an existing instance with new data.
  176. // @param object $iassign An object from the form in mod.html
  177. // @return boolean Fail Return the result.
  178. function iassign_update_instance ($data, $mform) {
  179. global $DB, $CFG;
  180. $data->id = $data->instance;
  181. $cmid = $data->coursemodule;
  182. $DB->update_record("iassign", $data);
  183. $context = context_module::instance($cmid);
  184. iassign_grade_item_update($data->id);
  185. // log event -----------------------------------------------------
  186. iassign_log::add_log('update_iassign', 'name: ' . $data->name, $cmid);
  187. // log event -----------------------------------------------------
  188. return true;
  189. }
  190. /// Update an item in grade of activities iAssign.
  191. // @param int $iassignid Id to activities iAssign
  192. function iassign_grade_item_update ($iassignid) {
  193. global $USER, $CFG, $COURSE, $DB, $OUTPUT;
  194. require_once($CFG->libdir . '/gradelib.php');
  195. // $sum_grade = $DB->get_records_sql("SELECT SUM(grade) as total FROM {$CFG->prefix}iassign_statement s WHERE s.iassignid = '$iassignid' AND s.type_iassign=3");
  196. $sum_grade = 0;
  197. $grade = $DB->get_records('iassign_statement', array('iassignid' => $iassignid, 'type_iassign' => 3));
  198. foreach ($grade as $tmp) {
  199. $sum_grade += $tmp->grade;
  200. }
  201. $grade_iassign = $DB->get_record("iassign", array("id" => $iassignid));
  202. $grades = NULL;
  203. $params = array('itemname' => $grade_iassign->name);
  204. $params['iteminstance'] = $iassignid;
  205. $params['gradetype'] = GRADE_TYPE_VALUE;
  206. if ($sum_grade != 0) {
  207. $params['gradiLMx'] = $sum_grade;
  208. $params['rawgradiLMx'] = $sum_grade;
  209. }
  210. else {
  211. $params['gradiLMx'] = 0;
  212. $params['rawgradiLMx'] = 0;
  213. }
  214. $params['grademin'] = 0;
  215. grade_update('mod/iassign', $grade_iassign->course, 'mod', 'iassign', $iassignid, 0, $grades, $params);
  216. $grades = $DB->get_records('grade_grades', array('itemid' => $iassignid));
  217. if ($grades) {
  218. foreach ($grades as $grade) {
  219. $grade->rawgradiLMx = $params['rawgradiLMx'];
  220. $DB->update_record("grade_grades", $grade);
  221. }
  222. }
  223. }
  224. /// Delete an item in grade of activities iAssign.
  225. // @param int $id Id to activities iAssign
  226. function iassign_delete_instance ($id) {
  227. global $DB;
  228. $result = true;
  229. if (!$iassign = $DB->get_record("iassign", array("id" => $id))) {
  230. return false;
  231. }
  232. $DB->delete_records('event', array('modulename' => 'iassign', 'instance' => $iassign->id));
  233. iassign_grade_item_delete($iassign);
  234. $iassign_statements = $DB->get_records("iassign_statement", array("iassignid" => $iassign->id));
  235. if ($iassign_statements) {
  236. foreach ($iassign_statements as $iassign_statement) {
  237. $iassign_statements_submissions = $DB->get_records("iassign_submission", array("iassign_statementid" => $iassign_statement->id));
  238. if ($iassign_statements_submissions) {
  239. foreach ($iassign_statements_submissions as $iassign_statements_submission) {
  240. $DB->delete_records('iassign_submission_comment', array('iassign_submissionid' => $iassign_statements_submission->id));
  241. }
  242. $DB->delete_records("iassign_submission ", array("iassign_statementid" => $iassign_statement->id));
  243. }
  244. }
  245. $DB->delete_records("iassign_statement", array("iassignid" => $iassign->id));
  246. }
  247. if (!$DB->delete_records("iassign", array("id" => $iassign->id))) {
  248. $result = false;
  249. }
  250. return $result;
  251. }
  252. /// Given an ID of an instance of this module,
  253. // this function will permanently delete the instance
  254. // and any data that depends on it.
  255. // @param object $iassign
  256. function iassign_grade_item_delete ($iassign) {
  257. global $DB, $CFG;
  258. require_once($CFG->libdir . '/gradelib.php');
  259. grade_update('mod/iassign', $iassign->course, 'mod', 'iassign', $iassign->id, 0, NULL, array('deleted' => 1));
  260. }
  261. /// Return a small object with summary information about what a
  262. // user has done with a given particular instance of this module
  263. // Used for user activity reports.
  264. // $return->time = the time they did it
  265. // $return->info = a short text description
  266. // @return boolean Return the state of function.
  267. function iassign_user_outline ($course, $user, $mod, $iassign) {
  268. return true;
  269. }
  270. /// Print a detailed representation of what a user has done with
  271. // a given particular instance of this module, for user activity reports.
  272. // @return boolean Return the state of function.
  273. function iassign_user_complete ($course, $user, $mod, $iassign) {
  274. return true;
  275. }
  276. /// Given a course and a time, this module should find recent activity
  277. // that has occurred in ia activities and print it out.
  278. // Return true if there was output, or false is there was none.
  279. // @return boolean Return the state of function.
  280. function iassign_print_recent_activity ($course, $isteacher, $timestart) {
  281. global $DB, $CFG;
  282. return false; // True if anything was printed, otherwise false
  283. }
  284. /// Function to be run periodically according to the moodle cron
  285. // This function searches for things that need to be done, such
  286. // as sending out mail, toggling flags etc ...
  287. // @return boolean Return the state of function.
  288. function iassign_cron () {
  289. global $DB, $CFG;
  290. return true;
  291. }
  292. /// Must return an array of grades for a given instance of this module,
  293. // indexed by user. It also returns a maximum allowed grade.
  294. // Example:
  295. // $return->grades = array of grades;
  296. // $return->maxgrade = maximum allowed grade;
  297. // return $return;
  298. // @param int $iassignid ID of an instance of this module
  299. // @return mixed Null or object with an array of grades and with the maximum grade
  300. function iassign_grades ($iassignid) {
  301. return NULL;
  302. }
  303. /// Must return an array of user records (all data) who are participants
  304. // for a given instance of ia. Must include every user involved
  305. // in the instance, independient of his role (student, teacher, admin...)
  306. // See other modules as example.
  307. // @param int $iassignid ID of an instance of this module
  308. // @return mixed boolean/array of students
  309. function iassign_get_participants ($iassignid) {
  310. return false;
  311. }
  312. /// This function returns if a scale is being used by one ia
  313. // it it has support for grading and scales. Commented code should be
  314. // modified if necessary. See forum, glossary or journal modules
  315. // as reference.
  316. // @param int $iassignid ID of an instance of this module
  317. // @return mixed boolean/array of students
  318. function iassign_scale_used ($iassignid, $scaleid) {
  319. $return = false;
  320. /// @todo Ver código comentado
  321. //$rec = $DB->get_record("iassign","id","$iassignid","scale","-$scaleid");
  322. //if (!empty($rec) && !empty($scaleid)) { $return = true; }
  323. return $return;
  324. }
  325. /// Checks if scale is being used by any instance of ia.
  326. // This function was added in 1.9
  327. // This is used to find out if scale used anywhere
  328. // @param $scaleid int
  329. // @return boolean True if the scale is used by any ia
  330. function iassign_scale_used_anywhere ($scaleid) {
  331. if ($scaleid and record_exists('iassign', 'grade', -$scaleid)) {
  332. return true;
  333. }
  334. else {
  335. return false;
  336. }
  337. }
  338. /// Search iLM
  339. // @param boolean $enable
  340. // @return array of iLM
  341. function search_iLM ($enable) {
  342. global $DB;
  343. $ilms = $DB->get_records('iassign_ilm', array('enable' => $enable));
  344. return $ilms;
  345. }
  346. /// Base implementation for backing up subtype specific information
  347. // for one single module
  348. // @return boolean Return the state of function.
  349. function backup_one_mod ($bf, $preferences, $iassign) {
  350. return true;
  351. }
  352. /// Base implementation for backing up subtype specific information
  353. // for one single submission
  354. // @return boolean Return the state of function.
  355. function backup_one_submission ($bf, $preferences, $iassign, $submission) {
  356. return true;
  357. }
  358. /// Base implementation for restoring subtype specific information
  359. // for one single module
  360. // @return boolean Return the state of function.
  361. function restore_one_mod ($info, $restore, $iassign) {
  362. return true;
  363. }
  364. /// Base implementation for restoring subtype specific information
  365. // for one single submission
  366. // @return boolean
  367. function restore_one_submission ($info, $restore, $iassign, $submission) {
  368. return true;
  369. }
  370. /// Used by Moodle file system to return iLM file content
  371. // It is called under URL http://.../pluginfile.php/2470/mod_iassign/exercise/903/aula5-baricentro_EF_web.geo
  372. // (1) (2) (3) (4) (5)
  373. // Where (1), (2), (3), (4) and (5) are (respctivelly) field 'contextid', 'component', 'fileare', 'itemid' and 'filename' of {files}
  374. // @param object $course
  375. // @param object $cm
  376. // @param object $context
  377. // @param string $filearea
  378. // @param array $args
  379. // @param bool $forcedownload
  380. // @return bool false if file not found, does not return if found - justsend the file
  381. // @calledby /lib/filelib.php: function file_pluginfile($relativepath, $forcedownload, $preview = null, $offline = false, $embed = false)
  382. // $filefunction = $component.'_pluginfile'; if (function_exists($filefunction)) $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, $sendfileoptions);
  383. function iassign_pluginfile ($course, $cm, $context, $filearea, $args, $forcedownload) {
  384. global $CFG, $DB;
  385. require_course_login($course, true, $cm);
  386. $fileareas = array('exercise', 'submit', 'activity', 'ilm');
  387. if (!in_array($filearea, $fileareas)) {
  388. return false;
  389. }
  390. $fs = get_file_storage();
  391. $itemid = (int) array_shift($args); // must be {files}.itemid
  392. $relativepath = implode('/', $args);
  393. $fullpath = "/" . $context->id . "/mod_iassign/" . $filearea . "/" . $itemid . "/" . $relativepath;
  394. //D echo "lib.php: iassign_pluginfile(.): context.id=" . $context->id . ": fullpath=" . $fullpath . "<br/>\n"; //exit;
  395. //D echo "sha1(" . $fullpath . ")=". sha1($fullpath) . "<br/>";
  396. //lib.php: iassign_pluginfile(.): context.id=55853: fullpath=/55853/mod_iassign/exercise/6023/ex4_7_laco_simples_for_imprimir_n_primeiros_termos_pa.ivph
  397. // (1) (2) (3) (4) (5)
  398. // They are {files}'s fields: (1)=contextid ; (2)=component ; (3)=filearea ; (4)=itemid ; (5)=filename
  399. // ./lib/filestorage/file_storage.php: public function get_file_by_hash($pathnamehash)
  400. // Try to recover iLM content file through {files}.pathnamehash
  401. $one_file = $fs->get_file_by_hash(sha1($fullpath));
  402. if (!$one_file || $one_file->is_directory()) { // if different Moodle version created iAssign {files}...
  403. //D echo "Erro: via sha1 falhou!<br/>\n";
  404. // ./lib/filestorage/file_storage.php: public function get_area_files($contextid, $component, $filearea, $itemid = false,...)
  405. $array_files = $fs->get_area_files($context->id, "mod_iassign", $filearea, $itemid);
  406. foreach ($array_files as $one_file) {
  407. $filename = $one_file->get_filename();
  408. if ($filename!=".")
  409. break; // found the {iassign_statement} associated {files}
  410. //D echo "{files} : id=" . $one_file->get_id() . ", filename=" . $one_file->get_filename() . "<br/>\n";
  411. }
  412. if (!$one_file || $one_file->filename == ".") {
  413. //D echo "Ops! Not found...<br/>"; exit;
  414. return false;
  415. }
  416. }
  417. //D echo "one_file: id=" . $one_file->get_id() . ", filename=" . $one_file->get_filename() . "<br/>"; //exit;
  418. // If error "Object of class stored_file could not be converted to string" => lost reference
  419. // Finally send the file
  420. send_stored_file($one_file, 0, 0, false); // download MUST be forced - security!
  421. return false;
  422. }
  423. /// Display an url from access iLM.
  424. // @calledby settings.php
  425. // @param string $url Initial url
  426. // @return string Return the url formatted.
  427. function display_url_ilm ($url) {
  428. // note: empty URL are prevented in form validation
  429. $url = trim($url);
  430. // remove encoded entities - we want the raw URI here
  431. $url = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
  432. if (!preg_match('|^[a-z]+:|i', $url) and ! preg_match('|^/|', $url)) {
  433. // invalid URI, try to fix it by making it normal URL, please note relative url are not allowed, /xx/yy links are ok
  434. $url = 'http://' . $url;
  435. }
  436. return $url;
  437. }