// (C) Copyright 2015 Martin Dougiamas // // 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 { Injectable } from '@angular/core'; import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; import { CoreUtilsProvider } from '@providers/utils/utils'; /** * Structure of offline ratings. */ export interface CoreRatingOfflineRating { component: string; ratingarea: string; contextlevel: string; instanceid: number; itemid: number; itemsetid: number; courseid: number; scaleid: number; rating: number; rateduserid: number; aggregation: number; } /** * Structure of item sets. */ export interface CoreRatingItemSet { component: string; ratingArea: string; contextLevel: string; instanceId: number; itemSetId: number; courseId: number; } /** * Service to handle offline data for rating. */ @Injectable() export class CoreRatingOfflineProvider { // Variables for database. static RATINGS_TABLE = 'rating_ratings'; protected siteSchema: CoreSiteSchema = { name: 'CoreRatingOfflineProvider', version: 1, tables: [ { name: CoreRatingOfflineProvider.RATINGS_TABLE, columns: [ { name: 'component', type: 'TEXT' }, { name: 'ratingarea', type: 'TEXT' }, { name: 'contextlevel', type: 'INTEGER', }, { name: 'instanceid', type: 'INTEGER' }, { name: 'itemid', type: 'INTEGER' }, { name: 'itemsetid', type: 'INTEGER' }, { name: 'courseid', type: 'INTEGER' }, { name: 'scaleid', type: 'INTEGER' }, { name: 'rating', type: 'INTEGER' }, { name: 'rateduserid', type: 'INTEGER' }, { name: 'aggregation', type: 'INTEGER' } ], primaryKeys: ['component', 'ratingarea', 'contextlevel', 'instanceid', 'itemid'] } ] }; constructor(private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider) { this.sitesProvider.registerSiteSchema(this.siteSchema); } /** * Get an offline rating. * * @param {string} contextLevel Context level: course, module, user, etc. * @param {numnber} instanceId Context instance id. * @param {string} component Component. Example: "mod_forum". * @param {string} ratingArea Rating area. Example: "post". * @param {number} itemId Item id. Example: forum post id. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved with the saved rating, rejected if not found. */ getRating(contextLevel: string, instanceId: number, component: string, ratingArea: string, itemId: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const conditions = { contextlevel: contextLevel, instanceid: instanceId, component: component, ratingarea: ratingArea, itemid: itemId }; return site.getDb().getRecord(CoreRatingOfflineProvider.RATINGS_TABLE, conditions); }); } /** * Add an offline rating. * * @param {string} component Component. Example: "mod_forum". * @param {string} ratingArea Rating area. Example: "post". * @param {string} contextLevel Context level: course, module, user, etc. * @param {numnber} instanceId Context instance id. * @param {number} itemId Item id. Example: forum post id. * @param {number} itemSetId Item set id. Example: forum discussion id. * @param {number} courseId Course id. * @param {number} scaleId Scale id. * @param {number} rating Rating value. Use CoreRatingProvider.UNSET_RATING to delete rating. * @param {number} ratedUserId Rated user id. * @param {number} aggregateMethod Aggregate method. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when the rating is saved. */ addRating(component: string, ratingArea: string, contextLevel: string, instanceId: number, itemId: number, itemSetId: number, courseId: number, scaleId: number, rating: number, ratedUserId: number, aggregateMethod: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const data: CoreRatingOfflineRating = { component: component, ratingarea: ratingArea, contextlevel: contextLevel, instanceid: instanceId, itemid: itemId, itemsetid: itemSetId, courseid: courseId, scaleid: scaleId, rating: rating, rateduserid: ratedUserId, aggregation: aggregateMethod }; return site.getDb().insertRecord(CoreRatingOfflineProvider.RATINGS_TABLE, data); }); } /** * Delete offline rating. * * @param {string} component Component. Example: "mod_forum". * @param {string} ratingArea Rating area. Example: "post". * @param {string} contextLevel Context level: course, module, user, etc. * @param {number} itemId Item id. Example: forum post id. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when the rating is saved. */ deleteRating(component: string, ratingArea: string, contextLevel: string, instanceId: number, itemId: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const conditions = { component: component, ratingarea: ratingArea, contextlevel: contextLevel, instanceid: instanceId, itemid: itemId }; return site.getDb().deleteRecords(CoreRatingOfflineProvider.RATINGS_TABLE, conditions); }); } /** * Get the list of item sets in a component or instance. * * @param {string} component Component. Example: "mod_forum". * @param {string} ratingArea Rating Area. Example: "post". * @param {string} [contextLevel] Context level: course, module, user, etc. * @param {numnber} [instanceId] Context instance id. * @param {number} [itemSetId] Item set id. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved with the list of item set ids. */ getItemSets(component: string, ratingArea: string, contextLevel?: string, instanceId?: number, itemSetId?: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const fields = 'DISTINCT contextlevel, instanceid, itemsetid, courseid'; const conditions: any = { component, ratingarea: ratingArea }; if (contextLevel != null && instanceId != null) { conditions.contextlevel = contextLevel; conditions.instanceId = instanceId; } if (itemSetId != null) { conditions.itemSetId = itemSetId; } return site.getDb().getRecords(CoreRatingOfflineProvider.RATINGS_TABLE, conditions, undefined, fields) .then((records: any[]) => { return records.map((record) => { return { component, ratingArea, contextLevel: record.contextlevel, instanceId: record.instanceid, itemSetId: record.itemsetid, courseId: record.courseid }; }); }); }); } /** * Get offline ratings of an item set. * * @param {string} component Component. Example: "mod_forum". * @param {string} ratingArea Rating Area. Example: "post". * @param {string} contextLevel Context level: course, module, user, etc. * @param {number} itemId Item id. Example: forum post id. * @param {number} itemSetId Item set id. Example: forum discussion id. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved with the list of ratings. */ getRatings(component: string, ratingArea: string, contextLevel: string, instanceId: number, itemSetId: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const conditions = { component, ratingarea: ratingArea, contextlevel: contextLevel, instanceid: instanceId, itemsetid: itemSetId }; return site.getDb().getRecords(CoreRatingOfflineProvider.RATINGS_TABLE, conditions); }); } /** * Return whether a component, instance or item set has offline ratings. * * @param {string} component Component. Example: "mod_forum". * @param {string} ratingArea Rating Area. Example: "post". * @param {string} [contextLevel] Context level: course, module, user, etc. * @param {number} [instanceId] Context instance id. * @param {number} [itemSetId] Item set id. Example: forum discussion id. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved with a boolean. */ hasRatings(component: string, ratingArea: string, contextLevel?: string, instanceId?: number, itemSetId?: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const conditions: any = { component, ratingarea: ratingArea }; if (contextLevel != null && instanceId != null) { conditions.contextlevel = contextLevel; conditions.instanceId = instanceId; } if (itemSetId != null) { conditions.itemsetid = itemSetId; } return this.utils.promiseWorks(site.getDb().recordExists(CoreRatingOfflineProvider.RATINGS_TABLE, conditions)); }); } }