Commit | Line | Data |
---|---|---|
27806552 YB |
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 | * Renderer for use with the badges output | |
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 | require_once($CFG->libdir . '/badgeslib.php'); | |
28 | require_once($CFG->libdir . '/tablelib.php'); | |
27806552 YB |
29 | |
30 | /** | |
31 | * Standard HTML output renderer for badges | |
32 | */ | |
33 | class core_badges_renderer extends plugin_renderer_base { | |
34 | ||
35 | // Outputs badges list. | |
36 | public function print_badges_list($badges, $userid, $profile = false, $external = false) { | |
37 | global $USER, $CFG; | |
38 | foreach ($badges as $badge) { | |
39 | if (!$external) { | |
40 | $context = ($badge->type == BADGE_TYPE_SITE) ? context_system::instance() : context_course::instance($badge->courseid); | |
41 | $bname = $badge->name; | |
42 | $imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false); | |
43 | } else { | |
ea76b652 | 44 | $bname = s($badge->assertion->badge->name); |
27806552 YB |
45 | $imageurl = $badge->imageUrl; |
46 | } | |
47 | ||
48 | $name = html_writer::tag('span', $bname, array('class' => 'badge-name')); | |
49 | ||
50 | $image = html_writer::empty_tag('img', array('src' => $imageurl, 'class' => 'badge-image')); | |
51 | if (!empty($badge->dateexpire) && $badge->dateexpire < time()) { | |
52 | $image .= $this->output->pix_icon('i/expired', | |
53 | get_string('expireddate', 'badges', userdate($badge->dateexpire)), | |
54 | 'moodle', | |
55 | array('class' => 'expireimage')); | |
56 | $name .= '(' . get_string('expired', 'badges') . ')'; | |
57 | } | |
58 | ||
59 | $download = $status = $push = ''; | |
60 | if (($userid == $USER->id) && !$profile) { | |
61 | $url = new moodle_url('mybadges.php', array('download' => $badge->id, 'hash' => $badge->uniquehash, 'sesskey' => sesskey())); | |
e2805314 YB |
62 | $notexpiredbadge = (empty($badge->dateexpire) || $badge->dateexpire > time()); |
63 | $backpackexists = badges_user_has_backpack($USER->id); | |
64 | if (!empty($CFG->badges_allowexternalbackpack) && $notexpiredbadge && $backpackexists) { | |
27806552 YB |
65 | $assertion = new moodle_url('/badges/assertion.php', array('b' => $badge->uniquehash)); |
66 | $action = new component_action('click', 'addtobackpack', array('assertion' => $assertion->out(false))); | |
67 | $push = $this->output->action_icon(new moodle_url('#'), new pix_icon('t/backpack', get_string('addtobackpack', 'badges')), $action); | |
68 | } | |
69 | ||
70 | $download = $this->output->action_icon($url, new pix_icon('t/download', get_string('download'))); | |
71 | if ($badge->visible) { | |
72 | $url = new moodle_url('mybadges.php', array('hide' => $badge->issuedid, 'sesskey' => sesskey())); | |
73 | $status = $this->output->action_icon($url, new pix_icon('t/hide', get_string('makeprivate', 'badges'))); | |
74 | } else { | |
75 | $url = new moodle_url('mybadges.php', array('show' => $badge->issuedid, 'sesskey' => sesskey())); | |
76 | $status = $this->output->action_icon($url, new pix_icon('t/show', get_string('makepublic', 'badges'))); | |
77 | } | |
78 | } | |
79 | ||
80 | if (!$profile) { | |
81 | $url = new moodle_url('badge.php', array('hash' => $badge->uniquehash)); | |
82 | } else { | |
83 | if (!$external) { | |
2d3c0fae | 84 | $url = new moodle_url('/badges/badge.php', array('hash' => $badge->uniquehash)); |
27806552 | 85 | } else { |
2d3c0fae YB |
86 | $hash = hash('md5', $badge->hostedUrl); |
87 | $url = new moodle_url('/badges/external.php', array('hash' => $hash, 'user' => $userid)); | |
27806552 YB |
88 | } |
89 | } | |
90 | $actions = html_writer::tag('div', $push . $download . $status, array('class' => 'badge-actions')); | |
91 | $items[] = html_writer::link($url, $image . $actions . $name, array('title' => $bname)); | |
92 | } | |
93 | ||
94 | return html_writer::alist($items, array('class' => 'badges')); | |
95 | } | |
96 | ||
97 | // Recipients selection form. | |
98 | public function recipients_selection_form(user_selector_base $existinguc, user_selector_base $potentialuc) { | |
99 | $output = ''; | |
100 | $formattributes = array(); | |
101 | $formattributes['id'] = 'recipientform'; | |
04da1a5a | 102 | $formattributes['action'] = $this->page->url; |
27806552 YB |
103 | $formattributes['method'] = 'post'; |
104 | $output .= html_writer::start_tag('form', $formattributes); | |
105 | $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())); | |
106 | ||
107 | $existingcell = new html_table_cell(); | |
108 | $existingcell->text = $existinguc->display(true); | |
109 | $existingcell->attributes['class'] = 'existing'; | |
110 | $actioncell = new html_table_cell(); | |
111 | $actioncell->text = html_writer::start_tag('div', array()); | |
112 | $actioncell->text .= html_writer::empty_tag('input', array( | |
113 | 'type' => 'submit', | |
114 | 'name' => 'award', | |
115 | 'value' => $this->output->larrow() . ' ' . get_string('award', 'badges'), | |
116 | 'class' => 'actionbutton') | |
117 | ); | |
118 | $actioncell->text .= html_writer::end_tag('div', array()); | |
119 | $actioncell->attributes['class'] = 'actions'; | |
120 | $potentialcell = new html_table_cell(); | |
121 | $potentialcell->text = $potentialuc->display(true); | |
122 | $potentialcell->attributes['class'] = 'potential'; | |
123 | ||
124 | $table = new html_table(); | |
125 | $table->attributes['class'] = 'recipienttable boxaligncenter'; | |
126 | $table->data = array(new html_table_row(array($existingcell, $actioncell, $potentialcell))); | |
127 | $output .= html_writer::table($table); | |
128 | ||
129 | $output .= html_writer::end_tag('form'); | |
130 | return $output; | |
131 | } | |
132 | ||
133 | // Prints a badge overview infomation. | |
134 | public function print_badge_overview($badge, $context) { | |
135 | $display = ""; | |
136 | ||
137 | // Badge details. | |
27806552 | 138 | |
cd243d94 Y |
139 | $display .= $this->heading(get_string('badgedetails', 'badges'), 3); |
140 | $dl = array(); | |
141 | $dl[get_string('name')] = $badge->name; | |
142 | $dl[get_string('description', 'badges')] = $badge->description; | |
64d00f4c | 143 | $dl[get_string('createdon', 'search')] = userdate($badge->timecreated); |
cd243d94 Y |
144 | $dl[get_string('badgeimage', 'badges')] = print_badge_image($badge, $context, 'large'); |
145 | $display .= $this->definition_list($dl); | |
27806552 | 146 | |
cd243d94 Y |
147 | // Issuer details. |
148 | $display .= $this->heading(get_string('issuerdetails', 'badges'), 3); | |
149 | $dl = array(); | |
150 | $dl[get_string('issuername', 'badges')] = $badge->issuername; | |
151 | $dl[get_string('contact', 'badges')] = html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact)); | |
152 | $display .= $this->definition_list($dl); | |
27806552 YB |
153 | |
154 | // Issuance details if any. | |
cd243d94 | 155 | $display .= $this->heading(get_string('issuancedetails', 'badges'), 3); |
27806552 YB |
156 | if ($badge->can_expire()) { |
157 | if ($badge->expiredate) { | |
158 | $display .= get_string('expiredate', 'badges', userdate($badge->expiredate)); | |
159 | } else if ($badge->expireperiod) { | |
160 | if ($badge->expireperiod < 60) { | |
161 | $display .= get_string('expireperiods', 'badges', round($badge->expireperiod, 2)); | |
162 | } else if ($badge->expireperiod < 60 * 60) { | |
163 | $display .= get_string('expireperiodm', 'badges', round($badge->expireperiod / 60, 2)); | |
164 | } else if ($badge->expireperiod < 60 * 60 * 24) { | |
165 | $display .= get_string('expireperiodh', 'badges', round($badge->expireperiod / 60 / 60, 2)); | |
166 | } else { | |
167 | $display .= get_string('expireperiod', 'badges', round($badge->expireperiod / 60 / 60 / 24, 2)); | |
168 | } | |
169 | } | |
170 | } else { | |
171 | $display .= get_string('noexpiry', 'badges'); | |
172 | } | |
27806552 YB |
173 | |
174 | // Criteria details if any. | |
cd243d94 | 175 | $display .= $this->heading(get_string('bcriteria', 'badges'), 3); |
27806552 YB |
176 | if ($badge->has_criteria()) { |
177 | $display .= self::print_badge_criteria($badge); | |
178 | } else { | |
179 | $display .= get_string('nocriteria', 'badges'); | |
180 | if (has_capability('moodle/badges:configurecriteria', $context)) { | |
181 | $display .= $this->output->single_button( | |
182 | new moodle_url('/badges/criteria.php', array('id' => $badge->id)), | |
183 | get_string('addcriteria', 'badges'), 'POST', array('class' => 'activatebadge')); | |
184 | } | |
185 | } | |
27806552 YB |
186 | |
187 | // Awards details if any. | |
188 | if (has_capability('moodle/badges:viewawarded', $context)) { | |
cd243d94 | 189 | $display .= $this->heading(get_string('awards', 'badges'), 3); |
27806552 YB |
190 | if ($badge->has_awards()) { |
191 | $url = new moodle_url('/badges/recipients.php', array('id' => $badge->id)); | |
192 | $a = new stdClass(); | |
193 | $a->link = $url->out(); | |
194 | $a->count = count($badge->get_awards()); | |
195 | $display .= get_string('numawards', 'badges', $a); | |
196 | } else { | |
197 | $display .= get_string('noawards', 'badges'); | |
198 | } | |
199 | ||
200 | if (has_capability('moodle/badges:awardbadge', $context) && | |
201 | $badge->has_manual_award_criteria() && | |
202 | $badge->is_active()) { | |
203 | $display .= $this->output->single_button( | |
204 | new moodle_url('/badges/award.php', array('id' => $badge->id)), | |
205 | get_string('award', 'badges'), 'POST', array('class' => 'activatebadge')); | |
206 | } | |
27806552 YB |
207 | } |
208 | ||
cd243d94 | 209 | return html_writer::div($display, null, array('id' => 'badge-overview')); |
27806552 YB |
210 | } |
211 | ||
212 | // Prints action icons for the badge. | |
213 | public function print_badge_table_actions($badge, $context) { | |
214 | $actions = ""; | |
215 | ||
4d7d17dd | 216 | if (has_capability('moodle/badges:configuredetails', $context) && $badge->has_criteria()) { |
27806552 YB |
217 | // Activate/deactivate badge. |
218 | if ($badge->status == BADGE_STATUS_INACTIVE || $badge->status == BADGE_STATUS_INACTIVE_LOCKED) { | |
4d7d17dd YB |
219 | // "Activate" will go to another page and ask for confirmation. |
220 | $url = new moodle_url('/badges/action.php'); | |
221 | $url->param('id', $badge->id); | |
222 | $url->param('activate', true); | |
c5177654 | 223 | $url->param('sesskey', sesskey()); |
4d7d17dd YB |
224 | $return = new moodle_url(qualified_me()); |
225 | $url->param('return', $return->out_as_local_url(false)); | |
27806552 YB |
226 | $actions .= $this->output->action_icon($url, new pix_icon('t/show', get_string('activate', 'badges'))) . " "; |
227 | } else { | |
228 | $url = new moodle_url(qualified_me()); | |
229 | $url->param('lock', $badge->id); | |
230 | $url->param('sesskey', sesskey()); | |
231 | $actions .= $this->output->action_icon($url, new pix_icon('t/hide', get_string('deactivate', 'badges'))) . " "; | |
232 | } | |
233 | } | |
234 | ||
235 | // Award badge manually. | |
236 | if ($badge->has_manual_award_criteria() && | |
237 | has_capability('moodle/badges:awardbadge', $context) && | |
238 | $badge->is_active()) { | |
239 | $url = new moodle_url('/badges/award.php', array('id' => $badge->id)); | |
240 | $actions .= $this->output->action_icon($url, new pix_icon('t/award', get_string('award', 'badges'))) . " "; | |
241 | } | |
242 | ||
243 | // Edit badge. | |
244 | if (has_capability('moodle/badges:configuredetails', $context)) { | |
245 | $url = new moodle_url('/badges/edit.php', array('id' => $badge->id, 'action' => 'details')); | |
246 | $actions .= $this->output->action_icon($url, new pix_icon('t/edit', get_string('edit'))) . " "; | |
247 | } | |
248 | ||
249 | // Duplicate badge. | |
250 | if (has_capability('moodle/badges:createbadge', $context)) { | |
251 | $url = new moodle_url('/badges/action.php', array('copy' => '1', 'id' => $badge->id, 'sesskey' => sesskey())); | |
252 | $actions .= $this->output->action_icon($url, new pix_icon('t/copy', get_string('copy'))) . " "; | |
253 | } | |
254 | ||
255 | // Delete badge. | |
256 | if (has_capability('moodle/badges:deletebadge', $context)) { | |
257 | $url = new moodle_url(qualified_me()); | |
258 | $url->param('delete', $badge->id); | |
259 | $actions .= $this->output->action_icon($url, new pix_icon('t/delete', get_string('delete'))) . " "; | |
260 | } | |
261 | ||
262 | return $actions; | |
263 | } | |
264 | ||
265 | // Outputs issued badge with actions available. | |
266 | protected function render_issued_badge(issued_badge $ibadge) { | |
762b2a6b | 267 | global $USER, $CFG, $DB, $SITE; |
27806552 | 268 | $issued = $ibadge->issued; |
737a352f | 269 | $userinfo = $ibadge->recipient; |
853e506a | 270 | $badgeclass = $ibadge->badgeclass; |
27806552 | 271 | $badge = new badge($ibadge->badgeid); |
853e506a | 272 | $now = time(); |
cd243d94 | 273 | $expiration = isset($issued['expires']) ? $issued['expires'] : $now + 86400; |
27806552 | 274 | |
cd243d94 Y |
275 | $output = ''; |
276 | $output .= html_writer::start_tag('div', array('id' => 'badge')); | |
277 | $output .= html_writer::start_tag('div', array('id' => 'badge-image')); | |
278 | $output .= html_writer::empty_tag('img', array('src' => $badgeclass['image'], 'alt' => $badge->name)); | |
279 | if ($expiration < $now) { | |
280 | $output .= $this->output->pix_icon('i/expired', | |
281 | get_string('expireddate', 'badges', userdate($issued['expires'])), | |
282 | 'moodle', | |
283 | array('class' => 'expireimage')); | |
284 | } | |
27806552 | 285 | |
737a352f | 286 | if ($USER->id == $userinfo->id && !empty($CFG->enablebadges)) { |
cd243d94 | 287 | $output .= $this->output->single_button( |
853e506a | 288 | new moodle_url('/badges/badge.php', array('hash' => $issued['uid'], 'bake' => true)), |
e2805314 | 289 | get_string('download'), |
cd243d94 | 290 | 'POST'); |
853e506a Y |
291 | if (!empty($CFG->badges_allowexternalbackpack) && ($expiration > $now) && badges_user_has_backpack($USER->id)) { |
292 | $assertion = new moodle_url('/badges/assertion.php', array('b' => $issued['uid'])); | |
2c910861 | 293 | $action = new component_action('click', 'addtobackpack', array('assertion' => $assertion->out(false))); |
e2805314 | 294 | $attributes = array( |
2c910861 YB |
295 | 'type' => 'button', |
296 | 'id' => 'addbutton', | |
297 | 'value' => get_string('addtobackpack', 'badges')); | |
e2805314 | 298 | $tobackpack = html_writer::tag('input', '', $attributes); |
2c910861 | 299 | $this->output->add_action_handler($action, 'addbutton'); |
cd243d94 | 300 | $output .= $tobackpack; |
27806552 | 301 | } |
e2805314 | 302 | } |
cd243d94 | 303 | $output .= html_writer::end_tag('div'); |
737a352f | 304 | |
cd243d94 | 305 | $output .= html_writer::start_tag('div', array('id' => 'badge-details')); |
737a352f | 306 | // Recipient information. |
cd243d94 Y |
307 | $output .= $this->output->heading(get_string('recipientdetails', 'badges'), 3); |
308 | $dl = array(); | |
762b2a6b YB |
309 | if ($userinfo->deleted) { |
310 | $strdata = new stdClass(); | |
311 | $strdata->user = fullname($userinfo); | |
312 | $strdata->site = format_string($SITE->fullname, true, array('context' => context_system::instance())); | |
cd243d94 Y |
313 | |
314 | $dl[get_string('name')] = get_string('error:userdeleted', 'badges', $strdata); | |
737a352f | 315 | } else { |
cd243d94 | 316 | $dl[get_string('name')] = fullname($userinfo); |
737a352f | 317 | } |
cd243d94 | 318 | $output .= $this->definition_list($dl); |
737a352f | 319 | |
cd243d94 Y |
320 | $output .= $this->output->heading(get_string('issuerdetails', 'badges'), 3); |
321 | $dl = array(); | |
322 | $dl[get_string('issuername', 'badges')] = $badge->issuername; | |
e2805314 | 323 | if (isset($badge->issuercontact) && !empty($badge->issuercontact)) { |
cd243d94 | 324 | $dl[get_string('contact', 'badges')] = obfuscate_mailto($badge->issuercontact); |
e2805314 | 325 | } |
cd243d94 Y |
326 | $output .= $this->definition_list($dl); |
327 | ||
328 | $output .= $this->output->heading(get_string('badgedetails', 'badges'), 3); | |
329 | $dl = array(); | |
330 | $dl[get_string('name')] = $badge->name; | |
331 | $dl[get_string('description', 'badges')] = $badge->description; | |
27806552 | 332 | |
e2805314 YB |
333 | if ($badge->type == BADGE_TYPE_COURSE && isset($badge->courseid)) { |
334 | $coursename = $DB->get_field('course', 'fullname', array('id' => $badge->courseid)); | |
cd243d94 | 335 | $dl[get_string('course')] = $coursename; |
e2805314 | 336 | } |
cd243d94 Y |
337 | $dl[get_string('bcriteria', 'badges')] = self::print_badge_criteria($badge); |
338 | $output .= $this->definition_list($dl); | |
27806552 | 339 | |
cd243d94 Y |
340 | $output .= $this->output->heading(get_string('issuancedetails', 'badges'), 3); |
341 | $dl = array(); | |
342 | $dl[get_string('dateawarded', 'badges')] = userdate($issued['issuedOn']); | |
e2805314 | 343 | if (isset($issued['expires'])) { |
853e506a | 344 | if ($issued['expires'] < $now) { |
cd243d94 | 345 | $dl[get_string('expirydate', 'badges')] = userdate($issued['expires']) . get_string('warnexpired', 'badges'); |
e2805314 | 346 | |
e2805314 | 347 | } else { |
cd243d94 | 348 | $dl[get_string('expirydate', 'badges')] = userdate($issued['expires']); |
27806552 | 349 | } |
e2805314 | 350 | } |
27806552 | 351 | |
e2805314 YB |
352 | // Print evidence. |
353 | $agg = $badge->get_aggregation_methods(); | |
737a352f | 354 | $evidence = $badge->get_criteria_completions($userinfo->id); |
e2805314 YB |
355 | $eids = array_map(create_function('$o', 'return $o->critid;'), $evidence); |
356 | unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]); | |
357 | ||
358 | $items = array(); | |
359 | foreach ($badge->criteria as $type => $c) { | |
360 | if (in_array($c->id, $eids)) { | |
361 | if (count($c->params) == 1) { | |
362 | $items[] = get_string('criteria_descr_single_' . $type , 'badges') . $c->get_details(); | |
363 | } else { | |
364 | $items[] = get_string('criteria_descr_' . $type , 'badges', | |
ae17e383 | 365 | core_text::strtoupper($agg[$badge->get_aggregation_method($type)])) . $c->get_details(); |
27806552 YB |
366 | } |
367 | } | |
e2805314 | 368 | } |
27806552 | 369 | |
cd243d94 Y |
370 | $dl[get_string('evidence', 'badges')] = get_string('completioninfo', 'badges') . html_writer::alist($items, array(), 'ul'); |
371 | $output .= $this->definition_list($dl); | |
372 | $output .= html_writer::end_tag('div'); | |
27806552 | 373 | |
cd243d94 | 374 | return $output; |
27806552 YB |
375 | } |
376 | ||
377 | // Outputs external badge. | |
378 | protected function render_external_badge(external_badge $ibadge) { | |
379 | $issued = $ibadge->issued; | |
380 | $assertion = $issued->assertion; | |
381 | $issuer = $assertion->badge->issuer; | |
737a352f | 382 | $userinfo = $ibadge->recipient; |
27806552 | 383 | $table = new html_table(); |
ea76b652 | 384 | $today = strtotime(date('Y-m-d')); |
27806552 | 385 | |
cd243d94 Y |
386 | $output = ''; |
387 | $output .= html_writer::start_tag('div', array('id' => 'badge')); | |
388 | $output .= html_writer::start_tag('div', array('id' => 'badge-image')); | |
ea76b652 YB |
389 | $output .= html_writer::empty_tag('img', array('src' => $issued->imageUrl)); |
390 | if (isset($assertion->expires)) { | |
391 | $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires); | |
392 | if ($expiration < $today) { | |
393 | $output .= $this->output->pix_icon('i/expired', | |
394 | get_string('expireddate', 'badges', userdate($expiration)), | |
395 | 'moodle', | |
396 | array('class' => 'expireimage')); | |
397 | } | |
cd243d94 Y |
398 | } |
399 | $output .= html_writer::end_tag('div'); | |
27806552 | 400 | |
cd243d94 | 401 | $output .= html_writer::start_tag('div', array('id' => 'badge-details')); |
737a352f YB |
402 | |
403 | // Recipient information. | |
cd243d94 Y |
404 | $output .= $this->output->heading(get_string('recipientdetails', 'badges'), 3); |
405 | $dl = array(); | |
737a352f YB |
406 | // Technically, we should alway have a user at this point, but added an extra check just in case. |
407 | if ($userinfo) { | |
737a352f YB |
408 | if (!$ibadge->valid) { |
409 | $notify = $this->output->notification(get_string('recipientvalidationproblem', 'badges'), 'notifynotice'); | |
cd243d94 Y |
410 | $dl[get_string('name')] = fullname($userinfo) . $notify; |
411 | } else { | |
412 | $dl[get_string('name')] = fullname($userinfo); | |
737a352f YB |
413 | } |
414 | } else { | |
415 | $notify = $this->output->notification(get_string('recipientidentificationproblem', 'badges'), 'notifynotice'); | |
cd243d94 | 416 | $dl[get_string('name')] = $notify; |
737a352f | 417 | } |
cd243d94 Y |
418 | $output .= $this->definition_list($dl); |
419 | ||
420 | $output .= $this->output->heading(get_string('issuerdetails', 'badges'), 3); | |
421 | $dl = array(); | |
ea76b652 | 422 | $dl[get_string('issuername', 'badges')] = s($issuer->name); |
cd243d94 | 423 | $dl[get_string('issuerurl', 'badges')] = html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)); |
737a352f | 424 | |
27806552 | 425 | if (isset($issuer->contact)) { |
cd243d94 Y |
426 | $dl[get_string('contact', 'badges')] = obfuscate_mailto($issuer->contact); |
427 | } | |
428 | $output .= $this->definition_list($dl); | |
429 | ||
430 | $output .= $this->output->heading(get_string('badgedetails', 'badges'), 3); | |
431 | $dl = array(); | |
ea76b652 YB |
432 | $dl[get_string('name')] = s($assertion->badge->name); |
433 | $dl[get_string('description', 'badges')] = s($assertion->badge->description); | |
434 | $dl[get_string('bcriteria', 'badges')] = html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria)); | |
cd243d94 Y |
435 | $output .= $this->definition_list($dl); |
436 | ||
437 | $output .= $this->output->heading(get_string('issuancedetails', 'badges'), 3); | |
438 | $dl = array(); | |
27806552 | 439 | if (isset($assertion->issued_on)) { |
ea76b652 YB |
440 | $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on); |
441 | $dl[get_string('dateawarded', 'badges')] = userdate($issuedate); | |
27806552 | 442 | } |
ea76b652 | 443 | if (isset($assertion->expires)) { |
27806552 | 444 | if ($expiration < $today) { |
ea76b652 | 445 | $dl[get_string('expirydate', 'badges')] = userdate($expiration) . get_string('warnexpired', 'badges'); |
27806552 | 446 | } else { |
ea76b652 | 447 | $dl[get_string('expirydate', 'badges')] = userdate($expiration); |
27806552 YB |
448 | } |
449 | } | |
450 | if (isset($assertion->evidence)) { | |
ea76b652 | 451 | $dl[get_string('evidence', 'badges')] = html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence)); |
27806552 | 452 | } |
cd243d94 Y |
453 | $output .= $this->definition_list($dl); |
454 | $output .= html_writer::end_tag('div'); | |
27806552 | 455 | |
cd243d94 | 456 | return $output; |
27806552 YB |
457 | } |
458 | ||
cd243d94 | 459 | // Displays the user badges. |
27806552 YB |
460 | protected function render_badge_user_collection(badge_user_collection $badges) { |
461 | global $CFG, $USER, $SITE; | |
e2805314 YB |
462 | $backpack = $badges->backpack; |
463 | $mybackpack = new moodle_url('/badges/mybackpack.php'); | |
464 | ||
27806552 YB |
465 | $paging = new paging_bar($badges->totalcount, $badges->page, $badges->perpage, $this->page->url, 'page'); |
466 | $htmlpagingbar = $this->render($paging); | |
467 | ||
e2805314 YB |
468 | // Set backpack connection string. |
469 | $backpackconnect = ''; | |
470 | if (!empty($CFG->badges_allowexternalbackpack) && is_null($backpack)) { | |
471 | $backpackconnect = $this->output->box(get_string('localconnectto', 'badges', $mybackpack->out()), 'noticebox'); | |
472 | } | |
27806552 YB |
473 | // Search box. |
474 | $searchform = $this->output->box($this->helper_search_form($badges->search), 'boxwidthwide boxaligncenter'); | |
475 | ||
476 | // Download all button. | |
477 | $downloadall = $this->output->single_button( | |
478 | new moodle_url('/badges/mybadges.php', array('downloadall' => true, 'sesskey' => sesskey())), | |
479 | get_string('downloadall'), 'POST', array('class' => 'activatebadge')); | |
480 | ||
481 | // Local badges. | |
2c910861 | 482 | $localhtml = html_writer::start_tag('fieldset', array('id' => 'issued-badge-table', 'class' => 'generalbox')); |
5dcda2f8 YB |
483 | $heading = get_string('localbadges', 'badges', format_string($SITE->fullname, true, array('context' => context_system::instance()))); |
484 | $localhtml .= html_writer::tag('legend', $this->output->heading_with_help($heading, 'localbadgesh', 'badges')); | |
27806552 | 485 | if ($badges->badges) { |
cd243d94 Y |
486 | $downloadbutton = $this->output->heading(get_string('badgesearned', 'badges', $badges->totalcount), 4, 'activatebadge'); |
487 | $downloadbutton .= $downloadall; | |
27806552 YB |
488 | |
489 | $htmllist = $this->print_badges_list($badges->badges, $USER->id); | |
e2805314 | 490 | $localhtml .= $backpackconnect . $downloadbutton . $searchform . $htmlpagingbar . $htmllist . $htmlpagingbar; |
27806552 YB |
491 | } else { |
492 | $localhtml .= $searchform . $this->output->notification(get_string('nobadges', 'badges')); | |
493 | } | |
494 | $localhtml .= html_writer::end_tag('fieldset'); | |
495 | ||
496 | // External badges. | |
27806552 | 497 | $externalhtml = ""; |
60d72efb | 498 | if (!empty($CFG->badges_allowexternalbackpack)) { |
27806552 YB |
499 | $externalhtml .= html_writer::start_tag('fieldset', array('class' => 'generalbox')); |
500 | $externalhtml .= html_writer::tag('legend', $this->output->heading_with_help(get_string('externalbadges', 'badges'), 'externalbadges', 'badges')); | |
501 | if (!is_null($backpack)) { | |
e2805314 YB |
502 | if ($backpack->totalcollections == 0) { |
503 | $externalhtml .= get_string('nobackpackcollections', 'badges', $backpack); | |
27806552 | 504 | } else { |
e2805314 YB |
505 | if ($backpack->totalbadges == 0) { |
506 | $externalhtml .= get_string('nobackpackbadges', 'badges', $backpack); | |
507 | } else { | |
508 | $externalhtml .= get_string('backpackbadges', 'badges', $backpack); | |
509 | $externalhtml .= '<br/><br/>' . $this->print_badges_list($backpack->badges, $USER->id, true, true); | |
510 | } | |
27806552 | 511 | } |
27806552 | 512 | } else { |
e2805314 | 513 | $externalhtml .= get_string('externalconnectto', 'badges', $mybackpack->out()); |
27806552 | 514 | } |
27806552 | 515 | |
27806552 YB |
516 | $externalhtml .= html_writer::end_tag('fieldset'); |
517 | } | |
518 | ||
519 | return $localhtml . $externalhtml; | |
520 | } | |
521 | ||
cd243d94 | 522 | // Displays the available badges. |
27806552 YB |
523 | protected function render_badge_collection(badge_collection $badges) { |
524 | $paging = new paging_bar($badges->totalcount, $badges->page, $badges->perpage, $this->page->url, 'page'); | |
525 | $htmlpagingbar = $this->render($paging); | |
526 | $table = new html_table(); | |
f8ba185a | 527 | $table->attributes['class'] = 'collection'; |
27806552 YB |
528 | |
529 | $sortbyname = $this->helper_sortable_heading(get_string('name'), | |
530 | 'name', $badges->sort, $badges->dir); | |
531 | $sortbyawarded = $this->helper_sortable_heading(get_string('awardedtoyou', 'badges'), | |
532 | 'dateissued', $badges->sort, $badges->dir); | |
533 | $table->head = array( | |
534 | get_string('badgeimage', 'badges'), | |
535 | $sortbyname, | |
536 | get_string('description', 'badges'), | |
537 | get_string('bcriteria', 'badges'), | |
538 | $sortbyawarded | |
539 | ); | |
540 | $table->colclasses = array('badgeimage', 'name', 'description', 'criteria', 'awards'); | |
541 | ||
542 | foreach ($badges->badges as $badge) { | |
543 | $badgeimage = print_badge_image($badge, $this->page->context, 'large'); | |
544 | $name = $badge->name; | |
545 | $description = $badge->description; | |
546 | $criteria = self::print_badge_criteria($badge); | |
547 | if ($badge->dateissued) { | |
a8dd22a7 | 548 | $icon = new pix_icon('i/valid', |
27806552 YB |
549 | get_string('dateearned', 'badges', |
550 | userdate($badge->dateissued, get_string('strftimedatefullshort', 'core_langconfig')))); | |
551 | $badgeurl = new moodle_url('/badges/badge.php', array('hash' => $badge->uniquehash)); | |
552 | $awarded = $this->output->action_icon($badgeurl, $icon, null, null, true); | |
553 | } else { | |
554 | $awarded = ""; | |
555 | } | |
556 | $row = array($badgeimage, $name, $description, $criteria, $awarded); | |
557 | $table->data[] = $row; | |
558 | } | |
559 | ||
560 | $htmltable = html_writer::table($table); | |
561 | ||
562 | return $htmlpagingbar . $htmltable . $htmlpagingbar; | |
563 | } | |
564 | ||
565 | // Outputs table of badges with actions available. | |
566 | protected function render_badge_management(badge_management $badges) { | |
567 | $paging = new paging_bar($badges->totalcount, $badges->page, $badges->perpage, $this->page->url, 'page'); | |
568 | ||
569 | // New badge button. | |
19a9f2ea YB |
570 | $htmlnew = ''; |
571 | if (has_capability('moodle/badges:createbadge', $this->page->context)) { | |
572 | $n['type'] = $this->page->url->get_param('type'); | |
573 | $n['id'] = $this->page->url->get_param('id'); | |
574 | $htmlnew = $this->output->single_button(new moodle_url('newbadge.php', $n), get_string('newbadge', 'badges')); | |
575 | } | |
27806552 YB |
576 | |
577 | $htmlpagingbar = $this->render($paging); | |
578 | $table = new html_table(); | |
579 | $table->attributes['class'] = 'collection'; | |
580 | ||
581 | $sortbyname = $this->helper_sortable_heading(get_string('name'), | |
582 | 'name', $badges->sort, $badges->dir); | |
583 | $sortbystatus = $this->helper_sortable_heading(get_string('status', 'badges'), | |
584 | 'status', $badges->sort, $badges->dir); | |
585 | $table->head = array( | |
586 | $sortbyname, | |
587 | $sortbystatus, | |
588 | get_string('bcriteria', 'badges'), | |
589 | get_string('awards', 'badges'), | |
590 | get_string('actions') | |
591 | ); | |
592 | $table->colclasses = array('name', 'status', 'criteria', 'awards', 'actions'); | |
593 | ||
594 | foreach ($badges->badges as $b) { | |
595 | $style = !$b->is_active() ? array('class' => 'dimmed') : array(); | |
596 | $forlink = print_badge_image($b, $this->page->context) . ' ' . | |
597 | html_writer::start_tag('span') . $b->name . html_writer::end_tag('span'); | |
598 | $name = html_writer::link(new moodle_url('/badges/overview.php', array('id' => $b->id)), $forlink, $style); | |
599 | $status = $b->statstring; | |
600 | $criteria = self::print_badge_criteria($b, 'short'); | |
601 | ||
602 | if (has_capability('moodle/badges:viewawarded', $this->page->context)) { | |
603 | $awards = html_writer::link(new moodle_url('/badges/recipients.php', array('id' => $b->id)), $b->awards); | |
604 | } else { | |
605 | $awards = $b->awards; | |
606 | } | |
607 | ||
608 | $actions = self::print_badge_table_actions($b, $this->page->context); | |
609 | ||
610 | $row = array($name, $status, $criteria, $awards, $actions); | |
611 | $table->data[] = $row; | |
612 | } | |
613 | $htmltable = html_writer::table($table); | |
614 | ||
615 | return $htmlnew . $htmlpagingbar . $htmltable . $htmlpagingbar; | |
616 | } | |
617 | ||
618 | // Prints tabs for badge editing. | |
619 | public function print_badge_tabs($badgeid, $context, $current = 'overview') { | |
620 | global $DB; | |
621 | ||
a5f82c5b | 622 | $row = array(); |
27806552 YB |
623 | |
624 | $row[] = new tabobject('overview', | |
625 | new moodle_url('/badges/overview.php', array('id' => $badgeid)), | |
626 | get_string('boverview', 'badges') | |
627 | ); | |
628 | ||
629 | if (has_capability('moodle/badges:configuredetails', $context)) { | |
630 | $row[] = new tabobject('details', | |
631 | new moodle_url('/badges/edit.php', array('id' => $badgeid, 'action' => 'details')), | |
632 | get_string('bdetails', 'badges') | |
633 | ); | |
634 | } | |
635 | ||
636 | if (has_capability('moodle/badges:configurecriteria', $context)) { | |
637 | $row[] = new tabobject('criteria', | |
638 | new moodle_url('/badges/criteria.php', array('id' => $badgeid)), | |
639 | get_string('bcriteria', 'badges') | |
640 | ); | |
641 | } | |
642 | ||
643 | if (has_capability('moodle/badges:configuremessages', $context)) { | |
644 | $row[] = new tabobject('message', | |
645 | new moodle_url('/badges/edit.php', array('id' => $badgeid, 'action' => 'message')), | |
646 | get_string('bmessage', 'badges') | |
647 | ); | |
648 | } | |
649 | ||
650 | if (has_capability('moodle/badges:viewawarded', $context)) { | |
7f964cfd YB |
651 | $awarded = $DB->count_records_sql('SELECT COUNT(b.userid) |
652 | FROM {badge_issued} b INNER JOIN {user} u ON b.userid = u.id | |
653 | WHERE b.badgeid = :badgeid AND u.deleted = 0', array('badgeid' => $badgeid)); | |
27806552 YB |
654 | $row[] = new tabobject('awards', |
655 | new moodle_url('/badges/recipients.php', array('id' => $badgeid)), | |
656 | get_string('bawards', 'badges', $awarded) | |
657 | ); | |
658 | } | |
659 | ||
a5f82c5b | 660 | echo $this->tabtree($row, $current); |
27806552 YB |
661 | } |
662 | ||
36388ba8 AD |
663 | /** |
664 | * Prints badge status box. | |
665 | * @return Either the status box html as a string or null | |
666 | */ | |
27806552 | 667 | public function print_badge_status_box(badge $badge) { |
27806552 | 668 | if (has_capability('moodle/badges:configurecriteria', $badge->get_context())) { |
36388ba8 | 669 | |
27806552 YB |
670 | if (!$badge->has_criteria()) { |
671 | $criteriaurl = new moodle_url('/badges/criteria.php', array('id' => $badge->id)); | |
672 | $status = get_string('nocriteria', 'badges'); | |
673 | if ($this->page->url != $criteriaurl) { | |
674 | $action = $this->output->single_button( | |
675 | $criteriaurl, | |
676 | get_string('addcriteria', 'badges'), 'POST', array('class' => 'activatebadge')); | |
677 | } else { | |
678 | $action = ''; | |
679 | } | |
cd243d94 Y |
680 | |
681 | $message = $status . $action; | |
27806552 YB |
682 | } else { |
683 | $status = get_string('statusmessage_' . $badge->status, 'badges'); | |
684 | if ($badge->is_active()) { | |
685 | $action = $this->output->single_button(new moodle_url('/badges/action.php', | |
686 | array('id' => $badge->id, 'lock' => 1, 'sesskey' => sesskey(), | |
687 | 'return' => $this->page->url->out_as_local_url(false))), | |
688 | get_string('deactivate', 'badges'), 'POST', array('class' => 'activatebadge')); | |
689 | } else { | |
690 | $action = $this->output->single_button(new moodle_url('/badges/action.php', | |
691 | array('id' => $badge->id, 'activate' => 1, 'sesskey' => sesskey(), | |
692 | 'return' => $this->page->url->out_as_local_url(false))), | |
693 | get_string('activate', 'badges'), 'POST', array('class' => 'activatebadge')); | |
694 | } | |
cd243d94 Y |
695 | |
696 | $message = $status . $this->output->help_icon('status', 'badges') . $action; | |
697 | ||
27806552 | 698 | } |
27806552 | 699 | |
36388ba8 | 700 | $style = $badge->is_active() ? 'generalbox statusbox active' : 'generalbox statusbox inactive'; |
cd243d94 | 701 | return $this->output->box($message, $style); |
36388ba8 | 702 | } |
27806552 | 703 | |
36388ba8 | 704 | return null; |
27806552 YB |
705 | } |
706 | ||
3784d3be YB |
707 | /** |
708 | * Returns information about badge criteria in a list form. | |
709 | * | |
710 | * @param badge $badge Badge objects | |
711 | * @param string $short Indicates whether to print full info about this badge | |
712 | * @return string $output HTML string to output | |
713 | */ | |
27806552 YB |
714 | public function print_badge_criteria(badge $badge, $short = '') { |
715 | $output = ""; | |
716 | $agg = $badge->get_aggregation_methods(); | |
717 | if (empty($badge->criteria)) { | |
718 | return get_string('nocriteria', 'badges'); | |
3784d3be YB |
719 | } |
720 | ||
721 | $overalldescr = ''; | |
722 | if (!$short) { | |
723 | $overall = $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]; | |
724 | $overalldescr .= $this->output->box(clean_text($overall->description, FORMAT_HTML)); | |
725 | } | |
726 | if (count($badge->criteria) == 2) { | |
27806552 | 727 | if (!$short) { |
3784d3be | 728 | $output .= $overalldescr . get_string('criteria_descr', 'badges'); |
27806552 YB |
729 | } |
730 | } else { | |
3784d3be YB |
731 | $output .= $overalldescr . get_string('criteria_descr_' . $short . BADGE_CRITERIA_TYPE_OVERALL, 'badges', |
732 | core_text::strtoupper($agg[$badge->get_aggregation_method()])); | |
27806552 YB |
733 | } |
734 | $items = array(); | |
735 | unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]); | |
736 | foreach ($badge->criteria as $type => $c) { | |
3784d3be YB |
737 | $criteriadescr = ''; |
738 | if (!$short) { | |
739 | $criteriadescr = $this->output->box(clean_text($c->description, FORMAT_HTML)); | |
740 | } | |
27806552 | 741 | if (count($c->params) == 1) { |
3784d3be YB |
742 | $items[] = $criteriadescr . get_string('criteria_descr_single_' . $short . $type , 'badges') . |
743 | $c->get_details($short); | |
27806552 | 744 | } else { |
3784d3be | 745 | $items[] = $criteriadescr . get_string('criteria_descr_' . $short . $type , 'badges', |
ae17e383 | 746 | core_text::strtoupper($agg[$badge->get_aggregation_method($type)])) . $c->get_details($short); |
27806552 YB |
747 | } |
748 | } | |
749 | $output .= html_writer::alist($items, array(), 'ul'); | |
750 | return $output; | |
751 | } | |
752 | ||
753 | // Prints criteria actions for badge editing. | |
754 | public function print_criteria_actions(badge $badge) { | |
755 | $table = new html_table(); | |
756 | $table->attributes = array('class' => 'boxaligncenter', 'id' => 'badgeactions'); | |
757 | $table->colclasses = array('activatebadge'); | |
758 | ||
759 | $actions = array(); | |
760 | if (!$badge->is_active() && !$badge->is_locked()) { | |
761 | $accepted = $badge->get_accepted_criteria(); | |
762 | $potential = array_diff($accepted, array_keys($badge->criteria)); | |
763 | ||
764 | if (!empty($potential)) { | |
765 | foreach ($potential as $p) { | |
766 | if ($p != 0) { | |
767 | $select[$p] = get_string('criteria_' . $p, 'badges'); | |
768 | } | |
769 | } | |
770 | $actions[] = get_string('addbadgecriteria', 'badges'); | |
771 | $actions[] = $this->output->single_select(new moodle_url('/badges/criteria_settings.php', | |
772 | array('badgeid' => $badge->id, 'add' => true)), 'type', $select); | |
773 | } else { | |
774 | $actions[] = $this->output->box(get_string('nothingtoadd', 'badges'), 'clearfix'); | |
775 | } | |
776 | } | |
777 | ||
778 | $table->data[] = $actions; | |
779 | return html_writer::table($table); | |
780 | } | |
781 | ||
782 | // Renders a table with users who have earned the badge. | |
783 | // Based on stamps collection plugin. | |
784 | protected function render_badge_recipients(badge_recipients $recipients) { | |
785 | $paging = new paging_bar($recipients->totalcount, $recipients->page, $recipients->perpage, $this->page->url, 'page'); | |
786 | $htmlpagingbar = $this->render($paging); | |
787 | $table = new html_table(); | |
f8ba185a | 788 | $table->attributes['class'] = 'generaltable boxaligncenter boxwidthwide'; |
27806552 YB |
789 | |
790 | $sortbyfirstname = $this->helper_sortable_heading(get_string('firstname'), | |
791 | 'firstname', $recipients->sort, $recipients->dir); | |
792 | $sortbylastname = $this->helper_sortable_heading(get_string('lastname'), | |
793 | 'lastname', $recipients->sort, $recipients->dir); | |
794 | if ($this->helper_fullname_format() == 'lf') { | |
795 | $sortbyname = $sortbylastname . ' / ' . $sortbyfirstname; | |
796 | } else { | |
797 | $sortbyname = $sortbyfirstname . ' / ' . $sortbylastname; | |
798 | } | |
799 | ||
800 | $sortbydate = $this->helper_sortable_heading(get_string('dateawarded', 'badges'), | |
801 | 'dateissued', $recipients->sort, $recipients->dir); | |
802 | ||
803 | $table->head = array($sortbyname, $sortbydate, ''); | |
804 | ||
805 | foreach ($recipients->userids as $holder) { | |
806 | $fullname = fullname($holder); | |
807 | $fullname = html_writer::link( | |
808 | new moodle_url('/user/profile.php', array('id' => $holder->userid)), | |
809 | $fullname | |
810 | ); | |
811 | $awarded = userdate($holder->dateissued); | |
812 | $badgeurl = html_writer::link( | |
813 | new moodle_url('/badges/badge.php', array('hash' => $holder->uniquehash)), | |
814 | get_string('viewbadge', 'badges') | |
815 | ); | |
816 | ||
817 | $row = array($fullname, $awarded, $badgeurl); | |
818 | $table->data[] = $row; | |
819 | } | |
820 | ||
821 | $htmltable = html_writer::table($table); | |
822 | ||
823 | return $htmlpagingbar . $htmltable . $htmlpagingbar; | |
824 | } | |
825 | ||
826 | //////////////////////////////////////////////////////////////////////////// | |
827 | // Helper methods | |
828 | // Reused from stamps collection plugin | |
829 | //////////////////////////////////////////////////////////////////////////// | |
830 | ||
831 | /** | |
832 | * Renders a text with icons to sort by the given column | |
833 | * | |
834 | * This is intended for table headings. | |
835 | * | |
836 | * @param string $text The heading text | |
837 | * @param string $sortid The column id used for sorting | |
838 | * @param string $sortby Currently sorted by (column id) | |
839 | * @param string $sorthow Currently sorted how (ASC|DESC) | |
840 | * | |
841 | * @return string | |
842 | */ | |
843 | protected function helper_sortable_heading($text, $sortid = null, $sortby = null, $sorthow = null) { | |
844 | $out = html_writer::tag('span', $text, array('class' => 'text')); | |
845 | ||
846 | if (!is_null($sortid)) { | |
847 | if ($sortby !== $sortid || $sorthow !== 'ASC') { | |
848 | $url = new moodle_url($this->page->url); | |
849 | $url->params(array('sort' => $sortid, 'dir' => 'ASC')); | |
850 | $out .= $this->output->action_icon($url, | |
851 | new pix_icon('t/sort_asc', get_string('sortbyx', 'core', s($text)), null, array('class' => 'iconsort'))); | |
852 | } | |
853 | if ($sortby !== $sortid || $sorthow !== 'DESC') { | |
854 | $url = new moodle_url($this->page->url); | |
855 | $url->params(array('sort' => $sortid, 'dir' => 'DESC')); | |
856 | $out .= $this->output->action_icon($url, | |
857 | new pix_icon('t/sort_desc', get_string('sortbyxreverse', 'core', s($text)), null, array('class' => 'iconsort'))); | |
858 | } | |
859 | } | |
860 | return $out; | |
861 | } | |
862 | /** | |
863 | * Tries to guess the fullname format set at the site | |
864 | * | |
865 | * @return string fl|lf | |
866 | */ | |
867 | protected function helper_fullname_format() { | |
868 | $fake = new stdClass(); | |
869 | $fake->lastname = 'LLLL'; | |
870 | $fake->firstname = 'FFFF'; | |
871 | $fullname = get_string('fullnamedisplay', '', $fake); | |
872 | if (strpos($fullname, 'LLLL') < strpos($fullname, 'FFFF')) { | |
873 | return 'lf'; | |
874 | } else { | |
875 | return 'fl'; | |
876 | } | |
877 | } | |
878 | /** | |
879 | * Renders a search form | |
880 | * | |
881 | * @param string $search Search string | |
882 | * @return string HTML | |
883 | */ | |
884 | protected function helper_search_form($search) { | |
885 | global $CFG; | |
886 | require_once($CFG->libdir . '/formslib.php'); | |
887 | ||
888 | $mform = new MoodleQuickForm('searchform', 'POST', $this->page->url); | |
889 | ||
890 | $mform->addElement('hidden', 'sesskey', sesskey()); | |
891 | ||
892 | $el[] = $mform->createElement('text', 'search', get_string('search'), array('size' => 20)); | |
893 | $mform->setDefault('search', $search); | |
894 | $el[] = $mform->createElement('submit', 'submitsearch', get_string('search')); | |
895 | $el[] = $mform->createElement('submit', 'clearsearch', get_string('clear')); | |
896 | $mform->addGroup($el, 'searchgroup', get_string('searchname', 'badges'), ' ', false); | |
897 | ||
898 | ob_start(); | |
899 | $mform->display(); | |
900 | $out = ob_get_clean(); | |
901 | ||
902 | return $out; | |
903 | } | |
cd243d94 Y |
904 | |
905 | /** | |
906 | * Renders a definition list | |
907 | * | |
908 | * @param array $items the list of items to define | |
909 | * @param array | |
910 | */ | |
911 | protected function definition_list(array $items, array $attributes = array()) { | |
912 | $output = html_writer::start_tag('dl', $attributes); | |
913 | foreach ($items as $label => $value) { | |
914 | $output .= html_writer::tag('dt', $label); | |
915 | $output .= html_writer::tag('dd', $value); | |
916 | } | |
917 | $output .= html_writer::end_tag('dl'); | |
918 | return $output; | |
919 | } | |
27806552 YB |
920 | } |
921 | ||
922 | /** | |
923 | * An issued badges for badge.php page | |
924 | */ | |
925 | class issued_badge implements renderable { | |
926 | /** @var issued badge */ | |
927 | public $issued; | |
928 | ||
929 | /** @var badge recipient */ | |
737a352f | 930 | public $recipient; |
27806552 | 931 | |
853e506a Y |
932 | /** @var badge class */ |
933 | public $badgeclass; | |
934 | ||
27806552 YB |
935 | /** @var badge visibility to others */ |
936 | public $visible = 0; | |
937 | ||
938 | /** @var badge class */ | |
939 | public $badgeid = 0; | |
940 | ||
27806552 YB |
941 | /** |
942 | * Initializes the badge to display | |
943 | * | |
944 | * @param string $hash Issued badge hash | |
945 | */ | |
946 | public function __construct($hash) { | |
947 | global $DB; | |
853e506a Y |
948 | |
949 | $assertion = new core_badges_assertion($hash); | |
950 | $this->issued = $assertion->get_badge_assertion(); | |
951 | $this->badgeclass = $assertion->get_badge_class(); | |
27806552 YB |
952 | |
953 | $rec = $DB->get_record_sql('SELECT userid, visible, badgeid | |
954 | FROM {badge_issued} | |
955 | WHERE ' . $DB->sql_compare_text('uniquehash', 40) . ' = ' . $DB->sql_compare_text(':hash', 40), | |
956 | array('hash' => $hash), IGNORE_MISSING); | |
957 | if ($rec) { | |
737a352f | 958 | // Get a recipient from database. |
5241526d | 959 | $namefields = get_all_user_name_fields(true, 'u'); |
774ead81 YB |
960 | $user = $DB->get_record_sql("SELECT u.id, $namefields, u.deleted, u.email |
961 | FROM {user} u WHERE u.id = :userid", array('userid' => $rec->userid)); | |
737a352f | 962 | $this->recipient = $user; |
27806552 YB |
963 | $this->visible = $rec->visible; |
964 | $this->badgeid = $rec->badgeid; | |
965 | } | |
966 | } | |
967 | } | |
968 | ||
969 | /** | |
970 | * An external badges for external.php page | |
971 | */ | |
972 | class external_badge implements renderable { | |
973 | /** @var issued badge */ | |
974 | public $issued; | |
975 | ||
737a352f YB |
976 | /** @var User ID */ |
977 | public $recipient; | |
978 | ||
979 | /** @var validation of external badge */ | |
980 | public $valid = true; | |
981 | ||
27806552 YB |
982 | /** |
983 | * Initializes the badge to display | |
984 | * | |
2d3c0fae | 985 | * @param object $badge External badge information. |
737a352f | 986 | * @param int $recipient User id. |
27806552 | 987 | */ |
737a352f YB |
988 | public function __construct($badge, $recipient) { |
989 | global $DB; | |
990 | // At this point a user has connected a backpack. So, we are going to get | |
991 | // their backpack email rather than their account email. | |
cd243d94 Y |
992 | $namefields = get_all_user_name_fields(true, 'u'); |
993 | $user = $DB->get_record_sql("SELECT {$namefields}, b.email | |
737a352f | 994 | FROM {user} u INNER JOIN {badge_backpack} b ON u.id = b.userid |
cd243d94 | 995 | WHERE userid = :userid", array('userid' => $recipient), IGNORE_MISSING); |
737a352f | 996 | |
2d3c0fae | 997 | $this->issued = $badge; |
737a352f YB |
998 | $this->recipient = $user; |
999 | ||
1000 | // Check if recipient is valid. | |
1001 | // There is no way to be 100% sure that a badge belongs to a user. | |
1002 | // Backpack does not return any recipient information. | |
1003 | // All we can do is compare that backpack email hashed using salt | |
1004 | // provided in the assertion matches a badge recipient from the assertion. | |
1005 | if ($user) { | |
1006 | if (validate_email($badge->assertion->recipient) && $badge->assertion->recipient == $user->email) { | |
1007 | // If we have email, compare emails. | |
1008 | $this->valid = true; | |
1009 | } else if ($badge->assertion->recipient == 'sha256$' . hash('sha256', $user->email)) { | |
1010 | // If recipient is hashed, but no salt, compare hashes without salt. | |
1011 | $this->valid = true; | |
1012 | } else if ($badge->assertion->recipient == 'sha256$' . hash('sha256', $user->email . $badge->assertion->salt)) { | |
1013 | // If recipient is hashed, compare hashes. | |
1014 | $this->valid = true; | |
1015 | } else { | |
1016 | // Otherwise, we cannot be sure that this user is a recipient. | |
1017 | $this->valid = false; | |
1018 | } | |
1019 | } else { | |
1020 | $this->valid = false; | |
1021 | } | |
27806552 YB |
1022 | } |
1023 | } | |
1024 | ||
1025 | /** | |
1026 | * Badge recipients rendering class | |
1027 | */ | |
1028 | class badge_recipients implements renderable { | |
1029 | /** @var string how are the data sorted */ | |
1030 | public $sort = 'lastname'; | |
1031 | ||
1032 | /** @var string how are the data sorted */ | |
1033 | public $dir = 'ASC'; | |
1034 | ||
1035 | /** @var int page number to display */ | |
1036 | public $page = 0; | |
1037 | ||
1038 | /** @var int number of badge recipients to display per page */ | |
1039 | public $perpage = 30; | |
1040 | ||
1041 | /** @var int the total number or badge recipients to display */ | |
1042 | public $totalcount = null; | |
1043 | ||
1044 | /** @var array internal list of badge recipients ids */ | |
1045 | public $userids = array(); | |
1046 | /** | |
1047 | * Initializes the list of users to display | |
1048 | * | |
1049 | * @param array $holders List of badge holders | |
1050 | */ | |
1051 | public function __construct($holders) { | |
1052 | $this->userids = $holders; | |
1053 | } | |
1054 | } | |
1055 | ||
1056 | /** | |
1057 | * Collection of all badges for view.php page | |
1058 | */ | |
1059 | class badge_collection implements renderable { | |
1060 | ||
1061 | /** @var string how are the data sorted */ | |
1062 | public $sort = 'name'; | |
1063 | ||
1064 | /** @var string how are the data sorted */ | |
1065 | public $dir = 'ASC'; | |
1066 | ||
1067 | /** @var int page number to display */ | |
1068 | public $page = 0; | |
1069 | ||
1070 | /** @var int number of badges to display per page */ | |
1071 | public $perpage = BADGE_PERPAGE; | |
1072 | ||
1073 | /** @var int the total number of badges to display */ | |
1074 | public $totalcount = null; | |
1075 | ||
1076 | /** @var array list of badges */ | |
1077 | public $badges = array(); | |
1078 | ||
1079 | /** | |
1080 | * Initializes the list of badges to display | |
1081 | * | |
1082 | * @param array $badges Badges to render | |
1083 | */ | |
1084 | public function __construct($badges) { | |
1085 | $this->badges = $badges; | |
1086 | } | |
1087 | } | |
1088 | ||
1089 | /** | |
1090 | * Collection of badges used at the index.php page | |
1091 | */ | |
1092 | class badge_management extends badge_collection implements renderable { | |
1093 | } | |
1094 | ||
1095 | /** | |
1096 | * Collection of user badges used at the mybadges.php page | |
1097 | */ | |
1098 | class badge_user_collection extends badge_collection implements renderable { | |
1099 | /** @var array backpack settings */ | |
e2805314 | 1100 | public $backpack = null; |
27806552 YB |
1101 | |
1102 | /** @var string search */ | |
1103 | public $search = ''; | |
1104 | ||
1105 | /** | |
1106 | * Initializes user badge collection. | |
1107 | * | |
1108 | * @param array $badges Badges to render | |
1109 | * @param int $userid Badges owner | |
1110 | */ | |
1111 | public function __construct($badges, $userid) { | |
e2805314 | 1112 | global $CFG; |
27806552 | 1113 | parent::__construct($badges); |
e2805314 YB |
1114 | |
1115 | if (!empty($CFG->badges_allowexternalbackpack)) { | |
2d3c0fae | 1116 | $this->backpack = get_backpack_settings($userid, true); |
e2805314 | 1117 | } |
27806552 YB |
1118 | } |
1119 | } |