From 1dee827c39ee86e684ac2f33774f742b85a67155 Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Thu, 15 Nov 2018 15:54:54 +0800 Subject: [PATCH 1/3] MDL-63973 core_badges: related badges query now works both ways If A is related to B, then we should be able to view this relationship from both badge A and badge B. The following badge methods were updated: - get_related_badges() - has_related() - delete_related_badge() --- lib/badgeslib.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/badgeslib.php b/lib/badgeslib.php index 544b37f2991..d0c1931c428 100644 --- a/lib/badgeslib.php +++ b/lib/badgeslib.php @@ -761,7 +761,10 @@ class badge { */ public function delete_related_badge($relatedid) { global $DB; - return $DB->delete_records('badge_related', array('badgeid' => $this->id, 'relatedbadgeid' => $relatedid)); + $sql = "(badgeid = :badgeid AND relatedbadgeid = :relatedid) OR " . + "(badgeid = :relatedid2 AND relatedbadgeid = :badgeid2)"; + $params = ['badgeid' => $this->id, 'badgeid2' => $this->id, 'relatedid' => $relatedid, 'relatedid2' => $relatedid]; + return $DB->delete_records_select('badge_related', $sql, $params); } /** @@ -771,7 +774,11 @@ class badge { */ public function has_related() { global $DB; - return $DB->record_exists('badge_related', array('badgeid' => $this->id)); + $sql = "SELECT DISTINCT b.id + FROM {badge_related} br + JOIN {badge} b ON (br.relatedbadgeid = b.id OR br.badgeid = b.id) + WHERE (br.badgeid = :badgeid OR br.relatedbadgeid = :badgeid2) AND b.id != :badgeid3"; + return $DB->record_exists_sql($sql, ['badgeid' => $this->id, 'badgeid2' => $this->id, 'badgeid3' => $this->id]); } /** @@ -783,11 +790,11 @@ class badge { public function get_related_badges(bool $activeonly = false) { global $DB; - $params = array('badgeid' => $this->id); - $query = "SELECT b.id, b.name, b.version, b.language, b.type + $params = array('badgeid' => $this->id, 'badgeid2' => $this->id, 'badgeid3' => $this->id); + $query = "SELECT DISTINCT b.id, b.name, b.version, b.language, b.type FROM {badge_related} br - JOIN {badge} b ON b.id = br.relatedbadgeid - WHERE br.badgeid = :badgeid"; + JOIN {badge} b ON (br.relatedbadgeid = b.id OR br.badgeid = b.id) + WHERE (br.badgeid = :badgeid OR br.relatedbadgeid = :badgeid2) AND b.id != :badgeid3"; if ($activeonly) { $query .= " AND b.status <> :status"; $params['status'] = BADGE_STATUS_INACTIVE; From c6607726001d238716905839b1f4ec4a8b0d92fa Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Mon, 19 Nov 2018 11:06:15 +0800 Subject: [PATCH 2/3] MDL-63973 core_badges: fix related badges count in the badges tabs If A is related to B, this should show a 1 count for either A or B. --- badges/renderer.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/badges/renderer.php b/badges/renderer.php index 307675db55c..c11fd7663a7 100644 --- a/badges/renderer.php +++ b/badges/renderer.php @@ -722,8 +722,10 @@ class core_badges_renderer extends plugin_renderer_base { } if (has_capability('moodle/badges:configuredetails', $context)) { - $related = $DB->count_records_sql("SELECT COUNT(br.badgeid) - FROM {badge_related} br WHERE br.badgeid = :badgeid", array('badgeid' => $badgeid)); + $sql = "SELECT COUNT(br.badgeid) + FROM {badge_related} br + WHERE (br.badgeid = :badgeid OR br.relatedbadgeid = :badgeid2)"; + $related = $DB->count_records_sql($sql, ['badgeid' => $badgeid, 'badgeid2' => $badgeid]); $row[] = new tabobject('brelated', new moodle_url('/badges/related.php', array('id' => $badgeid)), get_string('brelated', 'badges', $related) @@ -1502,4 +1504,4 @@ class badge_competencies_alignment implements renderable $this->alignments = $alignments; $this->currentbadgeid = $currentbadgeid; } -} \ No newline at end of file +} From 810da68e14241c6996eaf924e6e5f4d6efddc746 Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Mon, 19 Nov 2018 11:19:12 +0800 Subject: [PATCH 3/3] MDL-63973 core_badges: exclude related badges when adding related badges The form which allows a user to add related badges should exclude any related badges, regardless of the direction of the relationship. --- badges/related_form.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/badges/related_form.php b/badges/related_form.php index 8e7cd56b315..31d74f4cd40 100644 --- a/badges/related_form.php +++ b/badges/related_form.php @@ -82,9 +82,12 @@ class edit_relatedbadge_form extends moodleform { $sql = "SELECT b.id, b.name, b.version, b.language, b.type FROM {badge} b WHERE b.id <> :badgeid - AND b.id NOT IN (SELECT br.relatedbadgeid - FROM {badge_related} br WHERE br.badgeid = :badgeid1)"; - $params = array('badgeid' => $badge->id, 'badgeid1' => $badge->id); + AND b.id NOT IN ( + SELECT DISTINCT b.id + FROM {badge_related} br + JOIN {badge} b ON (br.relatedbadgeid = b.id OR br.badgeid = b.id) + WHERE (br.badgeid = :badgeid2 OR br.relatedbadgeid = :badgeid3) AND b.id != :badgeid4)"; + $params = ['badgeid' => $badge->id, 'badgeid2' => $badge->id, 'badgeid3' => $badge->id, 'badgeid4' => $badge->id]; if ($badge->type == BADGE_TYPE_COURSE) { $sql .= " AND (b.courseid = :courseid OR b.type = :badgetype)"; $params['courseid'] = $badge->courseid;