Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 * This file contains the profile completion badge award criteria type class 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 require_once($CFG->dirroot . "/user/lib.php"); 29 30 /** 31 * Profile completion badge award criteria 32 * 33 */ 34 class award_criteria_profile extends award_criteria { 35 36 /* @var int Criteria [BADGE_CRITERIA_TYPE_PROFILE] */ 37 public $criteriatype = BADGE_CRITERIA_TYPE_PROFILE; 38 39 public $required_param = 'field'; 40 public $optional_params = array(); 41 42 /* @var array The default profile fields allowed to be used as award criteria. 43 * 44 * Note: This is used instead of user_get_default_fields(), because it is not possible to 45 * determine which fields the user can modify. 46 */ 47 protected $allowed_default_fields = [ 48 'firstname', 49 'lastname', 50 'email', 51 'address', 52 'phone1', 53 'phone2', 54 'icq', 55 'skype', 56 'yahoo', 57 'aim', 58 'msn', 59 'department', 60 'institution', 61 'description', 62 'picture', 63 'city', 64 'url', 65 'country', 66 ]; 67 68 /** 69 * Add appropriate new criteria options to the form 70 * 71 */ 72 public function get_options(&$mform) { 73 global $DB; 74 75 $none = true; 76 $existing = array(); 77 $missing = array(); 78 $dfields = $this->allowed_default_fields; 79 80 $sql = "SELECT uf.id as fieldid, uf.name as name, ic.id as categoryid, ic.name as categoryname, uf.datatype 81 FROM {user_info_field} uf 82 JOIN {user_info_category} ic 83 ON uf.categoryid = ic.id AND uf.visible <> 0 84 ORDER BY ic.sortorder ASC, uf.sortorder ASC"; 85 86 // Get custom fields. 87 $cfields = $DB->get_records_sql($sql); 88 $cfids = array_map(function($o) { 89 return $o->fieldid; 90 }, $cfields); 91 92 if ($this->id !== 0) { 93 $existing = array_keys($this->params); 94 $missing = array_diff($existing, array_merge($dfields, $cfids)); 95 } 96 97 if (!empty($missing)) { 98 $mform->addElement('header', 'category_errors', get_string('criterror', 'badges')); 99 $mform->addHelpButton('category_errors', 'criterror', 'badges'); 100 foreach ($missing as $m) { 101 $this->config_options($mform, array('id' => $m, 'checked' => true, 'name' => get_string('error:nosuchfield', 'badges'), 'error' => true)); 102 $none = false; 103 } 104 } 105 106 if (!empty($dfields)) { 107 $mform->addElement('header', 'first_header', $this->get_title()); 108 $mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges'); 109 foreach ($dfields as $field) { 110 $checked = false; 111 if (in_array($field, $existing)) { 112 $checked = true; 113 } 114 $this->config_options($mform, array('id' => $field, 'checked' => $checked, 'name' => get_user_field_name($field), 'error' => false)); 115 $none = false; 116 } 117 } 118 119 if (!empty($cfields)) { 120 foreach ($cfields as $field) { 121 if (!isset($currentcat) || $currentcat != $field->categoryid) { 122 $currentcat = $field->categoryid; 123 $mform->addElement('header', 'category_' . $currentcat, format_string($field->categoryname)); 124 } 125 $checked = false; 126 if (in_array($field->fieldid, $existing)) { 127 $checked = true; 128 } 129 $this->config_options($mform, array('id' => $field->fieldid, 'checked' => $checked, 'name' => $field->name, 'error' => false)); 130 $none = false; 131 } 132 } 133 134 // Add aggregation. 135 if (!$none) { 136 $mform->addElement('header', 'aggregation', get_string('method', 'badges')); 137 $agg = array(); 138 $agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodprofile', 'badges'), 1); 139 $agg[] =& $mform->createElement('static', 'none_break', null, '<br/>'); 140 $agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodprofile', 'badges'), 2); 141 $mform->addGroup($agg, 'methodgr', '', array(' '), false); 142 if ($this->id !== 0) { 143 $mform->setDefault('agg', $this->method); 144 } else { 145 $mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY); 146 } 147 } 148 149 return array($none, get_string('noparamstoadd', 'badges')); 150 } 151 152 /** 153 * Get criteria details for displaying to users 154 * 155 * @return string 156 */ 157 public function get_details($short = '') { 158 global $DB, $OUTPUT; 159 $output = array(); 160 foreach ($this->params as $p) { 161 if (is_numeric($p['field'])) { 162 $str = $DB->get_field('user_info_field', 'name', array('id' => $p['field'])); 163 } else { 164 $str = get_user_field_name($p['field']); 165 } 166 if (!$str) { 167 $output[] = $OUTPUT->error_text(get_string('error:nosuchfield', 'badges')); 168 } else { 169 $output[] = $str; 170 } 171 } 172 173 if ($short) { 174 return implode(', ', $output); 175 } else { 176 return html_writer::alist($output, array(), 'ul'); 177 } 178 } 179 180 /** 181 * Review this criteria and decide if it has been completed 182 * 183 * @param int $userid User whose criteria completion needs to be reviewed. 184 * @param bool $filtered An additional parameter indicating that user list 185 * has been reduced and some expensive checks can be skipped. 186 * 187 * @return bool Whether criteria is complete 188 */ 189 public function review($userid, $filtered = false) { 190 global $DB; 191 192 // Users were already filtered by criteria completion, no checks required. 193 if ($filtered) { 194 return true; 195 } 196 197 $join = ''; 198 $whereparts = array(); 199 $sqlparams = array(); 200 $rule = ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) ? ' OR ' : ' AND '; 201 202 foreach ($this->params as $param) { 203 if (is_numeric($param['field'])) { 204 // This is a custom field. 205 $idx = count($whereparts) + 1; 206 $join .= " LEFT JOIN {user_info_data} uid{$idx} ON uid{$idx}.userid = u.id AND uid{$idx}.fieldid = :fieldid{$idx} "; 207 $sqlparams["fieldid{$idx}"] = $param['field']; 208 $whereparts[] = "uid{$idx}.id IS NOT NULL"; 209 } else if (in_array($param['field'], $this->allowed_default_fields)) { 210 // This is a valid field from {user} table. 211 if ($param['field'] == 'picture') { 212 // The picture field is numeric and requires special handling. 213 $whereparts[] = "u.{$param['field']} != 0"; 214 } else { 215 $whereparts[] = $DB->sql_isnotempty('u', "u.{$param['field']}", false, true); 216 } 217 } 218 } 219 220 $sqlparams['userid'] = $userid; 221 222 if ($whereparts) { 223 $where = " AND (" . implode($rule, $whereparts) . ")"; 224 } else { 225 $where = ''; 226 } 227 $sql = "SELECT 1 FROM {user} u " . $join . " WHERE u.id = :userid $where"; 228 $overall = $DB->record_exists_sql($sql, $sqlparams); 229 230 return $overall; 231 } 232 233 /** 234 * Returns array with sql code and parameters returning all ids 235 * of users who meet this particular criterion. 236 * 237 * @return array list($join, $where, $params) 238 */ 239 public function get_completed_criteria_sql() { 240 global $DB; 241 242 $join = ''; 243 $whereparts = array(); 244 $params = array(); 245 $rule = ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) ? ' OR ' : ' AND '; 246 247 foreach ($this->params as $param) { 248 if (is_numeric($param['field'])) { 249 // This is a custom field. 250 $idx = count($whereparts); 251 $join .= " LEFT JOIN {user_info_data} uid{$idx} ON uid{$idx}.userid = u.id AND uid{$idx}.fieldid = :fieldid{$idx} "; 252 $params["fieldid{$idx}"] = $param['field']; 253 $whereparts[] = "uid{$idx}.id IS NOT NULL"; 254 } else if (in_array($param['field'], $this->allowed_default_fields)) { 255 // This is a valid field from {user} table. 256 if ($param['field'] == 'picture') { 257 // The picture field is numeric and requires special handling. 258 $whereparts[] = "u.{$param['field']} != 0"; 259 } else { 260 $whereparts[] = $DB->sql_isnotempty('u', "u.{$param['field']}", false, true); 261 } 262 } 263 } 264 265 if ($whereparts) { 266 $where = " AND (" . implode($rule, $whereparts) . ")"; 267 } else { 268 $where = ''; 269 } 270 return array($join, $where, $params); 271 } 272 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body