Skip to content

Commit

Permalink
MDL-68019 course: Performance improvement with component favourites
Browse files Browse the repository at this point in the history
Add the ability to get all/select itemtypes within a component
  • Loading branch information
peterRd authored and Peter Dias committed Feb 28, 2020
1 parent 392e270 commit b3b2d72
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
15 changes: 11 additions & 4 deletions course/classes/local/service/content_item_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,17 @@ private function get_content_favourites(string $prefix, \context_user $userconte

$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;
}
Expand Down
19 changes: 17 additions & 2 deletions favourites/classes/local/repository/favourite_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,30 @@ public function find_all(int $limitfrom = 0, int $limitnum = 0) : array {
/**
* 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.
* @throws \dml_exception if any database errors are encountered.
*/
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);
}

Expand Down
32 changes: 32 additions & 0 deletions favourites/classes/local/service/user_favourite_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,38 @@ public function find_favourites_by_type(string $component, string $itemtype, int
);
}

/**
* 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.
*
Expand Down

0 comments on commit b3b2d72

Please sign in to comment.