diff --git a/src/addons/mod/data/fields/picture/component/picture.ts b/src/addons/mod/data/fields/picture/component/picture.ts index adf032eb148..804b4b9f556 100644 --- a/src/addons/mod/data/fields/picture/component/picture.ts +++ b/src/addons/mod/data/fields/picture/component/picture.ts @@ -18,6 +18,7 @@ import { CoreFileEntry, CoreFileHelper } from '@services/file-helper'; import { CoreFileSession } from '@services/file-session'; import { CoreDomUtils } from '@services/utils/dom'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component'; +import { CoreFile } from '@services/file'; /** * Component to render data picture field. @@ -129,7 +130,7 @@ export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginBa setTimeout(() => { if (this.image) { this.imageUrl = 'name' in this.image - ? this.image.toURL() // Is Offline. + ? CoreFile.getFileEntryURL(this.image) // Is Offline. : CoreFileHelper.getFileUrl(this.image); } }, 1); diff --git a/src/addons/mod/lti/services/lti.ts b/src/addons/mod/lti/services/lti.ts index 29f8f2aec4f..dfb4110983a 100644 --- a/src/addons/mod/lti/services/lti.ts +++ b/src/addons/mod/lti/services/lti.ts @@ -80,7 +80,7 @@ export class AddonModLtiProvider { const entry = await CoreFile.writeFile(LAUNCHER_FILE_NAME, text); - return entry.toURL(); + return CoreFile.getFileEntryURL(entry); } /** diff --git a/src/core/components/local-file/local-file.ts b/src/core/components/local-file/local-file.ts index d3ad65bf1e8..cddbd6a7232 100644 --- a/src/core/components/local-file/local-file.ts +++ b/src/core/components/local-file/local-file.ts @@ -98,7 +98,7 @@ export class CoreLocalFileComponent implements OnInit { this.fileExtension = CoreMimetypeUtils.getFileExtension(file.name); // Let's calculate the relative path for the file. - this.relativePath = CoreFile.removeBasePath(file.toURL()); + this.relativePath = CoreFile.removeBasePath(CoreFile.getFileEntryURL(file)); if (!this.relativePath) { // Didn't find basePath, use fullPath but if the user tries to manage the file it'll probably fail. this.relativePath = file.fullPath; @@ -139,7 +139,7 @@ export class CoreLocalFileComponent implements OnInit { options.iOSOpenFileAction = this.defaultIsOpenWithPicker ? OpenFileAction.OPEN : OpenFileAction.OPEN_WITH; } - CoreUtils.openFile(this.file.toURL(), options); + CoreUtils.openFile(CoreFile.getFileEntryURL(this.file), options); } /** diff --git a/src/core/features/emulator/components/capture-media/capture-media.ts b/src/core/features/emulator/components/capture-media/capture-media.ts index dfa82988825..9c7c5172421 100644 --- a/src/core/features/emulator/components/capture-media/capture-media.ts +++ b/src/core/features/emulator/components/capture-media/capture-media.ts @@ -324,7 +324,7 @@ export class CoreEmulatorCaptureMediaComponent implements OnInit, OnDestroy { const fileEntry = await CoreFile.writeFile(this.getFilePath(), this.mediaBlob); if (this.isImage && !this.isCaptureImage) { - this.dismissWithData(fileEntry.toURL()); + this.dismissWithData(CoreFile.getFileEntryURL(fileEntry)); } else { // The capture plugin should return a MediaFile, not a FileEntry. Convert it. const metadata = await CoreFile.getMetadata(fileEntry); diff --git a/src/core/features/fileuploader/components/audio-recorder/audio-recorder.component.ts b/src/core/features/fileuploader/components/audio-recorder/audio-recorder.component.ts index f6285e21160..5767ed2be57 100644 --- a/src/core/features/fileuploader/components/audio-recorder/audio-recorder.component.ts +++ b/src/core/features/fileuploader/components/audio-recorder/audio-recorder.component.ts @@ -170,7 +170,7 @@ export class CoreFileUploaderAudioRecorderComponent extends CoreModalComponent { - if ('remove' in file && CoreFile.removeBasePath(file.toURL()).startsWith(CoreFileProvider.TMPFOLDER)) { + if ( + 'remove' in file && + CoreFile.removeBasePath(CoreFile.getFileEntryURL(file)).startsWith(CoreFileProvider.TMPFOLDER) + ) { // Pass an empty function to prevent missing parameter error. file.remove(() => { // Nothing to do. @@ -568,7 +571,7 @@ export class CoreFileUploaderProvider { const destFile = CorePath.concatenatePaths(folderPath, file.name); result.offline++; - await CoreFile.copyFile(file.toURL(), destFile); + await CoreFile.copyFile(CoreFile.getFileEntryURL(file), destFile); } })); @@ -642,9 +645,10 @@ export class CoreFileUploaderProvider { usedNames[name] = file; // Now upload the file. - const options = this.getFileUploadOptions(file.toURL(), name, undefined, false, 'draft', itemId); + const filePath = CoreFile.getFileEntryURL(file); + const options = this.getFileUploadOptions(filePath, name, undefined, false, 'draft', itemId); - await this.uploadFile(file.toURL(), options, undefined, siteId); + await this.uploadFile(filePath, options, undefined, siteId); })); } @@ -701,9 +705,10 @@ export class CoreFileUploaderProvider { // Now upload the file. const extension = CoreMimetypeUtils.getFileExtension(fileName); const mimetype = extension ? CoreMimetypeUtils.getMimeType(extension) : undefined; - const options = this.getFileUploadOptions(fileEntry.toURL(), fileName, mimetype, isOnline, 'draft', itemId); + const filePath = CoreFile.getFileEntryURL(fileEntry); + const options = this.getFileUploadOptions(filePath, fileName, mimetype, isOnline, 'draft', itemId); - const result = await this.uploadFile(fileEntry.toURL(), options, undefined, siteId); + const result = await this.uploadFile(filePath, options, undefined, siteId); return result.itemid; } diff --git a/src/core/features/h5p/classes/file-storage.ts b/src/core/features/h5p/classes/file-storage.ts index 5907b6e26c0..7cccc2b0d59 100644 --- a/src/core/features/h5p/classes/file-storage.ts +++ b/src/core/features/h5p/classes/file-storage.ts @@ -333,7 +333,7 @@ export class CoreH5PFileStorage { const file = await CoreFile.getFile(this.getContentIndexPath(folderName, siteId)); - return file.toURL(); + return CoreFile.getFileEntryURL(file); } /** diff --git a/src/core/features/h5p/classes/helper.ts b/src/core/features/h5p/classes/helper.ts index ba3c25a12dd..6bb2f94215c 100644 --- a/src/core/features/h5p/classes/helper.ts +++ b/src/core/features/h5p/classes/helper.ts @@ -201,7 +201,7 @@ export class CoreH5PHelper { const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName); // Unzip the file. - await CoreFile.unzipFile(file.toURL(), destFolder, onProgress); + await CoreFile.unzipFile(CoreFile.getFileEntryURL(file), destFolder, onProgress); try { // Notify that the unzip is starting. diff --git a/src/core/features/h5p/classes/player.ts b/src/core/features/h5p/classes/player.ts index ddd74b9250e..8397647dd81 100644 --- a/src/core/features/h5p/classes/player.ts +++ b/src/core/features/h5p/classes/player.ts @@ -145,7 +145,7 @@ export class CoreH5PPlayer { const fileEntry = await CoreFile.writeFile(indexPath, html); - return fileEntry.toURL(); + return CoreFile.getFileEntryURL(fileEntry); } /** diff --git a/src/core/features/sharedfiles/services/sharedfiles-helper.ts b/src/core/features/sharedfiles/services/sharedfiles-helper.ts index 6fcba06791d..6d1ca2b5b94 100644 --- a/src/core/features/sharedfiles/services/sharedfiles-helper.ts +++ b/src/core/features/sharedfiles/services/sharedfiles-helper.ts @@ -227,7 +227,7 @@ export class CoreSharedFilesHelperProvider { } else if (siteIds.length == 1) { return this.storeSharedFileInSite(fileEntry, siteIds[0], !path); } else if (!this.isChoosingSite()) { - this.goToChooseSite(fileEntry.toURL(), !path); + this.goToChooseSite(CoreFile.getFileEntryURL(fileEntry), !path); } } catch (error) { if (error) { diff --git a/src/core/features/sharedfiles/services/sharedfiles.ts b/src/core/features/sharedfiles/services/sharedfiles.ts index f0a732e72c2..5d8e5231a51 100644 --- a/src/core/features/sharedfiles/services/sharedfiles.ts +++ b/src/core/features/sharedfiles/services/sharedfiles.ts @@ -245,7 +245,7 @@ export class CoreSharedFilesProvider { // Create dir if it doesn't exist already. await CoreFile.createDir(sharedFilesFolder); - const newFile = await CoreFile.moveExternalFile(entry.toURL(), newPath); + const newFile = await CoreFile.moveExternalFile(CoreFile.getFileEntryURL(entry), newPath); CoreEvents.trigger(CoreEvents.FILE_SHARED, { siteId, name: newName }); diff --git a/src/core/services/file.ts b/src/core/services/file.ts index d26667369ff..0e0c440b760 100644 --- a/src/core/services/file.ts +++ b/src/core/services/file.ts @@ -219,7 +219,7 @@ export class CoreFileProvider { const newDirEntry = await File.createDir(base, firstDir, true); - return this.create(isDirectory, restOfPath, failIfExists, newDirEntry.toURL()); + return this.create(isDirectory, restOfPath, failIfExists, this.getFileEntryURL(newDirEntry)); } } @@ -874,12 +874,29 @@ export class CoreFileProvider { getInternalURL(fileEntry: FileEntry): string { if (!fileEntry.toInternalURL) { // File doesn't implement toInternalURL, use toURL. - return fileEntry.toURL(); + return this.getFileEntryURL(fileEntry); } return fileEntry.toInternalURL(); } + /** + * Get the URL (absolute path) of a file. + * Use this function instead of doing fileEntry.toURL because the latter causes problems with WebView and other plugins. + * + * @param fileEntry File Entry. + * @returns URL. + */ + getFileEntryURL(fileEntry: Entry): string { + if (CorePlatform.isAndroid()) { + // Cordova plugin file v7 changed the format returned by toURL, the new format it's not compatible with + // Ionic WebView or FileTransfer plugin. + return fileEntry.nativeURL; + } + + return fileEntry.toURL(); + } + /** * Adds the basePath to a path if it doesn't have it already. * @@ -934,7 +951,7 @@ export class CoreFileProvider { // If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath). destFolder = this.addBasePathIfNeeded(destFolder || CoreMimetypeUtils.removeExtension(path)); - const result = await Zip.unzip(fileEntry.toURL(), destFolder, onProgress); + const result = await Zip.unzip(this.getFileEntryURL(fileEntry), destFolder, onProgress); if (result == -1) { throw new CoreError('Unzip failed.'); diff --git a/src/core/services/filepool.ts b/src/core/services/filepool.ts index 5623c46a8a1..8303fb85dd9 100644 --- a/src/core/services/filepool.ts +++ b/src/core/services/filepool.ts @@ -771,7 +771,7 @@ export class CoreFilepoolProvider { }); // Add the anchor again to the local URL. - return fileEntry.toURL() + (anchor || ''); + return CoreFile.getFileEntryURL(fileEntry) + (anchor || ''); }).finally(() => { // Download finished, delete the promise. delete this.filePromises[siteId][downloadId]; @@ -1278,7 +1278,7 @@ export class CoreFilepoolProvider { const filePath = await this.getFilePath(siteId, fileId, ''); const dirEntry = await CoreFile.getDir(filePath); - return dirEntry.toURL(); + return CoreFile.getFileEntryURL(dirEntry); } /** @@ -1666,7 +1666,7 @@ export class CoreFilepoolProvider { const path = await this.getFilePath(siteId, fileId); const fileEntry = await CoreFile.getFile(path); - return CoreFile.convertFileSrc(fileEntry.toURL()); + return CoreFile.convertFileSrc(CoreFile.getFileEntryURL(fileEntry)); } /** @@ -1685,7 +1685,7 @@ export class CoreFilepoolProvider { const fileEntry = await CoreFile.getFile(path); // This URL is usually used to launch files or put them in HTML. - return fileEntry.toURL(); + return CoreFile.getFileEntryURL(fileEntry); } /** @@ -1701,7 +1701,7 @@ export class CoreFilepoolProvider { const fileEntry = await CoreFile.getFile(filePath); - return fileEntry.toURL(); + return CoreFile.getFileEntryURL(fileEntry); } /** @@ -1797,7 +1797,7 @@ export class CoreFilepoolProvider { const dirPath = await this.getFilePath(siteId, dirName, ''); const dirEntry = await CoreFile.getDir(dirPath); - return dirEntry.toURL(); + return CoreFile.getFileEntryURL(dirEntry); } /** diff --git a/src/core/services/utils/mimetype.ts b/src/core/services/utils/mimetype.ts index dc537b7b581..5bbf6772443 100644 --- a/src/core/services/utils/mimetype.ts +++ b/src/core/services/utils/mimetype.ts @@ -185,7 +185,7 @@ export class CoreMimetypeUtilsProvider { // @todo linting: See if this can be removed (file as { embedType?: string }).embedType = embedType; - path = path ?? (CoreUtils.isFileEntry(file) ? file.toURL() : CoreFileHelper.getFileUrl(file)); + path = path ?? (CoreUtils.isFileEntry(file) ? CoreFile.getFileEntryURL(file) : CoreFileHelper.getFileUrl(file)); path = path && CoreFile.convertFileSrc(path); switch (embedType) { diff --git a/src/core/services/ws.ts b/src/core/services/ws.ts index 8e7d7ae0ce1..90a45244d9a 100644 --- a/src/core/services/ws.ts +++ b/src/core/services/ws.ts @@ -258,7 +258,7 @@ export class CoreWSProvider { onProgress && transfer.onProgress(onProgress); // Download the file in the tmp file. - await transfer.download(url, fileEntry.toURL(), true, { + await transfer.download(url, CoreFile.getFileEntryURL(fileEntry), true, { headers: { 'User-Agent': navigator.userAgent, }, diff --git a/upgrade.txt b/upgrade.txt index 567d515734c..0689f7b5eb6 100644 --- a/upgrade.txt +++ b/upgrade.txt @@ -12,6 +12,7 @@ For more information about upgrading, read the official documentation: https://m - With the upgrade to Ionic7 ion-datetime has changed its usage. We recommend using ion-datetime-button. More info here: https://ionicframework.com/docs/updating/6-0#datetime - CoreLoginHelper.getErrorMessages has been removed. Please create the messages object yourself. - CoreAppProvider.isAutomated() has been deprecated, use CorePlatformService.isAutomated() instead. + - Due to a breaking change in cordova-plugin-file, avoid using FileEntry.toURL(). Use CoreFileProvider.getFileEntryURL instead. === 4.3.0 ===