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