MDL-68019 course: Performance improvement with component favourites

Add the ability to get all/select itemtypes within a component
This commit is contained in:
Peter 2020-02-26 15:01:04 +08:00 committed by Peter Dias
parent 392e270c93
commit b3b2d72c1e
3 changed files with 60 additions and 6 deletions

View File

@ -141,10 +141,17 @@ class content_item_service {
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
$favourites = [];
foreach ($itemtypes as $itemtype) {
$favs = $ufservice->find_favourites_by_type(self::COMPONENT, $itemtype);
$favobj = (object) ['itemtype' => $itemtype, 'ids' => array_column($favs, 'itemid')];
$favourites[] = $favobj;
$favs = $ufservice->find_all_favourites(self::COMPONENT, $itemtypes);
$favsreduced = array_reduce($favs, function($carry, $item) {
$carry[$item->itemtype][$item->itemid] = 0;
return $carry;
}, []);
foreach ($itemtypes as $type) {
$favourites[] = (object) [
'itemtype' => $type,
'ids' => isset($favsreduced[$type]) ? array_keys($favsreduced[$type]) : []
];
}
return $favourites;
}

View File

@ -184,7 +184,7 @@ class favourite_repository implements favourite_repository_interface {
/**
* Return all items matching the supplied criteria (a [key => value,..] list).
*
* @param array $criteria the list of key/value criteria pairs.
* @param array $criteria the list of key/value(s) criteria pairs.
* @param int $limitfrom optional pagination control for returning a subset of records, starting at this point.
* @param int $limitnum optional pagination control for returning a subset comprising this many records.
* @return array the list of favourites matching the criteria.
@ -192,7 +192,22 @@ class favourite_repository implements favourite_repository_interface {
*/
public function find_by(array $criteria, int $limitfrom = 0, int $limitnum = 0) : array {
global $DB;
$records = $DB->get_records($this->favouritetable, $criteria, '', '*', $limitfrom, $limitnum);
$conditions = [];
$params = [];
foreach ($criteria as $field => $value) {
if (is_array($value) && count($value)) {
list($insql, $inparams) = $DB->get_in_or_equal($value, SQL_PARAMS_NAMED);
$conditions[] = "$field $insql";
$params = array_merge($params, $inparams);
} else {
$conditions[] = "$field = :$field";
$params = array_merge($params, [$field => $value]);
}
}
$records = $DB->get_records_select($this->favouritetable, implode(' AND ', $conditions), $params,
'', '*', $limitfrom, $limitnum);
return $this->get_list_of_favourites_from_records($records);
}

View File

@ -110,6 +110,38 @@ class user_favourite_service {
);
}
/**
* Find a list of favourites, by multiple types within a component.
*
* E.g. "Find all favourites in the activity chooser" might result in:
* $favcourses = find_all_favourites('core_course', ['contentitem_mod_assign','contentitem_mod_assignment');
*
* @param string $component the frankenstyle component name.
* @param array $itemtypes optional the type of the favourited item.
* @param int $limitfrom optional pagination control for returning a subset of records, starting at this point.
* @param int $limitnum optional pagination control for returning a subset comprising this many records.
* @return array the list of favourites found.
* @throws \moodle_exception if the component name is invalid, or if the repository encounters any errors.
*/
public function find_all_favourites(string $component, array $itemtypes = [], int $limitfrom = 0, int $limitnum = 0) : array {
if (!in_array($component, \core_component::get_component_names())) {
throw new \moodle_exception("Invalid component name '$component'");
}
$params = [
'userid' => $this->userid,
'component' => $component,
];
if ($itemtypes) {
$params['itemtype'] = $itemtypes;
}
return $this->repo->find_by(
$params,
$limitfrom,
$limitnum
);
}
/**
* Returns the SQL required to include favourite information for a given component/itemtype combination.
*