Return criteria progress details for display in reports

@param completion_completion $completion The user's completion record
@return array An array with the following keys:
type, criteria, requirement, status
182623
public function get_details($completion) {
        global $CFG;
        require_once($CFG->libdir . '/gradelib.php');
        $decimalpoints = grade_get_setting($this->course, 'decimalpoints', $CFG->grade_decimalpoints);

        $details = array();
        $details['type'] = get_string('coursegrade', 'completion');
        $details['criteria'] = get_string('graderequired', 'completion');
        $details['requirement'] = format_float($this->gradepass, $decimalpoints);
        $details['status'] = '';

        $grade = format_float($this->get_grade($completion), $decimalpoints);
        if ($grade) {
            $details['status'] = $grade;
        }

        return $details;
    }
938565
public function get_details($completion) {
        // Get completion info
        $modinfo = get_fast_modinfo($completion->course);
        $cm = $modinfo->get_cm($this->moduleinstance);

        $details = array();
        $details['type'] = $this->get_title();
        if ($cm->has_view()) {
            $details['criteria'] = html_writer::link($cm->url, $cm->get_formatted_name());
        } else {
            $details['criteria'] = $cm->get_formatted_name();
        }

        // Build requirements
        $details['requirement'] = array();

        if ($cm->completion == COMPLETION_TRACKING_MANUAL) {
            $details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
        } elseif ($cm->completion == COMPLETION_TRACKING_AUTOMATIC) {
            if ($cm->completionview) {
                $modulename = core_text::strtolower(get_string('modulename', $this->module));
                $details['requirement'][] = get_string('viewingactivity', 'completion', $modulename);
            }

            if (!is_null($cm->completiongradeitemnumber)) {
                $details['requirement'][] = get_string('achievinggrade', 'completion');
            }
        }

        $details['requirement'] = implode($details['requirement'], ', ');

        $details['status'] = '';

        return $details;
    }
607671
public static function get_available_completion_tabs($courseorid) {
        $tabs = [];

        $courseid = is_object($courseorid) ? $courseorid->id : $courseorid;
        $coursecontext = context_course::instance($courseid);

        if (has_capability('moodle/course:update', $coursecontext)) {
            $tabs[] = new tabobject(
                'completion',
                new moodle_url('/course/completion.php', ['id' => $courseid]),
                new lang_string('coursecompletion', 'completion')
            );
        }

        if (has_capability('moodle/course:manageactivities', $coursecontext)) {
            $tabs[] = new tabobject(
                'defaultcompletion',
                new moodle_url('/course/defaultcompletion.php', ['id' => $courseid]),
                new lang_string('defaultcompletion', 'completion')
            );
        }

        if (self::can_edit_bulk_completion($courseorid)) {
            $tabs[] = new tabobject(
                'bulkcompletion',
                new moodle_url('/course/bulkcompletion.php', ['id' => $courseid]),
                new lang_string('bulkactivitycompletion', 'completion')
            );
        }

        return $tabs;
    }
163835
public function add_completion_rules() {
        $mform =& $this->_form;

        $group=array();
        $group[] =& $mform->createElement('checkbox', 'completionpostsenabled', '', get_string('completionposts','forum'));
        $group[] =& $mform->createElement('text', 'completionposts', '', array('size'=>3));
        $mform->setType('completionposts',PARAM_INT);
        $mform->addGroup($group, 'completionpostsgroup', get_string('completionpostsgroup','forum'), array(' '), false);
        $mform->disabledIf('completionposts','completionpostsenabled','notchecked');

        $group=array();
        $group[] =& $mform->createElement('checkbox', 'completiondiscussionsenabled', '', get_string('completiondiscussions','forum'));
        $group[] =& $mform->createElement('text', 'completiondiscussions', '', array('size'=>3));
        $mform->setType('completiondiscussions',PARAM_INT);
        $mform->addGroup($group, 'completiondiscussionsgroup', get_string('completiondiscussionsgroup','forum'), array(' '), false);
        $mform->disabledIf('completiondiscussions','completiondiscussionsenabled','notchecked');

        $group=array();
        $group[] =& $mform->createElement('checkbox', 'completionrepliesenabled', '', get_string('completionreplies','forum'));
        $group[] =& $mform->createElement('text', 'completionreplies', '', array('size'=>3));
        $mform->setType('completionreplies',PARAM_INT);
        $mform->addGroup($group, 'completionrepliesgroup', get_string('completionrepliesgroup','forum'), array(' '), false);
        $mform->disabledIf('completionreplies','completionrepliesenabled','notchecked');

        return array('completiondiscussionsgroup','completionrepliesgroup','completionpostsgroup');
    }
725285
public function getCriteriaChange($owner, AchievementCriteria $criteria, Achievement $achievement, $data = null)
    {
        $handler = $this->handlers->getHandlerFor($criteria->type());

        if (!$handler instanceof CriteriaHandler) {
            return null;
        }

        return $handler->handle($owner, $criteria, $achievement, $data);
    }
