MDL-64057 core_favourites: add get_join_sql_by_type() to service layer
This provides a way for external queries to include information about favourited items.
This commit is contained in:
@@ -110,6 +110,51 @@ class user_favourite_service {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SQL required to include favourite information for a given component/itemtype combination.
|
||||
*
|
||||
* Generally, find_favourites_by_type() is the recommended way to fetch favourites.
|
||||
*
|
||||
* This method is used to include favourite information in external queries, for items identified by their
|
||||
* component and itemtype, matching itemid to the $joinitemid, and for the user to which this service is scoped.
|
||||
*
|
||||
* It uses a LEFT JOIN to preserve the original records. If you wish to restrict your records, please consider using a
|
||||
* "WHERE {$tablealias}.id IS NOT NULL" in your query.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* list($sql, $params) = $service->get_join_sql_by_type('core_message', 'message_conversations', 'myfavouritetablealias',
|
||||
* 'conv.id');
|
||||
* Results in $sql:
|
||||
* "LEFT JOIN {favourite} fav
|
||||
* ON fav.component = :favouritecomponent
|
||||
* AND fav.itemtype = :favouriteitemtype
|
||||
* AND fav.userid = 1234
|
||||
* AND fav.itemid = conv.id"
|
||||
* and $params:
|
||||
* ['favouritecomponent' => 'core_message', 'favouriteitemtype' => 'message_conversations']
|
||||
*
|
||||
* @param string $component the frankenstyle component name.
|
||||
* @param string $itemtype the type of the favourited item.
|
||||
* @param string $tablealias the desired alias for the favourites table.
|
||||
* @param string $joinitemid the table and column identifier which the itemid is joined to. E.g. conversation.id.
|
||||
* @return array the list of sql and params, in the format [$sql, $params].
|
||||
*/
|
||||
public function get_join_sql_by_type(string $component, string $itemtype, string $tablealias, string $joinitemid) : array {
|
||||
$sql = " LEFT JOIN {favourite} {$tablealias}
|
||||
ON {$tablealias}.component = :favouritecomponent
|
||||
AND {$tablealias}.itemtype = :favouriteitemtype
|
||||
AND {$tablealias}.userid = {$this->userid}
|
||||
AND {$tablealias}.itemid = {$joinitemid} ";
|
||||
|
||||
$params = [
|
||||
'favouritecomponent' => $component,
|
||||
'favouriteitemtype' => $itemtype,
|
||||
];
|
||||
|
||||
return [$sql, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a favourite item from an area and from within a context.
|
||||
*
|
||||
@@ -186,7 +231,7 @@ class user_favourite_service {
|
||||
* @param string $component the frankenstyle component name.
|
||||
* @param string $itemtype the type of the favourited item.
|
||||
* @param \context|null $context the context of the item which was favourited.
|
||||
* @return favourite|null
|
||||
* @return int
|
||||
*/
|
||||
public function count_favourites_by_type(string $component, string $itemtype, \context $context = null) {
|
||||
$criteria = [
|
||||
|
||||
@@ -429,4 +429,35 @@ class user_favourite_service_testcase extends advanced_testcase {
|
||||
// Gets counted if we include all contexts.
|
||||
$this->assertEquals(3, $service->count_favourites_by_type('core_course', 'course'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the join sql generated by get_join_sql_by_type is valid and can be used to include favourite information.
|
||||
*/
|
||||
public function test_get_join_sql_by_type() {
|
||||
global $DB;
|
||||
list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses();
|
||||
|
||||
// Get a user_favourite_service for the user.
|
||||
// We need to use a real (DB) repository, as we want to run the SQL.
|
||||
$repo = new \core_favourites\local\repository\favourite_repository();
|
||||
$service = new \core_favourites\local\service\user_favourite_service($user1context, $repo);
|
||||
|
||||
// Favourite the first course only.
|
||||
$service->create_favourite('core_course', 'course', $course1context->instanceid, $course1context);
|
||||
|
||||
// Generate the join snippet.
|
||||
list($favsql, $favparams) = $service->get_join_sql_by_type('core_course', 'course', 'favalias', 'c.id');
|
||||
|
||||
// Join against a simple select, including the 2 courses only.
|
||||
$params = ['courseid1' => $course1context->instanceid, 'courseid2' => $course2context->instanceid];
|
||||
$params = $params + $favparams;
|
||||
$records = $DB->get_records_sql("SELECT c.id, favalias.component
|
||||
FROM {course} c $favsql
|
||||
WHERE c.id = :courseid1 OR c.id = :courseid2", $params);
|
||||
|
||||
// Verify the favourite information is returned, but only for the favourited course.
|
||||
$this->assertCount(2, $records);
|
||||
$this->assertEquals('core_course', $records[$course1context->instanceid]->component);
|
||||
$this->assertEmpty($records[$course2context->instanceid]->component);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user