MOBILE-2261 core: Implement plugin file delegate
parent
93568a9c97
commit
0519875949
|
@ -49,6 +49,7 @@ import { CoreCronDelegate } from '../providers/cron';
|
|||
import { CoreFileSessionProvider } from '../providers/file-session';
|
||||
import { CoreFilepoolProvider } from '../providers/filepool';
|
||||
import { CoreUpdateManagerProvider } from '../providers/update-manager';
|
||||
import { CorePluginFileDelegate } from '../providers/plugin-file-delegate';
|
||||
|
||||
// For translate loader. AoT requires an exported function for factories.
|
||||
export function createTranslateLoader(http: HttpClient) {
|
||||
|
@ -105,6 +106,7 @@ export function createTranslateLoader(http: HttpClient) {
|
|||
CoreFileSessionProvider,
|
||||
CoreFilepoolProvider,
|
||||
CoreUpdateManagerProvider,
|
||||
CorePluginFileDelegate
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
|
|
|
@ -19,6 +19,7 @@ import { CoreEventsProvider } from './events';
|
|||
import { CoreFileProvider } from './file';
|
||||
import { CoreInitDelegate } from './init';
|
||||
import { CoreLoggerProvider } from './logger';
|
||||
import { CorePluginFileDelegate } from './plugin-file-delegate';
|
||||
import { CoreSitesProvider } from './sites';
|
||||
import { CoreWSProvider } from './ws';
|
||||
import { CoreMimetypeUtilsProvider } from './utils/mimetype';
|
||||
|
@ -276,7 +277,6 @@ export class CoreFilepoolProvider {
|
|||
new RegExp('(\\?|&)preview=[A-Za-z0-9]+'),
|
||||
new RegExp('(\\?|&)offline=[0-1]', 'g')
|
||||
];
|
||||
protected revisionRegex = new RegExp('/content/([0-9]+)/');
|
||||
protected queueDeferreds = {}; // To handle file downloads using the queue.
|
||||
protected sizeCache = {}; // A "cache" to store file sizes to prevent performing too many HEAD requests.
|
||||
// Variables to prevent downloading packages/files twice at the same time.
|
||||
|
@ -287,7 +287,7 @@ export class CoreFilepoolProvider {
|
|||
private sitesProvider: CoreSitesProvider, private wsProvider: CoreWSProvider, private textUtils: CoreTextUtilsProvider,
|
||||
private utils: CoreUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider, private urlUtils: CoreUrlUtilsProvider,
|
||||
private timeUtils: CoreTimeUtilsProvider, private eventsProvider: CoreEventsProvider, initDelegate: CoreInitDelegate,
|
||||
network: Network) {
|
||||
network: Network, private pluginFileDelegate: CorePluginFileDelegate) {
|
||||
this.logger = logger.getInstance('CoreFilepoolProvider');
|
||||
|
||||
this.appDB = this.appProvider.getDB();
|
||||
|
@ -1784,6 +1784,29 @@ export class CoreFilepoolProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the array of arguments of the pluginfile url.
|
||||
*
|
||||
* @param {string} url URL to get the args.
|
||||
* @return {string[]} The args found, undefined if not a pluginfile.
|
||||
*/
|
||||
protected getPluginFileArgs(url: string) : string[] {
|
||||
if (!this.urlUtils.isPluginFileUrl(url)) {
|
||||
// Not pluginfile, return.
|
||||
return;
|
||||
}
|
||||
|
||||
let relativePath = url.substr(url.indexOf('/pluginfile.php') + 16),
|
||||
args = relativePath.split('/');
|
||||
|
||||
if (args.length < 3) {
|
||||
// To be a plugin file it should have at least contextId, Component and Filearea.
|
||||
return;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the deferred object for a file in the queue.
|
||||
*
|
||||
|
@ -1862,11 +1885,22 @@ export class CoreFilepoolProvider {
|
|||
* @return {number} Revision number.
|
||||
*/
|
||||
protected getRevisionFromUrl(url: string) : number {
|
||||
const matches = url.match(this.revisionRegex);
|
||||
let args = this.getPluginFileArgs(url);
|
||||
if (!args) {
|
||||
// Not a pluginfile, no revision will be found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
let revisionRegex = this.pluginFileDelegate.getComponentRevisionRegExp(args);
|
||||
if (!revisionRegex) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let matches = url.match(revisionRegex);
|
||||
if (matches && typeof matches[1] != 'undefined') {
|
||||
return parseInt(matches[1], 10);
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1959,7 +1993,7 @@ export class CoreFilepoolProvider {
|
|||
filename = 'gravatar_' + this.urlUtils.getLastFileWithoutParams(fileUrl);
|
||||
} else if (this.urlUtils.isThemeImageUrl(fileUrl)) {
|
||||
// Extract user ID.
|
||||
const matches = fileUrl.match(/clean\/core\/([^\/]*)\//);
|
||||
const matches = fileUrl.match(/\/core\/([^\/]*)\//);
|
||||
if (matches && matches[1]) {
|
||||
filename = matches[1];
|
||||
}
|
||||
|
@ -2431,7 +2465,13 @@ export class CoreFilepoolProvider {
|
|||
* The revision is used to know if a file has changed. We remove it from the URL to prevent storing a file per revision.
|
||||
*/
|
||||
protected removeRevisionFromUrl(url: string) : string {
|
||||
return url.replace(this.revisionRegex, '/content/0/');
|
||||
let args = this.getPluginFileArgs(url);
|
||||
if (!args) {
|
||||
// Not a pluginfile, no revision will be found.
|
||||
return url;
|
||||
}
|
||||
|
||||
return this.pluginFileDelegate.removeRevisionFromUrl(url, args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
// (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 { CoreLoggerProvider } from './logger';
|
||||
|
||||
export interface CorePluginFileHandler {
|
||||
name: string; // Name of the handler.
|
||||
getComponentRevisionRegExp?(args: string[]): RegExp; // Should return the RegExp to match revision on pluginfile url.
|
||||
getComponentRevisionReplace?(args: string[]): string; // Should return the String to remove the revision on pluginfile url.
|
||||
};
|
||||
|
||||
/**
|
||||
* Delegate to register pluginfile information handlers.
|
||||
*/
|
||||
@Injectable()
|
||||
export class CorePluginFileDelegate {
|
||||
protected logger;
|
||||
protected handlers: {[s: string]: CorePluginFileHandler} = {};
|
||||
|
||||
constructor(logger: CoreLoggerProvider) {
|
||||
this.logger = logger.getInstance('CorePluginFileDelegate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handler for a certain pluginfile url.
|
||||
*
|
||||
* @param {string} pluginType Type of the plugin.
|
||||
* @return {CorePluginFileHandler} Handler. Undefined if no handler found for the plugin.
|
||||
*/
|
||||
protected getPluginHandler(pluginType: string) : CorePluginFileHandler {
|
||||
if (typeof this.handlers[pluginType] != 'undefined') {
|
||||
return this.handlers[pluginType];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RegExp of the component and filearea described in the URL.
|
||||
*
|
||||
* @param {string[]} args Arguments of the pluginfile URL defining component and filearea at least.
|
||||
* @return {RegExp} RegExp to match the revision or undefined if not found.
|
||||
*/
|
||||
getComponentRevisionRegExp(args: string[]) : RegExp {
|
||||
// Get handler based on component (args[1]).
|
||||
const handler = this.getPluginHandler(args[1]);
|
||||
|
||||
if (handler && handler.getComponentRevisionRegExp) {
|
||||
return handler.getComponentRevisionRegExp(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler.
|
||||
*
|
||||
* @param {CorePluginFileHandler} handler The handler to register.
|
||||
* @return {boolean} True if registered successfully, false otherwise.
|
||||
*/
|
||||
registerHandler(handler: CorePluginFileHandler) : boolean {
|
||||
if (typeof this.handlers[handler.name] !== 'undefined') {
|
||||
this.logger.log(`Addon 'handler.name' already registered`);
|
||||
return false;
|
||||
}
|
||||
this.logger.log(`Registered addon 'handler.name'`);
|
||||
this.handlers[handler.name] = handler;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the revision number from a file URL.
|
||||
*
|
||||
* @param {string} url URL to be replaced.
|
||||
* @param {string[]} args Arguments of the pluginfile URL defining component and filearea at least.
|
||||
* @return {string} Replaced URL without revision.
|
||||
*/
|
||||
removeRevisionFromUrl(url: string, args: string[]) : string {
|
||||
// Get handler based on component (args[1]).
|
||||
const handler = this.getPluginHandler(args[1]);
|
||||
|
||||
if (handler && handler.getComponentRevisionRegExp && handler.getComponentRevisionReplace) {
|
||||
const revisionRegex = handler.getComponentRevisionRegExp(args);
|
||||
if (revisionRegex) {
|
||||
return url.replace(revisionRegex, handler.getComponentRevisionReplace(args));
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue