diff --git a/badges/action.php b/badges/action.php index 929d9a0c819..31843a20880 100644 --- a/badges/action.php +++ b/badges/action.php @@ -29,7 +29,6 @@ require_once($CFG->libdir . '/badgeslib.php'); $badgeid = required_param('id', PARAM_INT); $copy = optional_param('copy', 0, PARAM_BOOL); -$delete = optional_param('delete', 0, PARAM_BOOL); $activate = optional_param('activate', 0, PARAM_BOOL); $deactivate = optional_param('lock', 0, PARAM_BOOL); $confirm = optional_param('confirm', 0, PARAM_BOOL); @@ -61,38 +60,6 @@ if ($return !== 0) { } $returnurl->remove_params('awards'); -if ($delete) { - require_capability('moodle/badges:deletebadge', $context); - - $PAGE->url->param('delete', 1); - if ($confirm) { - require_sesskey(); - $badge->delete(); - redirect(new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid))); - } - - $strheading = get_string('delbadge', 'badges'); - $PAGE->navbar->add($strheading); - $PAGE->set_title($strheading); - $PAGE->set_heading($badge->name); - echo $OUTPUT->header(); - echo $OUTPUT->heading($strheading); - - $urlparams = array( - 'id' => $badge->id, - 'delete' => 1, - 'confirm' => 1, - 'sesskey' => sesskey() - ); - $continue = new moodle_url('/badges/action.php', $urlparams); - $cancel = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid)); - - $message = get_string('delconfirm', 'badges', $badge->name); - echo $OUTPUT->confirm($message, $continue, $cancel); - echo $OUTPUT->footer(); - die; -} - if ($copy) { require_sesskey(); require_capability('moodle/badges:createbadge', $context); diff --git a/badges/index.php b/badges/index.php index 6c739901f37..ecc0d4fe263 100644 --- a/badges/index.php +++ b/badges/index.php @@ -30,12 +30,12 @@ require_once($CFG->libdir . '/badgeslib.php'); $type = required_param('type', PARAM_INT); $courseid = optional_param('id', 0, PARAM_INT); $page = optional_param('page', 0, PARAM_INT); -$activate = optional_param('activate', 0, PARAM_INT); $deactivate = optional_param('lock', 0, PARAM_INT); $sortby = optional_param('sort', 'name', PARAM_ALPHA); $sorthow = optional_param('dir', 'ASC', PARAM_ALPHA); $confirm = optional_param('confirm', false, PARAM_BOOL); $delete = optional_param('delete', 0, PARAM_INT); +$archive = optional_param('archive', 0, PARAM_INT); $msg = optional_param('msg', '', PARAM_TEXT); if (!in_array($sortby, array('name', 'status'))) { @@ -107,20 +107,34 @@ $PAGE->requires->js('/badges/backpack.js'); $PAGE->requires->js_init_call('check_site_access', null, false); $output = $PAGE->get_renderer('core', 'badges'); -if ($delete && has_capability('moodle/badges:deletebadge', $PAGE->context)) { - $badge = new badge($delete); +if (($delete || $archive) && has_capability('moodle/badges:deletebadge', $PAGE->context)) { + $badgeid = ($archive != 0) ? $archive : $delete; + $badge = new badge($badgeid); if (!$confirm) { echo $output->header(); - echo $output->confirm( - get_string('delconfirm', 'badges', $badge->name), - new moodle_url($PAGE->url, array('delete' => $badge->id, 'confirm' => 1)), - $returnurl - ); + // Archive this badge? + echo $output->heading(get_string('archivebadge', 'badges', $badge->name)); + $archivebutton = $output->single_button( + new moodle_url($PAGE->url, array('archive' => $badge->id, 'confirm' => 1)), + get_string('archiveconfirm', 'badges')); + echo $output->box(get_string('archivehelp', 'badges') . $archivebutton, 'generalbox'); + + // Delete this badge? + echo $output->heading(get_string('delbadge', 'badges', $badge->name)); + $deletebutton = $output->single_button( + new moodle_url($PAGE->url, array('delete' => $badge->id, 'confirm' => 1)), + get_string('delconfirm', 'badges')); + echo $output->box(get_string('deletehelp', 'badges') . $deletebutton, 'generalbox'); + + // Go back. + echo $output->action_link($returnurl, get_string('cancel')); + echo $output->footer(); die(); } else { require_sesskey(); - $badge->delete(); + $archiveonly = ($archive != 0) ? true : false; + $badge->delete($archiveonly); redirect($returnurl); } } diff --git a/badges/upgrade.txt b/badges/upgrade.txt index 1a48ffd9cfc..bab46ee7c41 100644 --- a/badges/upgrade.txt +++ b/badges/upgrade.txt @@ -7,6 +7,9 @@ information provided here is intended especially for developers. in all criteria classes. This method returns an array consisting of SQL JOIN statement, WHERE conditions, and any parameters that might be required. The results are used in lib/badgeslib.php in review_all_criteria() to reduce to the minimum the number of users to review and award badges. - * New optional parameter $filtered in review() allows to indicate that some expensive checks can be skipped if the list of users has been initially filtered based on met criteria. +* New optional parameter $archive in delete() in badge class in badgeslib.php + allows to indicate that a badge should be archived instead of fully deleted. + If this parameter is set to FALSE, a badge will all its information, criteria, + and awards will be removed from the database. diff --git a/lang/en/badges.php b/lang/en/badges.php index 14cd22b5137..099d8e7eec8 100644 --- a/lang/en/badges.php +++ b/lang/en/badges.php @@ -55,6 +55,10 @@ $string['anymethodactivity'] = 'Any of the selected activities is complete'; $string['anymethodcourseset'] = 'Any of the selected courses is complete'; $string['anymethodmanual'] = 'Any of the selected roles awards the badge'; $string['anymethodprofile'] = 'Any of the selected profile fields has been completed'; +$string['archivebadge'] = 'Would you like to delete badge \'{$a}\', but keep existing issued badges?'; +$string['archiveconfirm'] = 'Delete and keep existing issued badges'; +$string['archivehelp'] = '

This option means that the badge will be marked as "retired" and will no longer appear in the list of badges. Users will no longer be able to earn this badge, however existing badge recipients will still be able to display this badge on their profile page and push it to their external backpacks.

+

If you would like your users to retain access to the earned badges it is important to select this option instead of fully deleting badges.

'; $string['attachment'] = 'Attach badge to message'; $string['attachment_help'] = 'If checked, an issued badge file will be attached to the recepient\'s email for download. Email attachments must be enabled in site settings to use this option.'; $string['award'] = 'Award badge'; @@ -196,8 +200,10 @@ $string['defaultissuercontact'] = 'Default badge issuer contact details'; $string['defaultissuercontact_desc'] = 'An email address associated with the badge issuer.'; $string['defaultissuername'] = 'Default badge issuer name'; $string['defaultissuername_desc'] = 'Name of the issuing agent or authority.'; -$string['delbadge'] = 'Delete badge'; -$string['delconfirm'] = 'Are you sure that you want to delete badge \'{$a}\'?'; +$string['delbadge'] = 'Would you like to delete badge \'{$a}\' and remove all existing issued badges?'; +$string['delconfirm'] = 'Delete and remove existing issued badges'; +$string['deletehelp'] = '

Fully deleting a badge means that all its information and criteria records will be permanently removed. Users who have earned this badge will no longer be able to access it and display it on their profile pages.

+

Note: Users who have earned this badge and have already pushed it to their external backpack, will still have this badge in their external backpack. However, they will not be able to access criteria and evidence pages linking back to this web site.

'; $string['delcritconfirm'] = 'Are you sure that you want to delete this criterion?'; $string['delparamconfirm'] = 'Are you sure that you want to delete this parameter?'; $string['description'] = 'Description'; diff --git a/lib/badgeslib.php b/lib/badgeslib.php index 8d1bf9e5fe3..f233078b009 100644 --- a/lib/badgeslib.php +++ b/lib/badgeslib.php @@ -603,13 +603,42 @@ class badge { } /** - * Marks the badge as archived. - * For reporting and historical purposed we cannot completely delete badges. - * We will just change their status to BADGE_STATUS_ARCHIVED. + * Fully deletes the badge or marks it as archived. + * + * @param $archive bool Achive a badge without actual deleting of any data. */ - public function delete() { - $this->status = BADGE_STATUS_ARCHIVED; - $this->save(); + public function delete($archive = true) { + global $DB; + + if ($archive) { + $this->status = BADGE_STATUS_ARCHIVED; + $this->save(); + return; + } + + $fs = get_file_storage(); + + // Remove all issued badge image files and badge awards. + // Cannot bulk remove area files here because they are issued in user context. + $awards = $this->get_awards(); + foreach ($awards as $award) { + $usercontext = context_user::instance($award->userid); + $fs->delete_area_files($usercontext->id, 'badges', 'userbadge', $this->id); + } + $DB->delete_records('badge_issued', array('badgeid' => $this->id)); + + // Remove all badge criteria. + $criteria = $this->get_criteria(); + foreach ($criteria as $criterion) { + $criterion->delete(); + } + + // Delete badge images. + $badgecontext = $this->get_context(); + $fs->delete_area_files($badgecontext->id, 'badges', 'badgeimage', $this->id); + + // Finally, remove badge itself. + $DB->delete_records('badge', array('id' => $this->id)); } }