[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 /** 18 * Badge award criteria 19 * 20 * @package core 21 * @subpackage badges 22 * @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 * @author Yuliya Bozhko <yuliya.bozhko@totaralms.com> 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /* 30 * Role completion criteria type 31 * Criteria type constant, primarily for storing criteria type in the database. 32 */ 33 define('BADGE_CRITERIA_TYPE_OVERALL', 0); 34 35 /* 36 * Activity completion criteria type 37 * Criteria type constant, primarily for storing criteria type in the database. 38 */ 39 define('BADGE_CRITERIA_TYPE_ACTIVITY', 1); 40 41 /* 42 * Duration completion criteria type 43 * Criteria type constant, primarily for storing criteria type in the database. 44 */ 45 define('BADGE_CRITERIA_TYPE_MANUAL', 2); 46 47 /* 48 * Grade completion criteria type 49 * Criteria type constant, primarily for storing criteria type in the database. 50 */ 51 define('BADGE_CRITERIA_TYPE_SOCIAL', 3); 52 53 /* 54 * Course completion criteria type 55 * Criteria type constant, primarily for storing criteria type in the database. 56 */ 57 define('BADGE_CRITERIA_TYPE_COURSE', 4); 58 59 /* 60 * Courseset completion criteria type 61 * Criteria type constant, primarily for storing criteria type in the database. 62 */ 63 define('BADGE_CRITERIA_TYPE_COURSESET', 5); 64 65 /* 66 * Course completion criteria type 67 * Criteria type constant, primarily for storing criteria type in the database. 68 */ 69 define('BADGE_CRITERIA_TYPE_PROFILE', 6); 70 71 /* 72 * Criteria type constant to class name mapping 73 */ 74 global $BADGE_CRITERIA_TYPES; 75 $BADGE_CRITERIA_TYPES = array( 76 BADGE_CRITERIA_TYPE_OVERALL => 'overall', 77 BADGE_CRITERIA_TYPE_ACTIVITY => 'activity', 78 BADGE_CRITERIA_TYPE_MANUAL => 'manual', 79 BADGE_CRITERIA_TYPE_SOCIAL => 'social', 80 BADGE_CRITERIA_TYPE_COURSE => 'course', 81 BADGE_CRITERIA_TYPE_COURSESET => 'courseset', 82 BADGE_CRITERIA_TYPE_PROFILE => 'profile' 83 ); 84 85 /** 86 * Award criteria abstract definition 87 * 88 */ 89 abstract class award_criteria { 90 91 /** 92 * ID of the criterion. 93 * @var integer 94 */ 95 public $id; 96 97 /** 98 * Aggregation method [BADGE_CRITERIA_AGGREGATION_ANY, BADGE_CRITERIA_AGGREGATION_ALL]. 99 * @var integer 100 */ 101 public $method; 102 103 /** 104 * ID of a badge this criterion belongs to. 105 * @var integer 106 */ 107 public $badgeid; 108 109 /** 110 * Criterion HTML/plain text description. 111 * @var string 112 */ 113 public $description; 114 115 /** 116 * Format of the criterion description. 117 * @var integer 118 */ 119 public $descriptionformat; 120 121 /** 122 * Any additional parameters. 123 * @var array 124 */ 125 public $params = array(); 126 127 /** 128 * The base constructor 129 * 130 * @param array $params 131 */ 132 public function __construct($params) { 133 $this->id = isset($params['id']) ? $params['id'] : 0; 134 $this->method = isset($params['method']) ? $params['method'] : BADGE_CRITERIA_AGGREGATION_ANY; 135 $this->badgeid = $params['badgeid']; 136 $this->description = isset($params['description']) ? $params['description'] : ''; 137 $this->descriptionformat = isset($params['descriptionformat']) ? $params['descriptionformat'] : FORMAT_HTML; 138 if (isset($params['id'])) { 139 $this->params = $this->get_params($params['id']); 140 } 141 } 142 143 /** 144 * Factory method for creating criteria class object 145 * 146 * @param array $params associative arrays varname => value 147 * @return award_criteria 148 */ 149 public static function build($params) { 150 global $CFG, $BADGE_CRITERIA_TYPES; 151 152 if (!isset($params['criteriatype']) || !isset($BADGE_CRITERIA_TYPES[$params['criteriatype']])) { 153 print_error('error:invalidcriteriatype', 'badges'); 154 } 155 156 $class = 'award_criteria_' . $BADGE_CRITERIA_TYPES[$params['criteriatype']]; 157 require_once($CFG->dirroot . '/badges/criteria/' . $class . '.php'); 158 159 return new $class($params); 160 } 161 162 /** 163 * Return criteria title 164 * 165 * @return string 166 */ 167 public function get_title() { 168 return get_string('criteria_' . $this->criteriatype, 'badges'); 169 } 170 171 /** 172 * Get criteria details for displaying to users 173 * 174 * @param string $short Print short version of criteria 175 * @return string 176 */ 177 abstract public function get_details($short = ''); 178 179 /** 180 * Add appropriate criteria options to the form 181 * 182 */ 183 abstract public function get_options(&$mform); 184 185 /** 186 * Add appropriate parameter elements to the criteria form 187 * 188 */ 189 public function config_options(&$mform, $param) { 190 global $OUTPUT; 191 $prefix = $this->required_param . '_'; 192 193 if ($param['error']) { 194 $parameter[] =& $mform->createElement('advcheckbox', $prefix . $param['id'], '', 195 $OUTPUT->error_text($param['name']), null, array(0, $param['id'])); 196 $mform->addGroup($parameter, 'param_' . $prefix . $param['id'], '', array(' '), false); 197 } else { 198 $parameter[] =& $mform->createElement('advcheckbox', $prefix . $param['id'], '', $param['name'], null, array(0, $param['id'])); 199 $parameter[] =& $mform->createElement('static', 'break_start_' . $param['id'], null, '<div style="margin-left: 3em;">'); 200 201 if (in_array('grade', $this->optional_params)) { 202 $parameter[] =& $mform->createElement('static', 'mgrade_' . $param['id'], null, get_string('mingrade', 'badges')); 203 $parameter[] =& $mform->createElement('text', 'grade_' . $param['id'], '', array('size' => '5')); 204 $mform->setType('grade_' . $param['id'], PARAM_INT); 205 } 206 207 if (in_array('bydate', $this->optional_params)) { 208 $parameter[] =& $mform->createElement('static', 'complby_' . $param['id'], null, get_string('bydate', 'badges')); 209 $parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['id'], "", array('optional' => true)); 210 } 211 212 $parameter[] =& $mform->createElement('static', 'break_end_' . $param['id'], null, '</div>'); 213 $mform->addGroup($parameter, 'param_' . $prefix . $param['id'], '', array(' '), false); 214 if (in_array('grade', $this->optional_params)) { 215 $mform->addGroupRule('param_' . $prefix . $param['id'], array( 216 'grade_' . $param['id'] => array(array(get_string('err_numeric', 'form'), 'numeric', '', 'client')))); 217 } 218 $mform->disabledIf('bydate_' . $param['id'] . '[day]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked'); 219 $mform->disabledIf('bydate_' . $param['id'] . '[month]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked'); 220 $mform->disabledIf('bydate_' . $param['id'] . '[year]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked'); 221 $mform->disabledIf('param_' . $prefix . $param['id'], $prefix . $param['id'], 'notchecked'); 222 } 223 224 // Set default values. 225 $mform->setDefault($prefix . $param['id'], $param['checked']); 226 if (isset($param['bydate'])) { 227 $mform->setDefault('bydate_' . $param['id'], $param['bydate']); 228 } 229 if (isset($param['grade'])) { 230 $mform->setDefault('grade_' . $param['id'], $param['grade']); 231 } 232 } 233 234 /** 235 * Add appropriate criteria elements 236 * 237 * @param stdClass $data details of various criteria 238 */ 239 public function config_form_criteria($data) { 240 global $OUTPUT; 241 $agg = $data->get_aggregation_methods(); 242 243 $editurl = new moodle_url('/badges/criteria_settings.php', 244 array('badgeid' => $this->badgeid, 'edit' => true, 'type' => $this->criteriatype, 'crit' => $this->id)); 245 $deleteurl = new moodle_url('/badges/criteria_action.php', 246 array('badgeid' => $this->badgeid, 'delete' => true, 'type' => $this->criteriatype)); 247 $editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null, array('class' => 'criteria-action')); 248 $deleteaction = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', get_string('delete')), null, array('class' => 'criteria-action')); 249 250 echo $OUTPUT->box_start(); 251 if (!$data->is_locked() && !$data->is_active()) { 252 echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header')); 253 } 254 echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help'); 255 256 if (!empty($this->description)) { 257 $badge = new badge($this->badgeid); 258 echo $OUTPUT->box( 259 format_text($this->description, $this->descriptionformat, array('context' => $badge->get_context())), 260 'criteria-description' 261 ); 262 } 263 264 if (!empty($this->params)) { 265 if (count($this->params) > 1) { 266 echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges', 267 core_text::strtoupper($agg[$data->get_aggregation_method($this->criteriatype)])), array('clearfix')); 268 } else { 269 echo $OUTPUT->box(get_string('criteria_descr_single_' . $this->criteriatype , 'badges'), array('clearfix')); 270 } 271 echo $OUTPUT->box($this->get_details(), array('clearfix')); 272 } 273 echo $OUTPUT->box_end(); 274 } 275 276 /** 277 * Review this criteria and decide if the user has completed 278 * 279 * @param int $userid User whose criteria completion needs to be reviewed. 280 * @param bool $filtered An additional parameter indicating that user list 281 * has been reduced and some expensive checks can be skipped. 282 * 283 * @return bool Whether criteria is complete 284 */ 285 abstract public function review($userid, $filtered = false); 286 287 /** 288 * Returns array with sql code and parameters returning all ids 289 * of users who meet this particular criterion. 290 * 291 * @return array list($join, $where, $params) 292 */ 293 abstract public function get_completed_criteria_sql(); 294 295 /** 296 * Mark this criteria as complete for a user 297 * 298 * @param int $userid User whose criteria is completed. 299 */ 300 public function mark_complete($userid) { 301 global $DB; 302 $obj = array(); 303 $obj['critid'] = $this->id; 304 $obj['userid'] = $userid; 305 $obj['datemet'] = time(); 306 if (!$DB->record_exists('badge_criteria_met', array('critid' => $this->id, 'userid' => $userid))) { 307 $DB->insert_record('badge_criteria_met', $obj); 308 } 309 } 310 311 /** 312 * Return criteria parameters 313 * 314 * @param int $critid Criterion ID 315 * @return array 316 */ 317 public function get_params($cid) { 318 global $DB; 319 $params = array(); 320 321 $records = $DB->get_records('badge_criteria_param', array('critid' => $cid)); 322 foreach ($records as $rec) { 323 $arr = explode('_', $rec->name); 324 $params[$arr[1]][$arr[0]] = $rec->value; 325 } 326 327 return $params; 328 } 329 330 /** 331 * Delete this criterion 332 * 333 */ 334 public function delete() { 335 global $DB, $PAGE; 336 337 // Remove any records if it has already been met. 338 $DB->delete_records('badge_criteria_met', array('critid' => $this->id)); 339 340 // Remove all parameters records. 341 $DB->delete_records('badge_criteria_param', array('critid' => $this->id)); 342 343 // Finally remove criterion itself. 344 $DB->delete_records('badge_criteria', array('id' => $this->id)); 345 346 // Trigger event, badge criteria deleted. 347 $eventparams = array('objectid' => $this->id, 348 'context' => $PAGE->context, 349 'other' => array('badgeid' => $this->badgeid)); 350 $event = \core\event\badge_criteria_deleted::create($eventparams); 351 $event->trigger(); 352 } 353 354 /** 355 * Saves intial criteria records with required parameters set up. 356 * 357 * @param array $params Values from the form or any other array. 358 */ 359 public function save($params = array()) { 360 global $DB, $PAGE; 361 362 // Figure out criteria description. 363 // If it is coming from the form editor, it is an array(text, format). 364 $description = ''; 365 $descriptionformat = FORMAT_HTML; 366 if (isset($params['description']['text'])) { 367 $description = $params['description']['text']; 368 $descriptionformat = $params['description']['format']; 369 } else if (isset($params['description'])) { 370 $description = $params['description']; 371 } 372 373 $fordb = new stdClass(); 374 $fordb->criteriatype = $this->criteriatype; 375 $fordb->method = isset($params['agg']) ? $params['agg'] : BADGE_CRITERIA_AGGREGATION_ALL; 376 $fordb->badgeid = $this->badgeid; 377 $fordb->description = $description; 378 $fordb->descriptionformat = $descriptionformat; 379 $t = $DB->start_delegated_transaction(); 380 381 // Pick only params that are required by this criterion. 382 // Filter out empty values first. 383 $params = array_filter($params); 384 // Find out which param matches optional and required ones. 385 $match = array_merge($this->optional_params, array($this->required_param)); 386 $regex = implode('|', array_map(create_function('$a', 'return $a . "_";'), $match)); 387 $requiredkeys = preg_grep('/^(' . $regex . ').*$/', array_keys($params)); 388 389 if ($this->id !== 0) { 390 $cid = $this->id; 391 392 // Update criteria before doing anything with parameters. 393 $fordb->id = $cid; 394 $DB->update_record('badge_criteria', $fordb, true); 395 396 // Trigger event: badge_criteria_updated. 397 $eventparams = array('objectid' => $this->id, 398 'context' => $PAGE->context, 399 'other' => array('badgeid' => $this->badgeid)); 400 $event = \core\event\badge_criteria_updated::create($eventparams); 401 $event->trigger(); 402 403 $existing = $DB->get_fieldset_select('badge_criteria_param', 'name', 'critid = ?', array($cid)); 404 $todelete = array_diff($existing, $requiredkeys); 405 406 if (!empty($todelete)) { 407 // A workaround to add some disabled elements that are still being submitted from the form. 408 foreach ($todelete as $del) { 409 $name = explode('_', $del); 410 if ($name[0] == $this->required_param) { 411 foreach ($this->optional_params as $opt) { 412 $todelete[] = $opt . '_' . $name[1]; 413 } 414 } 415 } 416 $todelete = array_unique($todelete); 417 list($sql, $sqlparams) = $DB->get_in_or_equal($todelete, SQL_PARAMS_NAMED, 'd', true); 418 $sqlparams = array_merge(array('critid' => $cid), $sqlparams); 419 $DB->delete_records_select('badge_criteria_param', 'critid = :critid AND name ' . $sql, $sqlparams); 420 } 421 422 foreach ($requiredkeys as $key) { 423 if (in_array($key, $existing)) { 424 $updp = $DB->get_record('badge_criteria_param', array('name' => $key, 'critid' => $cid)); 425 $updp->value = $params[$key]; 426 $DB->update_record('badge_criteria_param', $updp, true); 427 } else { 428 $newp = new stdClass(); 429 $newp->critid = $cid; 430 $newp->name = $key; 431 $newp->value = $params[$key]; 432 $DB->insert_record('badge_criteria_param', $newp); 433 } 434 } 435 } else { 436 $cid = $DB->insert_record('badge_criteria', $fordb, true); 437 if ($cid) { 438 foreach ($requiredkeys as $key) { 439 $newp = new stdClass(); 440 $newp->critid = $cid; 441 $newp->name = $key; 442 $newp->value = $params[$key]; 443 $DB->insert_record('badge_criteria_param', $newp, false, true); 444 } 445 } 446 // Trigger event: badge_criteria_created. 447 $eventparams = array('objectid' => $this->id, 448 'context' => $PAGE->context, 449 'other' => array('badgeid' => $this->badgeid)); 450 $event = \core\event\badge_criteria_created::create($eventparams); 451 $event->trigger(); 452 } 453 $t->allow_commit(); 454 } 455 456 /** 457 * Saves intial criteria records with required parameters set up. 458 */ 459 public function make_clone($newbadgeid) { 460 global $DB; 461 462 $fordb = new stdClass(); 463 $fordb->criteriatype = $this->criteriatype; 464 $fordb->method = $this->method; 465 $fordb->badgeid = $newbadgeid; 466 $fordb->description = $this->description; 467 $fordb->descriptionformat = $this->descriptionformat; 468 if (($newcrit = $DB->insert_record('badge_criteria', $fordb, true)) && isset($this->params)) { 469 foreach ($this->params as $k => $param) { 470 foreach ($param as $key => $value) { 471 $paramdb = new stdClass(); 472 $paramdb->critid = $newcrit; 473 $paramdb->name = $key . '_' . $k; 474 $paramdb->value = $value; 475 $DB->insert_record('badge_criteria_param', $paramdb); 476 } 477 } 478 } 479 } 480 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |