Merge pull request #2567 from dpalou/MOBILE-3571
MOBILE-3571 core: Split calls with too many parametersmain
commit
099ca77221
|
@ -20,7 +20,9 @@ import { CoreDbProvider } from '@providers/db';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreFileProvider } from '@providers/file';
|
import { CoreFileProvider } from '@providers/file';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreWSProvider, CoreWSPreSets, CoreWSFileUploadOptions, CoreWSAjaxPreSets } from '@providers/ws';
|
import {
|
||||||
|
CoreWSProvider, CoreWSPreSets, CoreWSFileUploadOptions, CoreWSAjaxPreSets, CoreWSPreSetsSplitRequest
|
||||||
|
} from '@providers/ws';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||||
|
@ -138,6 +140,12 @@ export interface CoreSiteWSPreSets {
|
||||||
* Component id. Optionally included when 'component' is set.
|
* Component id. Optionally included when 'component' is set.
|
||||||
*/
|
*/
|
||||||
componentId?: number;
|
componentId?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to split a request if it has too many parameters. Sending too many parameters to the site
|
||||||
|
* can cause the request to fail (see PHP's max_input_vars).
|
||||||
|
*/
|
||||||
|
splitRequest?: CoreWSPreSetsSplitRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -650,7 +658,8 @@ export class CoreSite {
|
||||||
siteUrl: this.siteUrl,
|
siteUrl: this.siteUrl,
|
||||||
cleanUnicode: this.cleanUnicode,
|
cleanUnicode: this.cleanUnicode,
|
||||||
typeExpected: preSets.typeExpected,
|
typeExpected: preSets.typeExpected,
|
||||||
responseExpected: preSets.responseExpected
|
responseExpected: preSets.responseExpected,
|
||||||
|
splitRequest: preSets.splitRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (wsPreSets.cleanUnicode && this.textUtils.hasUnicodeData(data)) {
|
if (wsPreSets.cleanUnicode && this.textUtils.hasUnicodeData(data)) {
|
||||||
|
|
|
@ -471,7 +471,11 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate {
|
||||||
preSets: CoreSiteWSPreSets = {
|
preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getCourseUpdatesCacheKey(courseId),
|
cacheKey: this.getCourseUpdatesCacheKey(courseId),
|
||||||
emergencyCache: false, // If downloaded data has changed and offline, just fail. See MOBILE-2085.
|
emergencyCache: false, // If downloaded data has changed and offline, just fail. See MOBILE-2085.
|
||||||
uniqueCacheKey: true
|
uniqueCacheKey: true,
|
||||||
|
splitRequest: {
|
||||||
|
param: 'tocheck',
|
||||||
|
maxLength: 10,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return site.read('core_course_check_updates', params, preSets).then((response) => {
|
return site.read('core_course_check_updates', params, preSets).then((response) => {
|
||||||
|
|
|
@ -272,7 +272,11 @@ export class CoreFilterProvider {
|
||||||
},
|
},
|
||||||
preSets = {
|
preSets = {
|
||||||
cacheKey: this.getAvailableInContextsCacheKey(contextsToSend),
|
cacheKey: this.getAvailableInContextsCacheKey(contextsToSend),
|
||||||
updateFrequency: CoreSite.FREQUENCY_RARELY
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
splitRequest: {
|
||||||
|
param: 'contexts',
|
||||||
|
maxLength: 300,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return site.read('core_filters_get_available_in_context', data, preSets)
|
return site.read('core_filters_get_available_in_context', data, preSets)
|
||||||
|
|
|
@ -57,8 +57,34 @@ export interface CoreWSPreSets {
|
||||||
* Defaults to false. Clean multibyte Unicode chars from data.
|
* Defaults to false. Clean multibyte Unicode chars from data.
|
||||||
*/
|
*/
|
||||||
cleanUnicode?: boolean;
|
cleanUnicode?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to split a request if it has too many parameters. Sending too many parameters to the site
|
||||||
|
* can cause the request to fail (see PHP's max_input_vars).
|
||||||
|
*/
|
||||||
|
splitRequest?: CoreWSPreSetsSplitRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options to split a request.
|
||||||
|
*/
|
||||||
|
export type CoreWSPreSetsSplitRequest = {
|
||||||
|
/**
|
||||||
|
* Name of the parameter used to split the request if too big. Must be an array parameter.
|
||||||
|
*/
|
||||||
|
param: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max number of entries sent per request.
|
||||||
|
*/
|
||||||
|
maxLength: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to combine the results. If not supplied, arrays in the result will be concatenated.
|
||||||
|
*/
|
||||||
|
combineCallback?: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PreSets accepted by AJAX WS calls.
|
* PreSets accepted by AJAX WS calls.
|
||||||
*/
|
*/
|
||||||
|
@ -622,7 +648,7 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the post call and save the promise while waiting to be resolved.
|
* Perform the post call. It can be split into several requests.
|
||||||
*
|
*
|
||||||
* @param method The WebService method to be called.
|
* @param method The WebService method to be called.
|
||||||
* @param siteUrl Complete site url to perform the call.
|
* @param siteUrl Complete site url to perform the call.
|
||||||
|
@ -639,6 +665,64 @@ export class CoreWSProvider {
|
||||||
options['responseType'] = 'text';
|
options['responseType'] = 'text';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preSets.splitRequest || !ajaxData[preSets.splitRequest.param]) {
|
||||||
|
return this.performSinglePost(method, siteUrl, ajaxData, preSets, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the request into several requests if needed.
|
||||||
|
const promises: Promise<any>[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < ajaxData[preSets.splitRequest.param].length; i += preSets.splitRequest.maxLength) {
|
||||||
|
// Limit the array sent.
|
||||||
|
const limitedData = Object.assign({}, ajaxData);
|
||||||
|
limitedData[preSets.splitRequest.param] =
|
||||||
|
ajaxData[preSets.splitRequest.param].slice(i, i + preSets.splitRequest.maxLength);
|
||||||
|
|
||||||
|
promises.push(this.performSinglePost(method, siteUrl, limitedData, preSets, options));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises).then((results) => {
|
||||||
|
// Combine the results.
|
||||||
|
const firstResult = results.shift();
|
||||||
|
|
||||||
|
if (preSets.splitRequest.combineCallback) {
|
||||||
|
return results.reduce(preSets.splitRequest.combineCallback, firstResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.reduce(this.combineObjectsArrays, firstResult);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine the arrays of two objects.
|
||||||
|
*
|
||||||
|
* @param object1 First object.
|
||||||
|
* @param object2 Second object.
|
||||||
|
* @return Combined object.
|
||||||
|
*/
|
||||||
|
protected combineObjectsArrays(object1: any, object2: any): any {
|
||||||
|
for (const name in object2) {
|
||||||
|
if (Array.isArray(object2[name])) {
|
||||||
|
object1[name] = object1[name].concat(object2[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return object1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a single post request.
|
||||||
|
*
|
||||||
|
* @param method The WebService method to be called.
|
||||||
|
* @param siteUrl Complete site url to perform the call.
|
||||||
|
* @param ajaxData Arguments to pass to the method.
|
||||||
|
* @param preSets Extra settings and information.
|
||||||
|
* @param options Request options.
|
||||||
|
* @return Promise resolved with the response data in success and rejected with CoreWSError if it fails.
|
||||||
|
*/
|
||||||
|
protected performSinglePost(method: string, siteUrl: string, ajaxData: any, preSets: CoreWSPreSets, options: any)
|
||||||
|
: Promise<any> {
|
||||||
|
|
||||||
// We add the method name to the URL purely to help with debugging.
|
// We add the method name to the URL purely to help with debugging.
|
||||||
// This duplicates what is in the ajaxData, but that does no harm.
|
// This duplicates what is in the ajaxData, but that does no harm.
|
||||||
// POST variables take precedence over GET.
|
// POST variables take precedence over GET.
|
||||||
|
|
Loading…
Reference in New Issue