PageRenderTime 24ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/badges/criteria/award_criteria_activity.php

https://github.com/pauln/moodle
PHP | 266 lines | 175 code | 32 blank | 59 comment | 34 complexity | 171ee479921fda50d0b0d35f1ce6eeee MD5 | raw file
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * This file contains the activity badge award criteria type class
  18. *
  19. * @package core
  20. * @subpackage badges
  21. * @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. * @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
  24. */
  25. defined('MOODLE_INTERNAL') || die();
  26. require_once($CFG->libdir . '/completionlib.php');
  27. /**
  28. * Badge award criteria -- award on activity completion
  29. *
  30. */
  31. class award_criteria_activity extends award_criteria {
  32. /* @var int Criteria [BADGE_CRITERIA_TYPE_ACTIVITY] */
  33. public $criteriatype = BADGE_CRITERIA_TYPE_ACTIVITY;
  34. private $courseid;
  35. private $course;
  36. public $required_param = 'module';
  37. public $optional_params = array('bydate');
  38. public function __construct($record) {
  39. global $DB;
  40. parent::__construct($record);
  41. $this->course = $DB->get_record_sql('SELECT c.id, c.enablecompletion, c.cacherev, c.startdate
  42. FROM {badge} b INNER JOIN {course} c ON b.courseid = c.id
  43. WHERE b.id = :badgeid ', array('badgeid' => $this->badgeid));
  44. $this->courseid = $this->course->id;
  45. }
  46. /**
  47. * Gets the module instance from the database and returns it.
  48. * If no module instance exists this function returns false.
  49. *
  50. * @return stdClass|bool
  51. */
  52. private function get_mod_instance($cmid) {
  53. global $DB;
  54. $rec = $DB->get_record_sql("SELECT md.name
  55. FROM {course_modules} cm,
  56. {modules} md
  57. WHERE cm.id = ? AND
  58. md.id = cm.module", array($cmid));
  59. if ($rec) {
  60. return get_coursemodule_from_id($rec->name, $cmid);
  61. } else {
  62. return null;
  63. }
  64. }
  65. /**
  66. * Get criteria description for displaying to users
  67. *
  68. * @return string
  69. */
  70. public function get_details($short = '') {
  71. global $DB, $OUTPUT;
  72. $output = array();
  73. foreach ($this->params as $p) {
  74. $mod = self::get_mod_instance($p['module']);
  75. if (!$mod) {
  76. $str = $OUTPUT->error_text(get_string('error:nosuchmod', 'badges'));
  77. } else {
  78. $str = html_writer::tag('b', '"' . get_string('modulename', $mod->modname) . ' - ' . $mod->name . '"');
  79. if (isset($p['bydate'])) {
  80. $str .= get_string('criteria_descr_bydate', 'badges', userdate($p['bydate'], get_string('strftimedate', 'core_langconfig')));
  81. }
  82. }
  83. $output[] = $str;
  84. }
  85. if ($short) {
  86. return implode(', ', $output);
  87. } else {
  88. return html_writer::alist($output, array(), 'ul');
  89. }
  90. }
  91. /**
  92. * Add appropriate new criteria options to the form
  93. *
  94. */
  95. public function get_options(&$mform) {
  96. $none = true;
  97. $existing = array();
  98. $missing = array();
  99. $course = $this->course;
  100. $info = new completion_info($course);
  101. $mods = $info->get_activities();
  102. $mids = array_keys($mods);
  103. if ($this->id !== 0) {
  104. $existing = array_keys($this->params);
  105. $missing = array_diff($existing, $mids);
  106. }
  107. if (!empty($missing)) {
  108. $mform->addElement('header', 'category_errors', get_string('criterror', 'badges'));
  109. $mform->addHelpButton('category_errors', 'criterror', 'badges');
  110. foreach ($missing as $m) {
  111. $this->config_options($mform, array('id' => $m, 'checked' => true,
  112. 'name' => get_string('error:nosuchmod', 'badges'), 'error' => true));
  113. $none = false;
  114. }
  115. }
  116. if (!empty($mods)) {
  117. $mform->addElement('header', 'first_header', $this->get_title());
  118. foreach ($mods as $mod) {
  119. $checked = false;
  120. if (in_array($mod->id, $existing)) {
  121. $checked = true;
  122. }
  123. $param = array('id' => $mod->id,
  124. 'checked' => $checked,
  125. 'name' => get_string('modulename', $mod->modname) . ' - ' . $mod->name,
  126. 'error' => false
  127. );
  128. if ($this->id !== 0 && isset($this->params[$mod->id]['bydate'])) {
  129. $param['bydate'] = $this->params[$mod->id]['bydate'];
  130. }
  131. if ($this->id !== 0 && isset($this->params[$mod->id]['grade'])) {
  132. $param['grade'] = $this->params[$mod->id]['grade'];
  133. }
  134. $this->config_options($mform, $param);
  135. $none = false;
  136. }
  137. }
  138. // Add aggregation.
  139. if (!$none) {
  140. $mform->addElement('header', 'aggregation', get_string('method', 'badges'));
  141. $agg = array();
  142. $agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodactivity', 'badges'), 1);
  143. $agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodactivity', 'badges'), 2);
  144. $mform->addGroup($agg, 'methodgr', '', array('<br/>'), false);
  145. if ($this->id !== 0) {
  146. $mform->setDefault('agg', $this->method);
  147. } else {
  148. $mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY);
  149. }
  150. }
  151. return array($none, get_string('error:noactivities', 'badges'));
  152. }
  153. /**
  154. * Review this criteria and decide if it has been completed
  155. *
  156. * @param int $userid User whose criteria completion needs to be reviewed.
  157. * @param bool $filtered An additional parameter indicating that user list
  158. * has been reduced and some expensive checks can be skipped.
  159. *
  160. * @return bool Whether criteria is complete
  161. */
  162. public function review($userid, $filtered = false) {
  163. $completionstates = array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS);
  164. if ($this->course->startdate > time()) {
  165. return false;
  166. }
  167. $info = new completion_info($this->course);
  168. $overall = false;
  169. foreach ($this->params as $param) {
  170. $cm = new stdClass();
  171. $cm->id = $param['module'];
  172. $data = $info->get_data($cm, false, $userid);
  173. $check_date = true;
  174. if (isset($param['bydate'])) {
  175. $date = $data->timemodified;
  176. $check_date = ($date <= $param['bydate']);
  177. }
  178. if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
  179. if (in_array($data->completionstate, $completionstates) && $check_date) {
  180. $overall = true;
  181. continue;
  182. } else {
  183. return false;
  184. }
  185. } else {
  186. if (in_array($data->completionstate, $completionstates) && $check_date) {
  187. return true;
  188. } else {
  189. $overall = false;
  190. continue;
  191. }
  192. }
  193. }
  194. return $overall;
  195. }
  196. /**
  197. * Returns array with sql code and parameters returning all ids
  198. * of users who meet this particular criterion.
  199. *
  200. * @return array list($join, $where, $params)
  201. */
  202. public function get_completed_criteria_sql() {
  203. $join = '';
  204. $where = '';
  205. $params = array();
  206. if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
  207. foreach ($this->params as $param) {
  208. $moduledata[] = " cmc.coursemoduleid = :completedmodule{$param['module']} ";
  209. $params["completedmodule{$param['module']}"] = $param['module'];
  210. }
  211. if (!empty($moduledata)) {
  212. $extraon = implode(' OR ', $moduledata);
  213. $join = " JOIN {course_modules_completion} cmc ON cmc.userid = u.id AND
  214. ( cmc.completionstate = :completionpass OR cmc.completionstate = :completioncomplete ) AND ({$extraon})";
  215. $params["completionpass"] = COMPLETION_COMPLETE_PASS;
  216. $params["completioncomplete"] = COMPLETION_COMPLETE;
  217. }
  218. return array($join, $where, $params);
  219. } else {
  220. foreach ($this->params as $param) {
  221. $join .= " LEFT JOIN {course_modules_completion} cmc{$param['module']} ON
  222. cmc{$param['module']}.userid = u.id AND
  223. cmc{$param['module']}.coursemoduleid = :completedmodule{$param['module']} AND
  224. ( cmc{$param['module']}.completionstate = :completionpass{$param['module']} OR
  225. cmc{$param['module']}.completionstate = :completioncomplete{$param['module']} )";
  226. $where .= " AND cmc{$param['module']}.coursemoduleid IS NOT NULL ";
  227. $params["completedmodule{$param['module']}"] = $param['module'];
  228. $params["completionpass{$param['module']}"] = COMPLETION_COMPLETE_PASS;
  229. $params["completioncomplete{$param['module']}"] = COMPLETION_COMPLETE;
  230. }
  231. return array($join, $where, $params);
  232. }
  233. }
  234. }