463111
public function getAutocompleteResults(Request $request, $type)
    {
        $form = $this->formFactory->create($type);
        $fieldOptions = $form->get($request->get('field_name'))->getConfig()->getOptions();

        /** @var EntityRepository $repo */
        $repo = $this->doctrine->getRepository($fieldOptions['class']);

        $term = $request->get('q');

        $countQB = $repo->createQueryBuilder('e');
        $countQB
            ->select($countQB->expr()->count('e'))
            ->where('e.'.$fieldOptions['property'].' LIKE :term')
            ->setParameter('term', '%' . $term . '%')
        ;

        $maxResults = $fieldOptions['page_limit'];
        $offset = ($request->get('page', 1) - 1) * $maxResults;

        $resultQb = $repo->createQueryBuilder('e');
        $resultQb
            ->where('e.'.$fieldOptions['property'].' LIKE :term')
            ->setParameter('term', '%' . $term . '%')
            ->setMaxResults($maxResults)
            ->setFirstResult($offset)
        ;

        if (is_callable($fieldOptions['callback'])) {
            $cb = $fieldOptions['callback'];

            $cb($countQB, $request);
            $cb($resultQb, $request);
        }

        $count = $countQB->getQuery()->getSingleScalarResult();
        $paginationResults = $resultQb->getQuery()->getResult();

        $result = ['results' => null, 'more' => $count > ($offset + $maxResults)];

        $accessor = PropertyAccess::createPropertyAccessor();

        $result['results'] = array_map(function ($item) use ($accessor, $fieldOptions) {
            return ['id' => $accessor->getValue($item, $fieldOptions['primary_key']), 'text' => $accessor->getValue($item, $fieldOptions['property'])];
        }, $paginationResults);

        return $result;
    }
644897
public static function get_course_completion_info(\stdClass $user, \stdClass $course) : array {
        $completioninfo = new \completion_info($course);
        $completion = $completioninfo->is_enabled();

        if ($completion != COMPLETION_ENABLED) {
            return [];
        }

        $coursecomplete = $completioninfo->is_course_complete($user->id);

        if ($coursecomplete) {
            $status = get_string('complete');
        } else {
            $criteriacomplete = $completioninfo->count_course_user_data($user->id);
            $ccompletion = new \completion_completion(['userid' => $user->id, 'course' => $course->id]);

            if (!$criteriacomplete && !$ccompletion->timestarted) {
                $status = get_string('notyetstarted', 'completion');
            } else {
                $status = get_string('inprogress', 'completion');
            }
        }

        $completions = $completioninfo->get_completions($user->id);
        $overall = get_string('nocriteriaset', 'completion');
        if (!empty($completions)) {
            if ($completioninfo->get_aggregation_method() == COMPLETION_AGGREGATION_ALL) {
                $overall = get_string('criteriarequiredall', 'completion');
            } else {
                $overall = get_string('criteriarequiredany', 'completion');
            }
        }

        $coursecompletiondata = [
            'status' => $status,
            'required' => $overall,
        ];

        $coursecompletiondata['criteria'] = array_map(function($completion) use ($completioninfo) {
            $criteria = $completion->get_criteria();
            $aggregation = $completioninfo->get_aggregation_method($criteria->criteriatype);
            $required = ($aggregation == COMPLETION_AGGREGATION_ALL) ? get_string('all', 'completion') :
                    get_string('any', 'completion');
            $data = [
                'required' => $required,
                'completed' => transform::yesno($completion->is_complete()),
                'timecompleted' => isset($completion->timecompleted) ? transform::datetime($completion->timecompleted) : ''
            ];
            $details = $criteria->get_details($completion);
            $data = array_merge($data, $details);
            return $data;
        }, $completions);
        return $coursecompletiondata;
    }
916879
public function get_completion($user_id, $criteriatype) {
        $completions = $this->get_completions($user_id, $criteriatype);

        if (empty($completions)) {
            return false;
        } elseif (count($completions) > 1) {
            print_error('multipleselfcompletioncriteria', 'completion');
        }

        return $completions[0];
    }
1125507
public function getIssuesBySeverity(string $severity): array
    {
        return array_values(array_filter($this->getIssues(), function(Issue $i) use ($severity) {
            return $i->getSeverity() === $severity;
        }));
    }
1042852
def _get_completions(self):
        """"""
        completions = []
        self.begidx = self.l_buffer.point
        self.endidx = self.l_buffer.point
        buf=self.l_buffer.line_buffer
        if self.completer:
            # get the string to complete
            while self.begidx > 0:
                self.begidx -= 1
                if buf[self.begidx] in self.completer_delims:
                    self.begidx += 1
                    break
            text = ensure_str(u''.join(buf[self.begidx:self.endidx]))
            log(u'complete text="%s"' % ensure_unicode(text))
            i = 0
            while 1:
                try:
                    r = ensure_unicode(self.completer(text, i))
                except IndexError:
                    break
                i += 1
                if r is None:
                    break
                elif r and r not in completions:
                    completions.append(r)
                else:
                    pass
            log(u'text completions=<%s>' % map(ensure_unicode, completions))
        if (self.complete_filesystem == "on") and not completions:
            # get the filename to complete
            while self.begidx > 0:
                self.begidx -= 1
                if buf[self.begidx] in u' \t\n':
                    self.begidx += 1
                    break
            text = ensure_str(u''.join(buf[self.begidx:self.endidx]))
            log(u'file complete text="%s"' % ensure_unicode(text))
            completions = map(ensure_unicode, glob.glob(os.path.expanduser(text) + '*'))
            if self.mark_directories == u'on':
                mc = []
                for f in completions:
                    if os.path.isdir(f):
                        mc.append(f + os.sep)
                    else:
                        mc.append(f)
                completions = mc
            log(u'fnames=<%s>' % map(ensure_unicode, completions))
        return completions
563416
public function get_details($completion) {
        $details = array();
        $details['type'] = get_string('datepassed', 'completion');
        $details['criteria'] = get_string('remainingenroleduntildate', 'completion');
        $details['requirement'] = userdate($this->timeend, '%d %B %Y');
        $details['status'] = '';

        return $details;
    }
601295
public function getCompletionDate($format = 'Y-m-d')
    {
        if ($this->completionDate instanceof \DateTime && $format !== null) {
            return $this->completionDate->format($format);
        }

        return $this->completionDate;
    }
1063606
public function complete($requestParams)
    {
        $options["headers"] = self::retrieveContentTypeHeader(self::CONTENT_TYPE_JSON);
        $requiredParams = array("object_type_id");
        return $this->client->request($requestParams, $this->_mainTaskEndpoint."/". self::TASK_COMPLETE, "post", $requiredParams, $options);
    }
88551
public function getPlatformRequirements($withDevReqs = false)
    {
        $lockData = $this->getLockData();
        $versionParser = new VersionParser();
        $requirements = array();

        if (!empty($lockData['platform'])) {
            $requirements = $versionParser->parseLinks(
                '__ROOT__',
                '1.0.0',
                'requires',
                isset($lockData['platform']) ? $lockData['platform'] : array()
            );
        }

        if ($withDevReqs && !empty($lockData['platform-dev'])) {
            $devRequirements = $versionParser->parseLinks(
                '__ROOT__',
                '1.0.0',
                'requires',
                isset($lockData['platform-dev']) ? $lockData['platform-dev'] : array()
            );

            $requirements = array_merge($requirements, $devRequirements);
        }

        return $requirements;
    }
170155
public function parse(Collection $completedProcesses): ResultCollection
    {
        $this->resultsCollection = new ResultCollection;

        foreach ($completedProcesses as $file => $processes) {
            $this->parseCompletedProcessesForFile($file, $processes);
        }

        return $this->resultsCollection;
    }
1191596
public function get_completed_criteria_sql() {
        global $DB;

        $join = '';
        $whereparts = array();
        $params = array();
        $rule = ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) ? ' OR ' : ' AND ';

        foreach ($this->params as $param) {
            if (is_numeric($param['field'])) {
                // This is a custom field.
                $idx = count($whereparts);
                $join .= " LEFT JOIN {user_info_data} uid{$idx} ON uid{$idx}.userid = u.id AND uid{$idx}.fieldid = :fieldid{$idx} ";
                $params["fieldid{$idx}"] = $param['field'];
                $whereparts[] = "uid{$idx}.id IS NOT NULL";
            } else {
                // This is a field from {user} table.
                if ($param['field'] == 'picture') {
                    // The picture field is numeric and requires special handling.
                    $whereparts[] = "u.{$param['field']} != 0";
                } else {
                    $whereparts[] = $DB->sql_isnotempty('u', "u.{$param['field']}", false, true);
                }
            }
        }

        if ($whereparts) {
            $where = " AND (" . implode($rule, $whereparts) . ")";
        } else {
            $where = '';
        }
        return array($join, $where, $params);
    }
533734
public function searchReportExecutions(ReportExecutionSearchCriteria $criteria)
    {
        $url = $this->makeUrl() . '?' . $criteria->toQueryParams();
        try {
            $response = $this->service->prepAndSend($url, array(200), 'GET', null, true);
        } catch (RESTRequestException $e) {
            if ($e->statusCode == 204) {
                return array();
            } else {
                throw $e;
            }
        }
        $result = array();
        $executions = json_decode($response);
        foreach ($executions->reportExecution as $reportExecution) {
            $result[] = ReportExecution::createFromJSON($reportExecution);
        }
        return $result;
    }