2017-11-06 17:17:11 +01:00
|
|
|
|
// (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 { CoreLangProvider } from '../lang';
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* "Utils" service with helper functions for URLs.
|
|
|
|
|
*/
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class CoreUrlUtilsProvider {
|
|
|
|
|
|
|
|
|
|
constructor(private langProvider: CoreLangProvider) {}
|
|
|
|
|
|
2017-11-13 13:35:44 +01:00
|
|
|
|
/**
|
|
|
|
|
* Add or remove 'www' from a URL. The url needs to have http or https protocol.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to modify.
|
|
|
|
|
* @return {string} Modified URL.
|
|
|
|
|
*/
|
|
|
|
|
addOrRemoveWWW(url: string) : string {
|
|
|
|
|
if (url) {
|
|
|
|
|
if (url.match(/http(s)?:\/\/www\./)) {
|
|
|
|
|
// Already has www. Remove it.
|
|
|
|
|
url = url.replace('www.', '');
|
|
|
|
|
} else {
|
|
|
|
|
url = url.replace('https://', 'https://www.');
|
|
|
|
|
url = url.replace('http://', 'http://www.');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-06 17:17:11 +01:00
|
|
|
|
/**
|
|
|
|
|
* Extracts the parameters from a URL and stores them in an object.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to treat.
|
2017-11-20 16:19:21 +01:00
|
|
|
|
* @return {any} Object with the params.
|
2017-11-06 17:17:11 +01:00
|
|
|
|
*/
|
2017-11-20 16:19:21 +01:00
|
|
|
|
extractUrlParams(url: string) : any {
|
2017-11-06 17:17:11 +01:00
|
|
|
|
let regex = /[?&]+([^=&]+)=?([^&]*)?/gi,
|
|
|
|
|
params = {};
|
|
|
|
|
|
|
|
|
|
url.replace(regex, (match: string, key: string, value: string) : string => {
|
|
|
|
|
params[key] = typeof value != 'undefined' ? value : '';
|
|
|
|
|
return match;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return params;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-13 13:35:44 +01:00
|
|
|
|
/**
|
|
|
|
|
* Generic function for adding the wstoken to Moodle urls and for pointing to the correct script.
|
|
|
|
|
* For download remote files from Moodle we need to use the special /webservice/pluginfile passing
|
|
|
|
|
* the ws token as a get parameter.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The url to be fixed.
|
|
|
|
|
* @param {string} token Token to use.
|
|
|
|
|
* @return {string} Fixed URL.
|
|
|
|
|
*/
|
|
|
|
|
fixPluginfileURL(url: string, token: string) : string {
|
|
|
|
|
if (!url || !token) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// First check if we need to fix this url or is already fixed.
|
|
|
|
|
if (url.indexOf('token=') != -1) {
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if is a valid URL (contains the pluginfile endpoint).
|
|
|
|
|
if (!this.isPluginFileUrl(url)) {
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In which way the server is serving the files? Are we using slash parameters?
|
|
|
|
|
if (url.indexOf('?file=') != -1 || url.indexOf('?forcedownload=') != -1 || url.indexOf('?rev=') != -1) {
|
|
|
|
|
url += '&';
|
|
|
|
|
} else {
|
|
|
|
|
url += '?';
|
|
|
|
|
}
|
|
|
|
|
// Always send offline=1 (for external repositories). It shouldn't cause problems for local files or old Moodles.
|
|
|
|
|
url += 'token=' + token + '&offline=1';
|
|
|
|
|
|
|
|
|
|
// Some webservices returns directly the correct download url, others not.
|
|
|
|
|
if (url.indexOf('/webservice/pluginfile') == -1) {
|
|
|
|
|
url = url.replace('/pluginfile', '/webservice/pluginfile');
|
|
|
|
|
}
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Formats a URL, trim, lowercase, etc...
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The url to be formatted.
|
|
|
|
|
* @return {string} Fromatted url.
|
|
|
|
|
*/
|
|
|
|
|
formatURL(url: string) : string {
|
|
|
|
|
url = url.trim();
|
|
|
|
|
|
|
|
|
|
// Check if the URL starts by http or https.
|
|
|
|
|
if (! /^http(s)?\:\/\/.*/i.test(url)) {
|
|
|
|
|
// Test first allways https.
|
|
|
|
|
url = 'https://' + url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// http allways in lowercase.
|
|
|
|
|
url = url.replace(/^http/i, 'http');
|
|
|
|
|
url = url.replace(/^https/i, 'https');
|
|
|
|
|
|
|
|
|
|
// Replace last slash.
|
|
|
|
|
url = url.replace(/\/$/, "");
|
|
|
|
|
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-06 17:17:11 +01:00
|
|
|
|
/**
|
|
|
|
|
* Returns the URL to the documentation of the app, based on Moodle version and current language.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} [release] Moodle release.
|
|
|
|
|
* @param {string} [page=Mobile_app] Docs page to go to.
|
|
|
|
|
* @return {Promise<string>} Promise resolved with the Moodle docs URL.
|
|
|
|
|
*/
|
|
|
|
|
getDocsUrl(release?: string, page = 'Mobile_app') : Promise<string> {
|
|
|
|
|
let docsUrl = 'https://docs.moodle.org/en/' + page;
|
|
|
|
|
|
|
|
|
|
if (typeof release != 'undefined') {
|
|
|
|
|
let version = release.substr(0, 3).replace('.', '');
|
|
|
|
|
// Check is a valid number.
|
|
|
|
|
if (parseInt(version) >= 24) {
|
|
|
|
|
// Append release number.
|
|
|
|
|
docsUrl = docsUrl.replace('https://docs.moodle.org/', 'https://docs.moodle.org/' + version + '/');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.langProvider.getCurrentLanguage().then((lang) => {
|
|
|
|
|
return docsUrl.replace('/en/', '/' + lang + '/');
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
return docsUrl;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-13 13:35:44 +01:00
|
|
|
|
/**
|
|
|
|
|
* Given a URL, returns what's after the last '/' without params.
|
|
|
|
|
* Example:
|
|
|
|
|
* http://mysite.com/a/course.html?id=1 -> course.html
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to treat.
|
|
|
|
|
* @return {string} Last file without params.
|
|
|
|
|
*/
|
|
|
|
|
getLastFileWithoutParams(url: string) : string {
|
|
|
|
|
let filename = url.substr(url.lastIndexOf('/') + 1);
|
|
|
|
|
if (filename.indexOf('?') != -1) {
|
|
|
|
|
filename = filename.substr(0, filename.indexOf('?'));
|
|
|
|
|
}
|
|
|
|
|
return filename;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the protocol from a URL.
|
|
|
|
|
* E.g. http://www.google.com returns 'http'.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to treat.
|
|
|
|
|
* @return {string} Protocol, undefined if no protocol found.
|
|
|
|
|
*/
|
|
|
|
|
getUrlProtocol(url: string) : string {
|
|
|
|
|
if (!url) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let matches = url.match(/^([^\/:\.\?]*):\/\//);
|
|
|
|
|
if (matches && matches[1]) {
|
|
|
|
|
return matches[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the scheme from a URL. Please notice that, if a URL has protocol, it will return the protocol.
|
|
|
|
|
* E.g. javascript:doSomething() returns 'javascript'.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to treat.
|
|
|
|
|
* @return {string} Scheme, undefined if no scheme found.
|
|
|
|
|
*/
|
|
|
|
|
getUrlScheme(url: string) : string {
|
|
|
|
|
if (!url) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let matches = url.match(/^([a-z][a-z0-9+\-.]*):/);
|
|
|
|
|
if (matches && matches[1]) {
|
|
|
|
|
return matches[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Gets a username from a URL like: user@mysite.com.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to treat.
|
|
|
|
|
* @return {string} Username. Undefined if no username found.
|
|
|
|
|
*/
|
|
|
|
|
getUsernameFromUrl(url: string) : string {
|
|
|
|
|
if (url.indexOf('@') > -1) {
|
|
|
|
|
// Get URL without protocol.
|
|
|
|
|
let withoutProtocol = url.replace(/.*?:\/\//, ''),
|
|
|
|
|
matches = withoutProtocol.match(/[^@]*/);
|
|
|
|
|
|
|
|
|
|
// Make sure that @ is at the start of the URL, not in a param at the end.
|
|
|
|
|
if (matches && matches.length && !matches[0].match(/[\/|?]/)) {
|
|
|
|
|
return matches[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-06 17:17:11 +01:00
|
|
|
|
/**
|
|
|
|
|
* Returns if a URL has any protocol (not a relative URL).
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The url to test against the pattern.
|
|
|
|
|
* @return {boolean} Whether the url is absolute.
|
|
|
|
|
*/
|
|
|
|
|
isAbsoluteURL(url: string) : boolean {
|
|
|
|
|
return /^[^:]{2,}:\/\//i.test(url) || /^(tel:|mailto:|geo:)/.test(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns if a URL is downloadable: plugin file OR theme/image.php OR gravatar.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The URL to test.
|
|
|
|
|
* @return {boolean} Whether the URL is downloadable.
|
|
|
|
|
*/
|
|
|
|
|
isDownloadableUrl(url: string) : boolean {
|
|
|
|
|
return this.isPluginFileUrl(url) || this.isThemeImageUrl(url) || this.isGravatarUrl(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns if a URL is a gravatar URL.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The URL to test.
|
|
|
|
|
* @return {boolean} Whether the URL is a gravatar URL.
|
|
|
|
|
*/
|
|
|
|
|
isGravatarUrl(url: string) : boolean {
|
|
|
|
|
return url && url.indexOf('gravatar.com/avatar') !== -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a URL uses http or https protocol.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The url to test.
|
|
|
|
|
* @return {boolean} Whether the url uses http or https protocol.
|
|
|
|
|
*/
|
|
|
|
|
isHttpURL(url: string) : boolean {
|
|
|
|
|
return /^https?\:\/\/.+/i.test(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns if a URL is a pluginfile URL.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The URL to test.
|
|
|
|
|
* @return {boolean} Whether the URL is a pluginfile URL.
|
|
|
|
|
*/
|
|
|
|
|
isPluginFileUrl(url: string) : boolean {
|
|
|
|
|
return url && url.indexOf('/pluginfile.php') !== -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns if a URL is a theme image URL.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url The URL to test.
|
|
|
|
|
* @return {boolean} Whether the URL is a theme image URL.
|
|
|
|
|
*/
|
|
|
|
|
isThemeImageUrl(url: string) : boolean {
|
|
|
|
|
return url && url.indexOf('/theme/image.php') !== -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-11-13 13:35:44 +01:00
|
|
|
|
* Remove protocol and www from a URL.
|
2017-11-06 17:17:11 +01:00
|
|
|
|
*
|
2017-11-13 13:35:44 +01:00
|
|
|
|
* @param {string} url URL to treat.
|
|
|
|
|
* @return {string} Treated URL.
|
2017-11-06 17:17:11 +01:00
|
|
|
|
*/
|
2017-11-13 13:35:44 +01:00
|
|
|
|
removeProtocolAndWWW(url: string) : string {
|
|
|
|
|
// Remove protocol.
|
|
|
|
|
url = url.replace(/.*?:\/\//g, '');
|
|
|
|
|
// Remove www.
|
|
|
|
|
url = url.replace(/^www./, '');
|
2017-11-06 17:17:11 +01:00
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove the parameters from a URL, returning the URL without them.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} url URL to treat.
|
|
|
|
|
* @return {string} URL without params.
|
|
|
|
|
*/
|
|
|
|
|
removeUrlParams(url: string) : string {
|
|
|
|
|
let matches = url.match(/^[^\?]+/);
|
|
|
|
|
return matches && matches[0];
|
|
|
|
|
}
|
|
|
|
|
}
|