MOBILE-2856 data: Helper functions for fetching entries

main
Albert Gasset 2019-04-10 17:39:26 +02:00
parent 3d0e7d14e1
commit 6b0f08695f
6 changed files with 222 additions and 213 deletions

View File

@ -20,11 +20,9 @@ import { CoreGroupsProvider, CoreGroupInfo } from '@providers/groups';
import { CoreCourseModuleMainActivityComponent } from '@core/course/classes/main-activity-component';
import { CoreCommentsProvider } from '@core/comments/providers/comments';
import { CoreRatingProvider } from '@core/rating/providers/rating';
import { CoreRatingOfflineProvider } from '@core/rating/providers/offline';
import { CoreRatingSyncProvider } from '@core/rating/providers/sync';
import { AddonModDataProvider } from '../../providers/data';
import { AddonModDataHelperProvider } from '../../providers/helper';
import { AddonModDataOfflineProvider } from '../../providers/offline';
import { AddonModDataSyncProvider } from '../../providers/sync';
import { AddonModDataComponentsModule } from '../components.module';
import { AddonModDataPrefetchHandler } from '../../providers/prefetch-handler';
@ -65,8 +63,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
advanced: []
};
hasNextPage = false;
offlineActions: any;
offlineEntries: any;
entriesRendered = '';
extraImports = [AddonModDataComponentsModule];
jsData;
@ -81,12 +77,19 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
protected ratingOfflineObserver: any;
protected ratingSyncObserver: any;
constructor(injector: Injector, private dataProvider: AddonModDataProvider, private dataHelper: AddonModDataHelperProvider,
private dataOffline: AddonModDataOfflineProvider, @Optional() content: Content,
private prefetchHandler: AddonModDataPrefetchHandler, private timeUtils: CoreTimeUtilsProvider,
private groupsProvider: CoreGroupsProvider, private commentsProvider: CoreCommentsProvider,
private modalCtrl: ModalController, private utils: CoreUtilsProvider, protected navCtrl: NavController,
private ratingOffline: CoreRatingOfflineProvider) {
constructor(
injector: Injector,
@Optional() content: Content,
private dataProvider: AddonModDataProvider,
private dataHelper: AddonModDataHelperProvider,
private prefetchHandler: AddonModDataPrefetchHandler,
private timeUtils: CoreTimeUtilsProvider,
private groupsProvider: CoreGroupsProvider,
private commentsProvider: CoreCommentsProvider,
private modalCtrl: ModalController,
private utils: CoreUtilsProvider,
protected navCtrl: NavController) {
super(injector, content);
// Refresh entries on change.
@ -233,8 +236,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.selectedGroup = groupInfo.groups[0].id;
}
}
return this.fetchOfflineEntries();
});
}).then(() => {
return this.dataProvider.getFields(this.data.id).then((fields) => {
@ -270,21 +271,19 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
// Update values for current group.
this.access.canaddentry = accessData.canaddentry;
if (this.search.searching) {
const text = this.search.searchingAdvanced ? undefined : this.search.text,
advanced = this.search.searchingAdvanced ? this.search.advanced : undefined;
const search = this.search.searching && !this.search.searchingAdvanced ? this.search.text : undefined;
const advSearch = this.search.searching && this.search.searchingAdvanced ? this.search.advanced : undefined;
return this.dataProvider.searchEntries(this.data.id, this.selectedGroup, text, advanced, this.search.sortBy,
this.search.sortDirection, this.search.page);
} else {
return this.dataProvider.getEntries(this.data.id, this.selectedGroup, this.search.sortBy, this.search.sortDirection,
this.search.page);
}
return this.dataHelper.fetchEntries(this.data, this.fieldsArray, this.selectedGroup, search, advSearch,
this.search.sortBy, this.search.sortDirection, this.search.page);
}).then((entries) => {
const numEntries = (entries && entries.entries && entries.entries.length) || 0;
this.isEmpty = !numEntries && !Object.keys(this.offlineActions).length && !Object.keys(this.offlineEntries).length;
const numEntries = entries.entries.length;
const numOfflineEntries = entries.offlineEntries.length;
this.isEmpty = !numEntries && !entries.offlineEntries.length;
this.hasNextPage = numEntries >= AddonModDataProvider.PER_PAGE && ((this.search.page + 1) *
AddonModDataProvider.PER_PAGE) < entries.totalcount;
this.hasOffline = entries.hasOfflineActions;
this.hasOfflineRatings = entries.hasOfflineRatings;
this.entriesRendered = '';
if (typeof entries.maxcount != 'undefined') {
@ -298,76 +297,40 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
}
if (!this.isEmpty) {
const siteInfo = this.sitesProvider.getCurrentSite().getInfo(),
promises = [];
this.entries = entries.offlineEntries.concat(entries.entries);
this.utils.objectToArray(this.offlineEntries).forEach((offlineActions) => {
const offlineEntry = offlineActions.find((offlineEntry) => offlineEntry.action == 'add');
let entriesHTML = this.data.listtemplateheader || '';
if (offlineEntry) {
const entry = {
id: offlineEntry.entryid,
canmanageentry: true,
approved: !this.data.approval || this.data.manageapproved,
dataid: offlineEntry.dataid,
groupid: offlineEntry.groupid,
timecreated: -offlineEntry.entryid,
timemodified: -offlineEntry.entryid,
userid: siteInfo.userid,
fullname: siteInfo.fullname,
contents: {}
};
// Get first entry from the whole list.
if (!this.search.searching || !this.firstEntry) {
this.firstEntry = this.entries[0].id;
}
if (offlineActions.length > 0) {
promises.push(this.dataHelper.applyOfflineActions(entry, offlineActions, this.fieldsArray));
} else {
promises.push(Promise.resolve(entry));
}
}
const template = this.data.listtemplate || this.dataHelper.getDefaultTemplate('list', this.fieldsArray);
const entriesById = {};
this.entries.forEach((entry, index) => {
entriesById[entry.id] = entry;
const actions = this.dataHelper.getActions(this.data, this.access, entry);
const offset = this.search.searching ? undefined :
this.search.page * AddonModDataProvider.PER_PAGE + index - numOfflineEntries;
entriesHTML += this.dataHelper.displayShowFields(template, this.fieldsArray, entry, offset, 'list', actions);
});
entriesHTML += this.data.listtemplatefooter || '';
entries.entries.forEach((entry) => {
if (typeof this.offlineActions[entry.id] != 'undefined') {
promises.push(this.dataHelper.applyOfflineActions(entry, this.offlineActions[entry.id], this.fieldsArray));
} else {
promises.push(Promise.resolve(entry));
}
});
this.entriesRendered = entriesHTML;
return Promise.all(promises).then((entries) => {
this.entries = entries;
let entriesHTML = this.data.listtemplateheader || '';
// Get first entry from the whole list.
if (entries && entries[0] && (!this.search.searching || !this.firstEntry)) {
this.firstEntry = entries[0].id;
}
const template = this.data.listtemplate || this.dataHelper.getDefaultTemplate('list', this.fieldsArray);
const entriesById = {};
entries.forEach((entry, index) => {
entriesById[entry.id] = entry;
const actions = this.dataHelper.getActions(this.data, this.access, entry);
const offset = this.search.page * AddonModDataProvider.PER_PAGE + index;
entriesHTML += this.dataHelper.displayShowFields(template, this.fieldsArray, entry, offset, 'list',
actions);
});
entriesHTML += this.data.listtemplatefooter || '';
this.entriesRendered = entriesHTML;
// Pass the input data to the component.
this.jsData = {
fields: this.fields,
entries: entriesById,
data: this.data,
gotoEntry: this.gotoEntry.bind(this)
};
});
// Pass the input data to the component.
this.jsData = {
fields: this.fields,
entries: entriesById,
data: this.data,
module: this.module,
group: this.selectedGroup,
gotoEntry: this.gotoEntry.bind(this)
};
} else if (!this.search.searching) {
// Empty and no searching.
this.canSearch = false;
@ -476,42 +439,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.navCtrl.push('AddonModDataEntryPage', params);
}
/**
* Fetch offline entries.
*
* @return {Promise<any>} Resolved then done.
*/
protected fetchOfflineEntries(): Promise<any> {
// Check if there are entries stored in offline.
return this.dataOffline.getDatabaseEntries(this.data.id).then((offlineEntries) => {
this.hasOffline = !!offlineEntries.length;
this.offlineActions = {};
this.offlineEntries = {};
// Only show offline entries on first page.
if (this.search.page == 0 && this.hasOffline) {
offlineEntries.forEach((entry) => {
if (entry.entryid > 0) {
if (typeof this.offlineActions[entry.entryid] == 'undefined') {
this.offlineActions[entry.entryid] = [];
}
this.offlineActions[entry.entryid].push(entry);
} else {
if (typeof this.offlineActions[entry.entryid] == 'undefined') {
this.offlineEntries[entry.entryid] = [];
}
this.offlineEntries[entry.entryid].push(entry);
}
});
}
}).then(() => {
return this.ratingOffline.hasRatings('mod_data', 'entry', 'module', this.data.coursemodule).then((hasRatings) => {
this.hasOfflineRatings = hasRatings;
});
});
}
/**
* Performs the sync of the activity.
*

View File

@ -45,7 +45,6 @@ export class AddonModDataEditPage {
protected data: any;
protected entryId: number;
protected entry: any;
protected offlineActions = [];
protected fields = {};
protected fieldsArray = [];
protected siteId: string;
@ -145,28 +144,14 @@ export class AddonModDataEditPage {
});
}
}).then(() => {
return this.dataOffline.getEntryActions(this.data.id, this.entryId);
}).then((actions) => {
this.offlineActions = actions;
return this.dataProvider.getFields(this.data.id);
}).then((fieldsData) => {
this.fieldsArray = fieldsData;
this.fields = this.utils.arrayToObject(fieldsData, 'id');
return this.dataHelper.getEntry(this.data, this.entryId, this.offlineActions);
return this.dataHelper.fetchEntry(this.data, fieldsData, this.entryId);
}).then((entry) => {
if (entry) {
entry = entry.entry;
} else {
entry = {
contents: {}
};
}
return this.dataHelper.applyOfflineActions(entry, this.offlineActions, this.fieldsArray);
}).then((entryData) => {
this.entry = entryData;
this.entry = entry.entry;
this.editFormRender = this.displayEditFields();
}).catch((message) => {

View File

@ -9,7 +9,7 @@
</ion-refresher>
<core-loading [hideUntil]="entryLoaded && (isPullingToRefresh || !renderingEntry && !loadingRating && !loadingComments)">
<!-- Database entries found to be synchronized -->
<div class="core-warning-card" icon-start *ngIf="hasOffline">
<div class="core-warning-card" icon-start *ngIf="entry && entry.hasOffline">
<ion-icon name="warning"></ion-icon>
{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}
</div>
@ -31,7 +31,7 @@
<core-rating-rate *ngIf="data && entry && ratingInfo && (!data.approval || entry.approved)" [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="data.coursemodule" [itemId]="entry.id" [itemSetId]="0" [courseId]="courseId" [aggregateMethod]="data.assessed" [scaleId]="data.scale" [userId]="entry.userid" (onLoading)="setLoadingRating($event)" (onUpdate)="ratingUpdated()"></core-rating-rate>
<core-rating-aggregate *ngIf="data && entry && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="data.coursemodule" [itemId]="entry.id" [courseId]="courseId" [aggregateMethod]="data.assessed" [scaleId]="data.scale"></core-rating-aggregate>
<ion-item *ngIf="data && entry">
<ion-item *ngIf="data && entry && entry.id > 0">
<core-comments contextLevel="module" [instanceId]="data.coursemodule" component="mod_data" [itemId]="entry.id" area="database_entry" [displaySpinner]="false" (onLoading)="setLoadingComments($event)"></core-comments>
</ion-item>

View File

@ -23,7 +23,6 @@ import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreRatingInfo } from '@core/rating/providers/rating';
import { AddonModDataProvider } from '../../providers/data';
import { AddonModDataHelperProvider } from '../../providers/helper';
import { AddonModDataOfflineProvider } from '../../providers/offline';
import { AddonModDataSyncProvider } from '../../providers/sync';
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
import { AddonModDataComponentsModule } from '../../components/components.module';
@ -46,6 +45,7 @@ export class AddonModDataEntryPage implements OnDestroy {
protected syncObserver: any; // It will observe the sync auto event.
protected entryChangedObserver: any; // It will observe the changed entry event.
protected fields = {};
protected fieldsArray = [];
title = '';
moduleName = 'data';
@ -56,8 +56,6 @@ export class AddonModDataEntryPage implements OnDestroy {
loadingRating = false;
selectedGroup = 0;
entry: any;
offlineActions = [];
hasOffline = false;
previousOffset: number;
nextOffset: number;
access: any;
@ -74,7 +72,7 @@ export class AddonModDataEntryPage implements OnDestroy {
constructor(params: NavParams, protected utils: CoreUtilsProvider, protected groupsProvider: CoreGroupsProvider,
protected domUtils: CoreDomUtilsProvider, protected fieldsDelegate: AddonModDataFieldsDelegate,
protected courseProvider: CoreCourseProvider, protected dataProvider: AddonModDataProvider,
protected dataOffline: AddonModDataOfflineProvider, protected dataHelper: AddonModDataHelperProvider,
protected dataHelper: AddonModDataHelperProvider,
sitesProvider: CoreSitesProvider, protected navCtrl: NavController, protected eventsProvider: CoreEventsProvider,
private cdr: ChangeDetectorRef) {
this.module = params.get('module') || {};
@ -131,8 +129,6 @@ export class AddonModDataEntryPage implements OnDestroy {
* @return {Promise<any>} Resolved when done.
*/
protected fetchEntryData(refresh?: boolean, isPtr?: boolean): Promise<any> {
let fieldsArray;
this.isPullingToRefresh = isPtr;
return this.dataProvider.getDatabase(this.courseId, this.module.id).then((data) => {
@ -155,32 +151,22 @@ export class AddonModDataEntryPage implements OnDestroy {
this.selectedGroup = groupInfo.groups[0].id;
}
}
return this.dataOffline.getEntryActions(this.data.id, this.entryId);
});
}).then((actions) => {
this.offlineActions = actions;
this.hasOffline = !!actions.length;
}).then(() => {
return this.dataProvider.getFields(this.data.id).then((fieldsData) => {
this.fields = this.utils.arrayToObject(fieldsData, 'id');
this.fieldsArray = fieldsData;
return this.dataHelper.getEntry(this.data, this.entryId, this.offlineActions);
return this.dataHelper.fetchEntry(this.data, fieldsData, this.entryId);
});
}).then((entry) => {
this.entry = entry.entry;
this.ratingInfo = entry.ratinginfo;
entry = entry.entry;
fieldsArray = this.utils.objectToArray(this.fields);
return this.dataHelper.applyOfflineActions(entry, this.offlineActions, fieldsArray);
}).then((entryData) => {
this.entry = entryData;
const actions = this.dataHelper.getActions(this.data, this.access, this.entry);
const templte = this.data.singletemplate || this.dataHelper.getDefaultTemplate('single', fieldsArray);
this.entryHtml = this.dataHelper.displayShowFields(templte, fieldsArray, this.entry, this.offset, 'show', actions);
const templte = this.data.singletemplate || this.dataHelper.getDefaultTemplate('single', this.fieldsArray);
this.entryHtml = this.dataHelper.displayShowFields(templte, this.fieldsArray, this.entry, this.offset, 'show', actions);
this.showComments = actions.comments;
const entries = {};

View File

@ -19,7 +19,9 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
import { AddonModDataFieldsDelegate } from './fields-delegate';
import { AddonModDataOfflineProvider, AddonModDataOfflineAction } from './offline';
import { AddonModDataProvider, AddonModDataEntry, AddonModDataEntryFields } from './data';
import { AddonModDataProvider, AddonModDataEntry, AddonModDataEntryFields, AddonModDataEntries } from './data';
import { CoreRatingInfo } from '@core/rating/providers/rating';
import { CoreRatingOfflineProvider } from '@core/rating/providers/offline';
/**
* Service that provides helper functions for datas.
@ -30,7 +32,7 @@ export class AddonModDataHelperProvider {
constructor(private sitesProvider: CoreSitesProvider, protected dataProvider: AddonModDataProvider,
private translate: TranslateService, private fieldsDelegate: AddonModDataFieldsDelegate,
private dataOffline: AddonModDataOfflineProvider, private fileUploaderProvider: CoreFileUploaderProvider,
private textUtils: CoreTextUtilsProvider) { }
private textUtils: CoreTextUtilsProvider, private ratingOffline: CoreRatingOfflineProvider) { }
/**
* Returns the record with the offline actions applied.
@ -156,6 +158,153 @@ export class AddonModDataHelperProvider {
return template;
}
/**
* Get online and offline entries, or search entries.
*
* @param {any} data Database object.
* @param {any[]} fields The fields that define the contents.
* @param {number} [groupId=0] Group ID.
* @param {string} [search] Search text. It will be used if advSearch is not defined.
* @param {any[]} [advSearch] Advanced search data.
* @param {string} [sort=0] Sort the records by this field id, reserved ids are:
* 0: timeadded
* -1: firstname
* -2: lastname
* -3: approved
* -4: timemodified.
* Empty for using the default database setting.
* @param {string} [order=DESC] The direction of the sorting: 'ASC' or 'DESC'.
* Empty for using the default database setting.
* @param {number} [page=0] Page of records to return.
* @param {number} [perPage=PER_PAGE] Records per page to return. Default on PER_PAGE.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<AddonModDataEntries>} Promise resolved when the database is retrieved.
*/
fetchEntries(data: any, fields: any[], groupId: number = 0, search?: string, advSearch?: any[], sort: string = '0',
order: string = 'DESC', page: number = 0, perPage: number = AddonModDataProvider.PER_PAGE, siteId?: string):
Promise<AddonModDataEntries> {
return this.sitesProvider.getSite(siteId).then((site) => {
const offlineActions = {};
const result: AddonModDataEntries = {
entries: [],
totalcount: 0,
offlineEntries: []
};
const offlinePromise = this.dataOffline.getDatabaseEntries(data.id, site.id).then((actions) => {
result.hasOfflineActions = !!actions.length;
actions.forEach((action) => {
if (typeof offlineActions[action.entryid] == 'undefined') {
offlineActions[action.entryid] = [];
}
offlineActions[action.entryid].push(action);
// We only display new entries in the first page when not searching.
if (action.action == 'add' && page == 0 && !search && !advSearch &&
(!action.groupid || !groupId || action.groupid == groupId)) {
result.offlineEntries.push({
id: action.entryid,
canmanageentry: true,
approved: !data.approval || data.manageapproved,
dataid: data.id,
groupid: action.groupid,
timecreated: -action.entryid,
timemodified: -action.entryid,
userid: site.getUserId(),
fullname: site.getInfo().fullname,
contents: {}
});
}
});
// Sort offline entries by creation time.
result.offlineEntries.sort((entry1, entry2) => entry2.timecreated - entry1.timecreated);
});
const ratingsPromise = this.ratingOffline.hasRatings('mod_data', 'entry', 'module', data.coursemodule)
.then((hasRatings) => {
result.hasOfflineRatings = hasRatings;
});
let fetchPromise: Promise<void>;
if (search || advSearch) {
fetchPromise = this.dataProvider.searchEntries(data.id, groupId, search, advSearch, sort, order, page, perPage,
site.id).then((fetchResult) => {
result.entries = fetchResult.entries;
result.totalcount = fetchResult.totalcount;
result.maxcount = fetchResult.maxcount;
});
} else {
fetchPromise = this.dataProvider.getEntries(data.id, groupId, sort, order, page, perPage, false, false, site.id)
.then((fetchResult) => {
result.entries = fetchResult.entries;
result.totalcount = fetchResult.totalcount;
});
}
return Promise.all([offlinePromise, ratingsPromise, fetchPromise]).then(() => {
// Apply offline actions to online and offline entries.
const promises = [];
result.entries.forEach((entry) => {
promises.push(this.applyOfflineActions(entry, offlineActions[entry.id] || [], fields));
});
result.offlineEntries.forEach((entry) => {
promises.push(this.applyOfflineActions(entry, offlineActions[entry.id] || [], fields));
});
return Promise.all(promises);
}).then(() => {
return result;
});
});
}
/**
* Fetch an online or offline entry.
*
* @param {any} data Database.
* @param {any[]} fields List of database fields.
* @param {number} entryId Entry ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<{entry: AddonModDataEntry, ratinginfo?: CoreRatingInfo}>} Promise resolved with the entry.
*/
fetchEntry(data: any, fields: any[], entryId: number, siteId?: string):
Promise<{entry: AddonModDataEntry, ratinginfo?: CoreRatingInfo}> {
return this.sitesProvider.getSite(siteId).then((site) => {
return this.dataOffline.getEntryActions(data.id, entryId, site.id).then((offlineActions) => {
let promise: Promise<{entry: AddonModDataEntry, ratinginfo?: CoreRatingInfo}>;
if (entryId > 0) {
// Online entry.
promise = this.dataProvider.getEntry(data.id, entryId, false, site.id);
} else {
// Offline entry or new entry.
promise = Promise.resolve({
entry: {
id: entryId,
userid: site.getUserId(),
groupid: 0,
dataid: data.id,
timecreated: -entryId,
timemodified: -entryId,
approved: !data.approval || data.manageapproved,
canmanageentry: true,
fullname: site.getInfo().fullname,
contents: [],
}
});
}
return promise.then((response) => {
return this.applyOfflineActions(response.entry, offlineActions, fields).then(() => {
return response;
});
});
});
});
}
/**
* Returns an object with all the actions that the user can do over the record.
*
@ -352,45 +501,6 @@ export class AddonModDataHelperProvider {
});
}
/**
* Get an online or offline entry.
*
* @param {any} data Database.
* @param {number} entryId Entry ID.
* @param {any} [offlineActions] Offline data with the actions done. Required for offline entries.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved with the entry.
*/
getEntry(data: any, entryId: number, offlineActions?: any, siteId?: string): Promise<any> {
if (entryId > 0) {
// It's an online entry, get it from WS.
return this.dataProvider.getEntry(data.id, entryId, false, siteId);
}
// It's an offline entry, search it in the offline actions.
return this.sitesProvider.getSite(siteId).then((site) => {
const offlineEntry = offlineActions.find((offlineAction) => offlineAction.action == 'add');
if (offlineEntry) {
const siteInfo = site.getInfo();
return {entry: {
id: offlineEntry.entryid,
canmanageentry: true,
approved: !data.approval || data.manageapproved,
dataid: offlineEntry.dataid,
groupid: offlineEntry.groupid,
timecreated: -offlineEntry.entryid,
timemodified: -offlineEntry.entryid,
userid: siteInfo.userid,
fullname: siteInfo.fullname,
contents: {}
}
};
}
});
}
/**
* Get a list of stored attachment files for a new entry. See $mmaModDataHelper#storeFiles.
*

View File

@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreFileProvider } from '@providers/file';
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
import { SQLiteDB } from '@classes/sqlitedb';
@ -101,7 +102,8 @@ export class AddonModDataOfflineProvider {
};
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider,
private fileProvider: CoreFileProvider, private fileUploaderProvider: CoreFileUploaderProvider) {
private fileProvider: CoreFileProvider, private fileUploaderProvider: CoreFileUploaderProvider,
private utils: CoreUtilsProvider) {
this.logger = logger.getInstance('AddonModDataOfflineProvider');
this.sitesProvider.registerSiteSchema(this.siteSchema);
}
@ -201,7 +203,7 @@ export class AddonModDataOfflineProvider {
}
/**
* Get all the stored entry data from a certain database.
* Get all the stored entry actions from a certain database, sorted by modification time.
*
* @param {number} dataId Database ID.
* @param {string} [siteId] Site ID. If not defined, current site.
@ -209,7 +211,7 @@ export class AddonModDataOfflineProvider {
*/
getDatabaseEntries(dataId: number, siteId?: string): Promise<AddonModDataOfflineAction[]> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.getDb().getRecords(AddonModDataOfflineProvider.DATA_ENTRY_TABLE, {dataid: dataId});
return site.getDb().getRecords(AddonModDataOfflineProvider.DATA_ENTRY_TABLE, {dataid: dataId}, 'timemodified');
}).then((entries) => {
return entries.map(this.parseRecord.bind(this));
});
@ -257,11 +259,10 @@ export class AddonModDataOfflineProvider {
* @return {Promise<any>} Promise resolved with boolean: true if has offline answers, false otherwise.
*/
hasOfflineData(dataId: number, siteId?: string): Promise<any> {
return this.getDatabaseEntries(dataId, siteId).then((entries) => {
return !!entries.length;
}).catch(() => {
// No offline data found, return false.
return false;
return this.sitesProvider.getSite(siteId).then((site) => {
return this.utils.promiseWorks(
site.getDb().recordExists(AddonModDataOfflineProvider.DATA_ENTRY_TABLE, {dataid: dataId})
);
});
}