2021-03-08 12:45:51 +01:00

272 lines
8.8 KiB
TypeScript

// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { ContextLevel } from '@/core/constants';
import { Injectable } from '@angular/core';
import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { CoreRatingDBPrimaryData, CoreRatingDBRecord, RATINGS_TABLE } from './database/rating';
/**
* Structure of item sets.
*/
export interface CoreRatingItemSet {
component: string;
ratingArea: string;
contextLevel: ContextLevel;
instanceId: number;
itemSetId: number;
courseId?: number;
}
/**
* Service to handle offline data for rating.
*/
@Injectable( { providedIn: 'root' })
export class CoreRatingOfflineProvider {
/**
* Get an offline rating.
*
* @param contextLevel Context level: course, module, user, etc.
* @param instanceId Context instance id.
* @param component Component. Example: "mod_forum".
* @param ratingArea Rating area. Example: "post".
* @param itemId Item id. Example: forum post id.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the saved rating, rejected if not found.
*/
async getRating(
contextLevel: ContextLevel,
instanceId: number,
component: string,
ratingArea: string,
itemId: number,
siteId?: string,
): Promise<CoreRatingDBRecord> {
const site = await CoreSites.getSite(siteId);
const conditions: CoreRatingDBPrimaryData = {
contextlevel: contextLevel,
instanceid: instanceId,
component: component,
ratingarea: ratingArea,
itemid: itemId,
};
return site.getDb().getRecord(RATINGS_TABLE, conditions);
}
/**
* Add an offline rating.
*
* @param component Component. Example: "mod_forum".
* @param ratingArea Rating area. Example: "post".
* @param contextLevel Context level: course, module, user, etc.
* @param instanceId Context instance id.
* @param itemId Item id. Example: forum post id.
* @param itemSetId Item set id. Example: forum discussion id.
* @param courseId Course id.
* @param scaleId Scale id.
* @param rating Rating value. Use CoreRatingProvider.UNSET_RATING to delete rating.
* @param ratedUserId Rated user id.
* @param aggregateMethod Aggregate method.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when the rating is saved.
*/
async addRating(
component: string,
ratingArea: string,
contextLevel: ContextLevel,
instanceId: number,
itemId: number,
itemSetId: number,
courseId: number,
scaleId: number,
rating: number,
ratedUserId: number,
aggregateMethod: number,
siteId?: string,
): Promise<void> {
const site = await CoreSites.getSite(siteId);
const data: CoreRatingDBRecord = {
component: component,
ratingarea: ratingArea,
contextlevel: contextLevel,
instanceid: instanceId,
itemid: itemId,
itemsetid: itemSetId,
courseid: courseId,
scaleid: scaleId,
rating: rating,
rateduserid: ratedUserId,
aggregation: aggregateMethod,
};
await site.getDb().insertRecord(RATINGS_TABLE, data);
}
/**
* Delete offline rating.
*
* @param component Component. Example: "mod_forum".
* @param ratingArea Rating area. Example: "post".
* @param contextLevel Context level: course, module, user, etc.
* @param itemId Item id. Example: forum post id.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when the rating is saved.
*/
async deleteRating(
component: string,
ratingArea: string,
contextLevel: ContextLevel,
instanceId: number,
itemId: number,
siteId?: string,
): Promise<void> {
const site = await CoreSites.getSite(siteId);
const conditions: CoreRatingDBPrimaryData = {
component: component,
ratingarea: ratingArea,
contextlevel: contextLevel,
instanceid: instanceId,
itemid: itemId,
};
await site.getDb().deleteRecords(RATINGS_TABLE, conditions);
}
/**
* Get the list of item sets in a component or instance.
*
* @param component Component. Example: "mod_forum".
* @param ratingArea Rating Area. Example: "post".
* @param contextLevel Context level: course, module, user, etc.
* @param instanceId Context instance id.
* @param itemSetId Item set id.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the list of item set ids.
*/
async getItemSets(
component: string,
ratingArea: string,
contextLevel?: ContextLevel,
instanceId?: number,
itemSetId?: number,
siteId?: string,
): Promise<CoreRatingItemSet[]> {
const site = await CoreSites.getSite(siteId);
const fields = 'DISTINCT contextlevel, instanceid, itemsetid, courseid';
const conditions: Partial<CoreRatingDBRecord> = {
component,
ratingarea: ratingArea,
};
if (contextLevel && instanceId) {
conditions.contextlevel = contextLevel;
conditions.instanceid = instanceId;
}
if (itemSetId) {
conditions.itemsetid = itemSetId;
}
const records = await site.getDb().getRecords<CoreRatingDBRecord>(RATINGS_TABLE, conditions, undefined, fields);
return records.map((record) => ({
component,
ratingArea,
contextLevel: record.contextlevel,
instanceId: record.instanceid,
itemSetId: record.itemsetid,
courseId: record.courseid,
}));
}
/**
* Get offline ratings of an item set.
*
* @param component Component. Example: "mod_forum".
* @param ratingArea Rating Area. Example: "post".
* @param contextLevel Context level: course, module, user, etc.
* @param itemId Item id. Example: forum post id.
* @param itemSetId Item set id. Example: forum discussion id.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the list of ratings.
*/
async getRatings(
component: string,
ratingArea: string,
contextLevel: ContextLevel,
instanceId: number,
itemSetId: number,
siteId?: string,
): Promise<CoreRatingDBRecord[]> {
const site = await CoreSites.getSite(siteId);
const conditions: Partial<CoreRatingDBRecord> = {
component,
ratingarea: ratingArea,
contextlevel: contextLevel,
instanceid: instanceId,
itemsetid: itemSetId,
};
return site.getDb().getRecords(RATINGS_TABLE, conditions);
}
/**
* Return whether a component, instance or item set has offline ratings.
*
* @param component Component. Example: "mod_forum".
* @param ratingArea Rating Area. Example: "post".
* @param contextLevel Context level: course, module, user, etc.
* @param instanceId Context instance id.
* @param itemSetId Item set id. Example: forum discussion id.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with a boolean.
*/
async hasRatings(
component: string,
ratingArea: string,
contextLevel?: ContextLevel,
instanceId?: number,
itemSetId?: number,
siteId?: string,
): Promise<boolean> {
const site = await CoreSites.getSite(siteId);
const conditions: Partial<CoreRatingDBRecord> = {
component,
ratingarea: ratingArea,
};
if (contextLevel && instanceId) {
conditions.contextlevel = contextLevel;
conditions.instanceid = instanceId;
}
if (itemSetId) {
conditions.itemsetid = itemSetId;
}
return CoreUtils.promiseWorks(site.getDb().recordExists(RATINGS_TABLE, conditions));
}
}
export const CoreRatingOffline = makeSingleton(CoreRatingOfflineProvider);