2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Badge assertion library.
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>
27 namespace core_badges
;
29 defined('MOODLE_INTERNAL') ||
die();
31 require_once($CFG->dirroot
.'/lib/badgeslib.php');
40 use core_php_time_limit
;
45 * Class that represents badge.
47 * @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
48 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
51 /** @var int Badge id */
54 /** @var string Badge name */
57 /** @var string Badge description */
60 /** @var integer Timestamp this badge was created */
63 /** @var integer Timestamp this badge was modified */
66 /** @var int The user who created this badge */
69 /** @var int The user who modified this badge */
72 /** @var string The name of the issuer of this badge */
75 /** @var string The url of the issuer of this badge */
78 /** @var string The email of the issuer of this badge */
79 public $issuercontact;
81 /** @var integer Timestamp this badge will expire */
84 /** @var integer Duration this badge is valid for */
87 /** @var integer Site or course badge */
90 /** @var integer The course this badge belongs to */
93 /** @var string The message this badge includes. */
96 /** @var string The subject of the message for this badge */
97 public $messagesubject;
99 /** @var int Is this badge image baked. */
102 /** @var int Send a message when this badge is awarded. */
103 public $notification;
105 /** @var int Lifecycle status for this badge. */
108 /** @var int Timestamp to next run cron for this badge. */
111 /** @var int What backpack api version to use for this badge. */
114 /** @var string What language is this badge written in. */
117 /** @var string The author of the image for this badge. */
118 public $imageauthorname;
120 /** @var string The email of the author of the image for this badge. */
121 public $imageauthoremail;
123 /** @var string The url of the author of the image for this badge. */
124 public $imageauthorurl;
126 /** @var string The caption of the image for this badge. */
127 public $imagecaption;
129 /** @var array Badge criteria */
130 public $criteria = array();
133 * Constructs with badge details.
135 * @param int $badgeid badge ID.
137 public function __construct($badgeid) {
139 $this->id
= $badgeid;
141 $data = $DB->get_record('badge', array('id' => $badgeid));
144 print_error('error:nosuchbadge', 'badges', $badgeid);
147 foreach ((array)$data as $field => $value) {
148 if (property_exists($this, $field)) {
149 $this->{$field} = $value;
153 if (badges_open_badges_backpack_api() != OPEN_BADGES_V1
) {
154 // For Open Badges 2 we need to use a single site issuer with no exceptions.
155 $issuer = badges_get_default_issuer();
156 $this->issuername
= $issuer['name'];
157 $this->issuercontact
= $issuer['email'];
158 $this->issuerurl
= $issuer['url'];
161 $this->criteria
= self
::get_criteria();
165 * Use to get context instance of a badge.
167 * @return context instance.
169 public function get_context() {
170 if ($this->type
== BADGE_TYPE_SITE
) {
171 return context_system
::instance();
172 } else if ($this->type
== BADGE_TYPE_COURSE
) {
173 return context_course
::instance($this->courseid
);
175 debugging('Something is wrong...');
180 * Return array of aggregation methods
184 public static function get_aggregation_methods() {
186 BADGE_CRITERIA_AGGREGATION_ALL
=> get_string('all', 'badges'),
187 BADGE_CRITERIA_AGGREGATION_ANY
=> get_string('any', 'badges'),
192 * Return array of accepted criteria types for this badge
196 public function get_accepted_criteria() {
198 $criteriatypes = array();
200 if ($this->type
== BADGE_TYPE_COURSE
) {
201 $criteriatypes = array(
202 BADGE_CRITERIA_TYPE_OVERALL
,
203 BADGE_CRITERIA_TYPE_MANUAL
,
204 BADGE_CRITERIA_TYPE_COURSE
,
205 BADGE_CRITERIA_TYPE_BADGE
,
206 BADGE_CRITERIA_TYPE_ACTIVITY
,
207 BADGE_CRITERIA_TYPE_COMPETENCY
209 } else if ($this->type
== BADGE_TYPE_SITE
) {
210 $criteriatypes = array(
211 BADGE_CRITERIA_TYPE_OVERALL
,
212 BADGE_CRITERIA_TYPE_MANUAL
,
213 BADGE_CRITERIA_TYPE_COURSESET
,
214 BADGE_CRITERIA_TYPE_BADGE
,
215 BADGE_CRITERIA_TYPE_PROFILE
,
216 BADGE_CRITERIA_TYPE_COHORT
,
217 BADGE_CRITERIA_TYPE_COMPETENCY
220 $alltypes = badges_list_criteria();
221 foreach ($criteriatypes as $index => $type) {
222 if (!isset($alltypes[$type])) {
223 unset($criteriatypes[$index]);
227 return $criteriatypes;
231 * Save/update badge information in 'badge' table only.
232 * Cannot be used for updating awards and criteria settings.
234 * @return boolean Returns true on success.
236 public function save() {
239 $fordb = new stdClass();
240 foreach (get_object_vars($this) as $k => $v) {
243 unset($fordb->criteria
);
245 $fordb->timemodified
= time();
246 if ($DB->update_record_raw('badge', $fordb)) {
247 // Trigger event, badge updated.
248 $eventparams = array('objectid' => $this->id
, 'context' => $this->get_context());
249 $event = \core\event\badge_updated
::create($eventparams);
253 throw new moodle_exception('error:save', 'badges');
259 * Creates and saves a clone of badge with all its properties.
260 * Clone is not active by default and has 'Copy of' attached to its name.
262 * @return int ID of new badge.
264 public function make_clone() {
265 global $DB, $USER, $PAGE;
267 $fordb = new stdClass();
268 foreach (get_object_vars($this) as $k => $v) {
272 $fordb->name
= get_string('copyof', 'badges', $this->name
);
273 $fordb->status
= BADGE_STATUS_INACTIVE
;
274 $fordb->usercreated
= $USER->id
;
275 $fordb->usermodified
= $USER->id
;
276 $fordb->timecreated
= time();
277 $fordb->timemodified
= time();
280 if ($fordb->notification
> 1) {
281 $fordb->nextcron
= badges_calculate_message_schedule($fordb->notification
);
284 $criteria = $fordb->criteria
;
285 unset($fordb->criteria
);
287 if ($new = $DB->insert_record('badge', $fordb, true)) {
288 $newbadge = new badge($new);
291 $fs = get_file_storage();
292 if ($file = $fs->get_file($this->get_context()->id
, 'badges', 'badgeimage', $this->id
, '/', 'f1.png')) {
293 if ($imagefile = $file->copy_content_to_temp()) {
294 badges_process_badge_image($newbadge, $imagefile);
298 // Copy badge criteria.
299 foreach ($this->criteria
as $crit) {
300 $crit->make_clone($new);
303 // Trigger event, badge duplicated.
304 $eventparams = array('objectid' => $new, 'context' => $PAGE->context
);
305 $event = \core\event\badge_duplicated
::create($eventparams);
310 throw new moodle_exception('error:clone', 'badges');
316 * Checks if badges is active.
317 * Used in badge award.
319 * @return boolean A status indicating badge is active
321 public function is_active() {
322 if (($this->status
== BADGE_STATUS_ACTIVE
) ||
323 ($this->status
== BADGE_STATUS_ACTIVE_LOCKED
)) {
330 * Use to get the name of badge status.
334 public function get_status_name() {
335 return get_string('badgestatus_' . $this->status
, 'badges');
339 * Use to set badge status.
340 * Only active badges can be earned/awarded/issued.
342 * @param int $status Status from BADGE_STATUS constants
344 public function set_status($status = 0) {
345 $this->status
= $status;
347 if ($status == BADGE_STATUS_ACTIVE
) {
348 // Trigger event, badge enabled.
349 $eventparams = array('objectid' => $this->id
, 'context' => $this->get_context());
350 $event = \core\event\badge_enabled
::create($eventparams);
352 } else if ($status == BADGE_STATUS_INACTIVE
) {
353 // Trigger event, badge disabled.
354 $eventparams = array('objectid' => $this->id
, 'context' => $this->get_context());
355 $event = \core\event\badge_disabled
::create($eventparams);
361 * Checks if badges is locked.
362 * Used in badge award and editing.
364 * @return boolean A status indicating badge is locked
366 public function is_locked() {
367 if (($this->status
== BADGE_STATUS_ACTIVE_LOCKED
) ||
368 ($this->status
== BADGE_STATUS_INACTIVE_LOCKED
)) {
375 * Checks if badge has been awarded to users.
376 * Used in badge editing.
378 * @return boolean A status indicating badge has been awarded at least once
380 public function has_awards() {
382 $awarded = $DB->record_exists_sql('SELECT b.uniquehash
383 FROM {badge_issued} b INNER JOIN {user} u ON b.userid = u.id
384 WHERE b.badgeid = :badgeid AND u.deleted = 0', array('badgeid' => $this->id
));
390 * Gets list of users who have earned an instance of this badge.
392 * @return array An array of objects with information about badge awards.
394 public function get_awards() {
397 $awards = $DB->get_records_sql(
398 'SELECT b.userid, b.dateissued, b.uniquehash, u.firstname, u.lastname
399 FROM {badge_issued} b INNER JOIN {user} u
401 WHERE b.badgeid = :badgeid AND u.deleted = 0', array('badgeid' => $this->id
));
407 * Indicates whether badge has already been issued to a user.
409 * @param int $userid User to check
412 public function is_issued($userid) {
414 return $DB->record_exists('badge_issued', array('badgeid' => $this->id
, 'userid' => $userid));
418 * Issue a badge to user.
420 * @param int $userid User who earned the badge
421 * @param boolean $nobake Not baking actual badges (for testing purposes)
423 public function issue($userid, $nobake = false) {
427 $issued = new stdClass();
428 $issued->badgeid
= $this->id
;
429 $issued->userid
= $userid;
430 $issued->uniquehash
= sha1(rand() . $userid . $this->id
. $now);
431 $issued->dateissued
= $now;
433 if ($this->can_expire()) {
434 $issued->dateexpire
= $this->calculate_expiry($now);
436 $issued->dateexpire
= null;
439 // Take into account user badges privacy settings.
440 // If none set, badges default visibility is set to public.
441 $issued->visible
= get_user_preferences('badgeprivacysetting', 1, $userid);
443 $result = $DB->insert_record('badge_issued', $issued, true);
446 // Trigger badge awarded event.
448 'context' => $this->get_context(),
449 'objectid' => $this->id
,
450 'relateduserid' => $userid,
451 'other' => array('dateexpire' => $issued->dateexpire
, 'badgeissuedid' => $result)
453 \core\event\badge_awarded
::create($eventdata)->trigger();
455 // Lock the badge, so that its criteria could not be changed any more.
456 if ($this->status
== BADGE_STATUS_ACTIVE
) {
457 $this->set_status(BADGE_STATUS_ACTIVE_LOCKED
);
460 // Update details in criteria_met table.
461 $compl = $this->get_criteria_completions($userid);
462 foreach ($compl as $c) {
463 $obj = new stdClass();
465 $obj->issuedid
= $result;
466 $DB->update_record('badge_criteria_met', $obj, true);
470 // Bake a badge image.
471 $pathhash = badges_bake($issued->uniquehash
, $this->id
, $userid, true);
473 // Notify recipients and badge creators.
474 badges_notify_badge_award($this, $userid, $issued->uniquehash
, $pathhash);
480 * Reviews all badge criteria and checks if badge can be instantly awarded.
482 * @return int Number of awards
484 public function review_all_criteria() {
488 // Raise timelimit as this could take a while for big web sites.
489 core_php_time_limit
::raise();
490 raise_memory_limit(MEMORY_HUGE
);
492 foreach ($this->criteria
as $crit) {
493 // Overall criterion is decided when other criteria are reviewed.
494 if ($crit->criteriatype
== BADGE_CRITERIA_TYPE_OVERALL
) {
498 list($extrajoin, $extrawhere, $extraparams) = $crit->get_completed_criteria_sql();
499 // For site level badges, get all active site users who can earn this badge and haven't got it yet.
500 if ($this->type
== BADGE_TYPE_SITE
) {
501 $sql = "SELECT DISTINCT u.id, bi.badgeid
504 LEFT JOIN {badge_issued} bi
505 ON u.id = bi.userid AND bi.badgeid = :badgeid
506 WHERE bi.badgeid IS NULL AND u.id != :guestid AND u.deleted = 0 " . $extrawhere;
507 $params = array_merge(array('badgeid' => $this->id
, 'guestid' => $CFG->siteguest
), $extraparams);
508 $toearn = $DB->get_fieldset_sql($sql, $params);
510 // For course level badges, get all users who already earned the badge in this course.
511 // Then find the ones who are enrolled in the course and don't have a badge yet.
512 $earned = $DB->get_fieldset_select(
515 'badgeid = :badgeid',
516 array('badgeid' => $this->id
)
520 $earnedparams = array();
521 if (!empty($earned)) {
522 list($earnedsql, $earnedparams) = $DB->get_in_or_equal($earned, SQL_PARAMS_NAMED
, 'u', false);
523 $wheresql = ' WHERE u.id ' . $earnedsql;
525 list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->get_context(), 'moodle/badges:earnbadge', 0, true);
526 $sql = "SELECT DISTINCT u.id
529 JOIN ({$enrolledsql}) je ON je.id = u.id " . $wheresql . $extrawhere;
530 $params = array_merge($enrolledparams, $earnedparams, $extraparams);
531 $toearn = $DB->get_fieldset_sql($sql, $params);
534 foreach ($toearn as $uid) {
535 $reviewoverall = false;
536 if ($crit->review($uid, true)) {
537 $crit->mark_complete($uid);
538 if ($this->criteria
[BADGE_CRITERIA_TYPE_OVERALL
]->method
== BADGE_CRITERIA_AGGREGATION_ANY
) {
539 $this->criteria
[BADGE_CRITERIA_TYPE_OVERALL
]->mark_complete($uid);
543 $reviewoverall = true;
546 // Will be reviewed some other time.
547 $reviewoverall = false;
549 // Review overall if it is required.
550 if ($reviewoverall && $this->criteria
[BADGE_CRITERIA_TYPE_OVERALL
]->review($uid)) {
551 $this->criteria
[BADGE_CRITERIA_TYPE_OVERALL
]->mark_complete($uid);
562 * Gets an array of completed criteria from 'badge_criteria_met' table.
564 * @param int $userid Completions for a user
565 * @return array Records of criteria completions
567 public function get_criteria_completions($userid) {
569 $completions = array();
570 $sql = "SELECT bcm.id, bcm.critid
571 FROM {badge_criteria_met} bcm
572 INNER JOIN {badge_criteria} bc ON bcm.critid = bc.id
573 WHERE bc.badgeid = :badgeid AND bcm.userid = :userid ";
574 $completions = $DB->get_records_sql($sql, array('badgeid' => $this->id
, 'userid' => $userid));
580 * Checks if badges has award criteria set up.
582 * @return boolean A status indicating badge has at least one criterion
584 public function has_criteria() {
585 if (count($this->criteria
) > 0) {
592 * Returns badge award criteria
594 * @return array An array of badge criteria
596 public function get_criteria() {
600 if ($records = (array)$DB->get_records('badge_criteria', array('badgeid' => $this->id
))) {
601 foreach ($records as $record) {
602 $criteria[$record->criteriatype
] = award_criteria
::build((array)$record);
610 * Get aggregation method for badge criteria
612 * @param int $criteriatype If none supplied, get overall aggregation method (optional)
613 * @return int One of BADGE_CRITERIA_AGGREGATION_ALL or BADGE_CRITERIA_AGGREGATION_ANY
615 public function get_aggregation_method($criteriatype = 0) {
617 $params = array('badgeid' => $this->id
, 'criteriatype' => $criteriatype);
618 $aggregation = $DB->get_field('badge_criteria', 'method', $params, IGNORE_MULTIPLE
);
621 return BADGE_CRITERIA_AGGREGATION_ALL
;
628 * Checks if badge has expiry period or date set up.
630 * @return boolean A status indicating badge can expire
632 public function can_expire() {
633 if ($this->expireperiod ||
$this->expiredate
) {
640 * Calculates badge expiry date based on either expirydate or expiryperiod.
642 * @param int $timestamp Time of badge issue
643 * @return int A timestamp
645 public function calculate_expiry($timestamp) {
648 if (isset($this->expiredate
)) {
649 $expiry = $this->expiredate
;
650 } else if (isset($this->expireperiod
)) {
651 $expiry = $timestamp +
$this->expireperiod
;
658 * Checks if badge has manual award criteria set.
660 * @return boolean A status indicating badge can be awarded manually
662 public function has_manual_award_criteria() {
663 foreach ($this->criteria
as $criterion) {
664 if ($criterion->criteriatype
== BADGE_CRITERIA_TYPE_MANUAL
) {
672 * Fully deletes the badge or marks it as archived.
674 * @param boolean $archive Achive a badge without actual deleting of any data.
676 public function delete($archive = true) {
680 $this->status
= BADGE_STATUS_ARCHIVED
;
683 // Trigger event, badge archived.
684 $eventparams = array('objectid' => $this->id
, 'context' => $this->get_context());
685 $event = \core\event\badge_archived
::create($eventparams);
690 $fs = get_file_storage();
692 // Remove all issued badge image files and badge awards.
693 // Cannot bulk remove area files here because they are issued in user context.
694 $awards = $this->get_awards();
695 foreach ($awards as $award) {
696 $usercontext = context_user
::instance($award->userid
);
697 $fs->delete_area_files($usercontext->id
, 'badges', 'userbadge', $this->id
);
699 $DB->delete_records('badge_issued', array('badgeid' => $this->id
));
701 // Remove all badge criteria.
702 $criteria = $this->get_criteria();
703 foreach ($criteria as $criterion) {
704 $criterion->delete();
707 // Delete badge images.
708 $badgecontext = $this->get_context();
709 $fs->delete_area_files($badgecontext->id
, 'badges', 'badgeimage', $this->id
);
711 // Delete endorsements, competencies and related badges.
712 $DB->delete_records('badge_endorsement', array('badgeid' => $this->id
));
713 $relatedsql = 'badgeid = :badgeid OR relatedbadgeid = :relatedbadgeid';
714 $relatedparams = array(
715 'badgeid' => $this->id
,
716 'relatedbadgeid' => $this->id
718 $DB->delete_records_select('badge_related', $relatedsql, $relatedparams);
719 $DB->delete_records('badge_alignment', array('badgeid' => $this->id
));
721 // Finally, remove badge itself.
722 $DB->delete_records('badge', array('id' => $this->id
));
724 // Trigger event, badge deleted.
725 $eventparams = array('objectid' => $this->id
,
726 'context' => $this->get_context(),
727 'other' => array('badgetype' => $this->type
, 'courseid' => $this->courseid
)
729 $event = \core\event\badge_deleted
::create($eventparams);
734 * Add multiple related badges.
736 * @param array $relatedids Id of badges.
738 public function add_related_badges($relatedids) {
740 $relatedbadges = array();
741 foreach ($relatedids as $relatedid) {
742 $relatedbadge = new stdClass();
743 $relatedbadge->badgeid
= $this->id
;
744 $relatedbadge->relatedbadgeid
= $relatedid;
745 $relatedbadges[] = $relatedbadge;
747 $DB->insert_records('badge_related', $relatedbadges);
751 * Delete an related badge.
753 * @param int $relatedid Id related badge.
754 * @return boolean A status for delete an related badge.
756 public function delete_related_badge($relatedid) {
758 $sql = "(badgeid = :badgeid AND relatedbadgeid = :relatedid) OR " .
759 "(badgeid = :relatedid2 AND relatedbadgeid = :badgeid2)";
760 $params = ['badgeid' => $this->id
, 'badgeid2' => $this->id
, 'relatedid' => $relatedid, 'relatedid2' => $relatedid];
761 return $DB->delete_records_select('badge_related', $sql, $params);
765 * Checks if badge has related badges.
767 * @return boolean A status related badge.
769 public function has_related() {
771 $sql = "SELECT DISTINCT b.id
772 FROM {badge_related} br
773 JOIN {badge} b ON (br.relatedbadgeid = b.id OR br.badgeid = b.id)
774 WHERE (br.badgeid = :badgeid OR br.relatedbadgeid = :badgeid2) AND b.id != :badgeid3";
775 return $DB->record_exists_sql($sql, ['badgeid' => $this->id
, 'badgeid2' => $this->id
, 'badgeid3' => $this->id
]);
779 * Get related badges of badge.
781 * @param boolean $activeonly Do not get the inactive badges when is true.
782 * @return array Related badges information.
784 public function get_related_badges($activeonly = false) {
787 $params = array('badgeid' => $this->id
, 'badgeid2' => $this->id
, 'badgeid3' => $this->id
);
788 $query = "SELECT DISTINCT b.id, b.name, b.version, b.language, b.type
789 FROM {badge_related} br
790 JOIN {badge} b ON (br.relatedbadgeid = b.id OR br.badgeid = b.id)
791 WHERE (br.badgeid = :badgeid OR br.relatedbadgeid = :badgeid2) AND b.id != :badgeid3";
793 $query .= " AND b.status <> :status";
794 $params['status'] = BADGE_STATUS_INACTIVE
;
796 $relatedbadges = $DB->get_records_sql($query, $params);
797 return $relatedbadges;
801 * Insert/update alignment information of badge.
803 * @param stdClass $alignment Data of a alignment.
804 * @param int $alignmentid ID alignment.
805 * @return bool|int A status/ID when insert or update data.
807 public function save_alignment($alignment, $alignmentid = 0) {
810 $record = $DB->record_exists('badge_alignment', array('id' => $alignmentid));
812 $alignment->id
= $alignmentid;
813 return $DB->update_record('badge_alignment', $alignment);
815 return $DB->insert_record('badge_alignment', $alignment, true);
820 * Delete a alignment of badge.
822 * @param int $alignmentid ID alignment.
823 * @return boolean A status for delete a alignment.
825 public function delete_alignment($alignmentid) {
827 return $DB->delete_records('badge_alignment', array('badgeid' => $this->id
, 'id' => $alignmentid));
831 * Get alignments of badge.
833 * @return array List content alignments.
835 public function get_alignments() {
837 return $DB->get_records('badge_alignment', array('badgeid' => $this->id
));
841 * Insert/update Endorsement information of badge.
843 * @param stdClass $endorsement Data of an endorsement.
844 * @return bool|int A status/ID when insert or update data.
846 public function save_endorsement($endorsement) {
848 $record = $DB->get_record('badge_endorsement', array('badgeid' => $this->id
));
850 $endorsement->id
= $record->id
;
851 return $DB->update_record('badge_endorsement', $endorsement);
853 return $DB->insert_record('badge_endorsement', $endorsement, true);
858 * Get endorsement of badge.
860 * @return array|stdClass Endorsement information.
862 public function get_endorsement() {
864 return $DB->get_record('badge_endorsement', array('badgeid' => $this->id
));
868 * Markdown language support for criteria.
870 * @return string $output Markdown content to output.
872 public function markdown_badge_criteria() {
873 $agg = $this->get_aggregation_methods();
874 if (empty($this->criteria
)) {
875 return get_string('nocriteria', 'badges');
878 $overall = $this->criteria
[BADGE_CRITERIA_TYPE_OVERALL
];
879 if (!empty($overall->description
)) {
880 $overalldescr = format_text($overall->description
, $overall->descriptionformat
,
881 array('context' => $this->get_context())) . '\n';
883 // Get the condition string.
884 if (count($this->criteria
) == 2) {
885 $condition = get_string('criteria_descr', 'badges');
887 $condition = get_string('criteria_descr_' . BADGE_CRITERIA_TYPE_OVERALL
, 'badges',
888 core_text
::strtoupper($agg[$this->get_aggregation_method()]));
890 unset($this->criteria
[BADGE_CRITERIA_TYPE_OVERALL
]);
892 // If only one criterion left, make sure its description goe to the top.
893 if (count($this->criteria
) == 1) {
894 $c = reset($this->criteria
);
895 if (!empty($c->description
)) {
896 $overalldescr = $c->description
. '\n';
898 if (count($c->params
) == 1) {
899 $items[] = ' * ' . get_string('criteria_descr_single_' . $c->criteriatype
, 'badges') .
902 $items[] = '* ' . get_string('criteria_descr_' . $c->criteriatype
, 'badges',
903 core_text
::strtoupper($agg[$this->get_aggregation_method($c->criteriatype
)])) .
907 foreach ($this->criteria
as $type => $c) {
909 if (!empty($c->description
)) {
910 $criteriadescr = $c->description
;
912 if (count($c->params
) == 1) {
913 $items[] = ' * ' . get_string('criteria_descr_single_' . $type, 'badges') .
914 $c->get_details() . $criteriadescr;
916 $items[] = '* ' . get_string('criteria_descr_' . $type, 'badges',
917 core_text
::strtoupper($agg[$this->get_aggregation_method($type)])) .
918 $c->get_details() . $criteriadescr;
922 return strip_tags($overalldescr . $condition . html_writer
::alist($items, array(), 'ul'));
926 * Define issuer information by format Open Badges specification version 2.
928 * @return array Issuer informations of the badge.
930 public function get_badge_issuer() {
932 $issuerurl = new moodle_url('/badges/badge_json.php', array('id' => $this->id
, 'action' => 0));
933 $issuer['name'] = $this->issuername
;
934 $issuer['url'] = $this->issuerurl
;
935 $issuer['email'] = $this->issuercontact
;
936 $issuer['@context'] = OPEN_BADGES_V2_CONTEXT
;
937 $issuer['id'] = $this->issuerurl
;
938 $issuer['type'] = OPEN_BADGES_V2_TYPE_ISSUER
;