diff --git a/classes/badgeinfo.php b/classes/badgeinfo.php index f03f867..ecfeb8f 100644 --- a/classes/badgeinfo.php +++ b/classes/badgeinfo.php @@ -166,9 +166,23 @@ class badgeinfo { "id" => new \external_value(PARAM_INT, 'id of badge'), "infolink" => new \external_value(PARAM_TEXT, 'badge issue information link', VALUE_OPTIONAL), "name" => new \external_value(PARAM_TEXT, 'badge name'), - "criteria" => new \external_multiple_structure( - new \external_value(PARAM_RAW, 'criteria text'), - 'badge criteria', VALUE_OPTIONAL), + "completion" => new \external_multiple_structure(new \external_single_structure([ + "types" => new \external_multiple_structure(new \external_single_structure([ + 'criteria' => new \external_multiple_structure(new \external_single_structure([ + "title" => new \external_value(PARAM_TEXT, 'criterion title'), + "details" => new \external_value(PARAM_TEXT, 'criterion details'), + "completed" => new \external_value(PARAM_BOOL, 'criterion is completed or not'), + ]),'specific criteria'), + "aggregation" => new \external_value(PARAM_TEXT, 'any|all'), + "count" => new \external_value(PARAM_INT, 'effective number of critera for type progress'), + "progress" => new \external_value(PARAM_INT, 'effective number of completed criteria for type progress'), + "fraction" => new \external_value(PARAM_FLOAT, 'fraction of completed type criteria as float'), + ]), "criteria types"), + "aggregation" => new \external_value(PARAM_TEXT, 'any|all'), + "count" => new \external_value(PARAM_INT, 'total number of critera for progress'), + "progress" => new \external_value(PARAM_INT, 'number of completed criteria for progress'), + "fraction" => new \external_value(PARAM_FLOAT, 'fraction of completed criteria as float'), + ]),'badge criteria', VALUE_OPTIONAL), "description" => new \external_value(PARAM_TEXT, 'badge description'), "imageurl" => new \external_value(PARAM_TEXT, 'url of badge image'), "issued" => new \external_value(PARAM_BOOL, 'badge is issued'), @@ -195,10 +209,7 @@ class badgeinfo { $issued = $this->badge->is_issued($userid); // If the user is viewing another user's badge and doesn't have the right capability return only part of the data. - $criteria = []; - foreach ($this->badge->get_criteria() as $bc) { - $criteria[] = $bc->get_title()."".$bc->get_details(); - } + $badge = [ 'id' => $this->badge->id, 'name' => $this->badge->name, @@ -208,7 +219,7 @@ class badgeinfo { 'badgeimage', $this->badge->id, '/', 'f1' )->out(false), - 'criteria' => $criteria, + 'completion' => $this->badge_completion_data($userid), 'issued' => $issued, 'infolink' => (new \moodle_url('/badges/overview.php', ['id' => $this->badge->id]))->out(false), ]; @@ -226,6 +237,70 @@ class badgeinfo { return $badge; } + protected function badge_completion_data($userid) { + + $count = 0; + $progress = 0; + $fraction = 0; + + $badgeagg = $this->badge->get_aggregation_method(); + $types = []; + foreach ($this->badge->criteria as $type => $c) { + $typeagg = $this->badge->get_aggregation_method($type); + $typecrit = []; + + $typeprogress = 0; + $typecount = count($c); + foreach ($c as $bc) { + $iscompleted = $bc->review($userid); + $typecrit[] = [ + "title" => $bc->get_title(), + "details" => $bc->get_details(), + "completed" => $iscompleted, + ]; + if ($iscompleted) { + $typeprogress++; + } + } + if ($typeagg == BADGE_CRITERIA_AGGREGATION_ANY) { + $typecount = 1; + $typeprogress = ($typeprogress > 0)?1:0; + } + if($badgeagg == BADGE_CRITERIA_AGGREGATION_ANY) { + /* If ANY completion overall, count only the criteria type with the highest completion percentage -. + Overwrite data if current type is more complete */ + $typefraction = $typeprogress / $typecount; + if ($typefraction > $fraction) { + $fraction = $typefraction; + $count = $typecount; + $progress = $typeprogress; + } + } else { + /* If ALL completion overall, just add it up to the total */ + $count += $typecount; + $progress += $typeprogress; + } + + $typeinfo = [ + 'aggregation' => ($typeagg == BADGE_CRITERIA_AGGREGATION_ALL)?"all":"any", + 'criteria' => $typecrit, + 'count' => $typecount, + 'progress' => $typeprogress, + "fraction" => $typefraction, + ]; + $types[] = $typeinfo; + } + + $c = [ + "types" => $types, + "aggregation" => ($typeagg == BADGE_CRITERIA_AGGREGATION_ALL)?"all":"any", + "count" => $count, + "progress" => $progress, + "fraction" => $fraction, + ]; + + } + /** * Count how many of the students in the array have this badge issued * @param int[] $studentids List of user id's to check