forked from EVOgeek/Vmeda.Online
		
	Merge pull request #2310 from dpalou/MOBILE-3298
MOBILE-3298 course: Don't fail module download if avatar fails
This commit is contained in:
		
						commit
						14a963cf6d
					
				| @ -354,15 +354,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | ||||
|                         }).then(() => { | ||||
|                             // Participiants already fetched, we don't need to ignore cache now.
 | ||||
|                             return this.assignHelper.getParticipants(assign, group.id, false, siteId).then((participants) => { | ||||
|                                 const promises = []; | ||||
| 
 | ||||
|                                 participants.forEach((participant) => { | ||||
|                                     if (participant.profileimageurl) { | ||||
|                                         promises.push(this.filepoolProvider.addToQueueByUrl(siteId, participant.profileimageurl)); | ||||
|                                     } | ||||
|                                 }); | ||||
| 
 | ||||
|                                 return Promise.all(promises); | ||||
|                                 return this.userProvider.prefetchUserAvatars(participants, 'profileimageurl', siteId); | ||||
|                             }).catch(() => { | ||||
|                                 // Fail silently (Moodle < 3.2).
 | ||||
|                             }); | ||||
|  | ||||
| @ -182,9 +182,7 @@ export class AddonModChatPrefetchHandler extends CoreCourseActivityPrefetchHandl | ||||
|             }); | ||||
|             const userIds = Object.keys(users).map(Number); | ||||
| 
 | ||||
|             return this.userProvider.prefetchProfiles(userIds, courseId, siteId).catch(() => { | ||||
|                 // Ignore errors, some users might not exist.
 | ||||
|             }); | ||||
|             return this.userProvider.prefetchProfiles(userIds, courseId, siteId); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -244,13 +244,14 @@ export class AddonModForumProvider { | ||||
|      * Check if a user can post to all groups. | ||||
|      * | ||||
|      * @param forumId Forum ID. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @return Promise resolved with an object with the following properties: | ||||
|      *         - status (boolean) | ||||
|      *         - canpindiscussions (boolean) | ||||
|      *         - cancreateattachment (boolean) | ||||
|      */ | ||||
|     canAddDiscussionToAll(forumId: number): Promise<any> { | ||||
|         return this.canAddDiscussion(forumId, AddonModForumProvider.ALL_PARTICIPANTS); | ||||
|     canAddDiscussionToAll(forumId: number, siteId?: string): Promise<any> { | ||||
|         return this.canAddDiscussion(forumId, AddonModForumProvider.ALL_PARTICIPANTS, siteId); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -107,12 +107,13 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand | ||||
|      * Get the posts to be prefetched. | ||||
|      * | ||||
|      * @param forum Forum instance. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @return Promise resolved with array of posts. | ||||
|      */ | ||||
|     protected getPostsForPrefetch(forum: any): Promise<any[]> { | ||||
|     protected getPostsForPrefetch(forum: any, siteId?: string): Promise<any[]> { | ||||
|         const promises = this.forumProvider.getAvailableSortOrders().map((sortOrder) => { | ||||
|             // Get discussions in first 2 pages.
 | ||||
|             return this.forumProvider.getDiscussionsInPages(forum.id, sortOrder.value, false, 2).then((response) => { | ||||
|             return this.forumProvider.getDiscussionsInPages(forum.id, sortOrder.value, false, 2, 0, siteId).then((response) => { | ||||
|                 if (response.error) { | ||||
|                     return Promise.reject(null); | ||||
|                 } | ||||
| @ -120,7 +121,7 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand | ||||
|                 const promises = []; | ||||
| 
 | ||||
|                 response.discussions.forEach((discussion) => { | ||||
|                     promises.push(this.forumProvider.getDiscussionPosts(discussion.discussion)); | ||||
|                     promises.push(this.forumProvider.getDiscussionPosts(discussion.discussion, siteId)); | ||||
|                 }); | ||||
| 
 | ||||
|               return Promise.all(promises); | ||||
| @ -200,41 +201,31 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand | ||||
|      */ | ||||
|     protected prefetchForum(module: any, courseId: number, single: boolean, siteId: string): Promise<any> { | ||||
|         // Get the forum data.
 | ||||
|         return this.forumProvider.getForum(courseId, module.id).then((forum) => { | ||||
|         return this.forumProvider.getForum(courseId, module.id, siteId).then((forum) => { | ||||
|             const promises = []; | ||||
| 
 | ||||
|             // Prefetch the posts.
 | ||||
|             promises.push(this.getPostsForPrefetch(forum).then((posts) => { | ||||
|             promises.push(this.getPostsForPrefetch(forum, siteId).then((posts) => { | ||||
|                 const promises = []; | ||||
| 
 | ||||
|                 // Gather user profile images.
 | ||||
|                 const avatars = {}; // List of user avatars, preventing duplicates.
 | ||||
| 
 | ||||
|                 posts.forEach((post) => { | ||||
|                     if (post.userpictureurl) { | ||||
|                         avatars[post.userpictureurl] = true; | ||||
|                     } | ||||
|                 }); | ||||
| 
 | ||||
|                 // Prefetch intro files, attachments, embedded files and user avatars.
 | ||||
|                 const avatarFiles = Object.keys(avatars).map((url) => { | ||||
|                     return { fileurl: url }; | ||||
|                 }); | ||||
|                 const files = this.getIntroFilesFromInstance(module, forum).concat(this.getPostsFiles(posts)).concat(avatarFiles); | ||||
|                 const files = this.getIntroFilesFromInstance(module, forum).concat(this.getPostsFiles(posts)); | ||||
|                 promises.push(this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id)); | ||||
| 
 | ||||
|                 // Prefetch groups data.
 | ||||
|                 promises.push(this.prefetchGroupsInfo(forum, courseId, forum.cancreatediscussions)); | ||||
|                 promises.push(this.prefetchGroupsInfo(forum, courseId, forum.cancreatediscussions, siteId)); | ||||
| 
 | ||||
|                 // Prefetch avatars.
 | ||||
|                 promises.push(this.userProvider.prefetchUserAvatars(posts, 'userpictureurl', siteId)); | ||||
| 
 | ||||
|                 return Promise.all(promises); | ||||
|             })); | ||||
| 
 | ||||
|             // Prefetch access information.
 | ||||
|             promises.push(this.forumProvider.getAccessInformation(forum.id)); | ||||
|             promises.push(this.forumProvider.getAccessInformation(forum.id, false, siteId)); | ||||
| 
 | ||||
|             // Prefetch sort order preference.
 | ||||
|             if (this.forumProvider.isDiscussionListSortingAvailable()) { | ||||
|                promises.push(this.userProvider.getUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER)); | ||||
|                promises.push(this.userProvider.getUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER, siteId)); | ||||
|             } | ||||
| 
 | ||||
|             return Promise.all(promises); | ||||
| @ -247,30 +238,31 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand | ||||
|      * @param module The module object returned by WS. | ||||
|      * @param courseI Course ID the module belongs to. | ||||
|      * @param canCreateDiscussions Whether the user can create discussions in the forum. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @return Promise resolved when group data has been prefetched. | ||||
|      */ | ||||
|     protected prefetchGroupsInfo(forum: any, courseId: number, canCreateDiscussions: boolean): any { | ||||
|     protected prefetchGroupsInfo(forum: any, courseId: number, canCreateDiscussions: boolean, siteId?: string): any { | ||||
|         // Check group mode.
 | ||||
|         return this.groupsProvider.getActivityGroupMode(forum.cmid).then((mode) => { | ||||
|         return this.groupsProvider.getActivityGroupMode(forum.cmid, siteId).then((mode) => { | ||||
|             if (mode !== CoreGroupsProvider.SEPARATEGROUPS && mode !== CoreGroupsProvider.VISIBLEGROUPS) { | ||||
|                 // Activity doesn't use groups. Prefetch canAddDiscussionToAll to determine if user can pin/attach.
 | ||||
|                 return this.forumProvider.canAddDiscussionToAll(forum.id).catch(() => { | ||||
|                 return this.forumProvider.canAddDiscussionToAll(forum.id, siteId).catch(() => { | ||||
|                         // Ignore errors.
 | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
|             // Activity uses groups, prefetch allowed groups.
 | ||||
|             return this.groupsProvider.getActivityAllowedGroups(forum.cmid).then((result) => { | ||||
|             return this.groupsProvider.getActivityAllowedGroups(forum.cmid, undefined, siteId).then((result) => { | ||||
|                 if (mode === CoreGroupsProvider.SEPARATEGROUPS) { | ||||
|                     // Groups are already filtered by WS. Prefetch canAddDiscussionToAll to determine if user can pin/attach.
 | ||||
|                     return this.forumProvider.canAddDiscussionToAll(forum.id).catch(() => { | ||||
|                     return this.forumProvider.canAddDiscussionToAll(forum.id, siteId).catch(() => { | ||||
|                         // Ignore errors.
 | ||||
|                     }); | ||||
|                 } | ||||
| 
 | ||||
|                 if (canCreateDiscussions) { | ||||
|                     // Prefetch data to check the visible groups when creating discussions.
 | ||||
|                     return this.forumProvider.canAddDiscussionToAll(forum.id).catch(() => { | ||||
|                     return this.forumProvider.canAddDiscussionToAll(forum.id, siteId).catch(() => { | ||||
|                         // The call failed, let's assume he can't.
 | ||||
|                         return { | ||||
|                             status: false | ||||
| @ -284,7 +276,7 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand | ||||
|                         // The user can't post to all groups, let's check which groups he can post to.
 | ||||
|                         const groupPromises = []; | ||||
|                         result.groups.forEach((group) => { | ||||
|                             groupPromises.push(this.forumProvider.canAddDiscussion(forum.id, group.id).catch(() => { | ||||
|                             groupPromises.push(this.forumProvider.canAddDiscussion(forum.id, group.id, siteId).catch(() => { | ||||
|                                 // Ignore errors.
 | ||||
|                             })); | ||||
|                         }); | ||||
|  | ||||
| @ -26,6 +26,7 @@ import { AddonModGlossaryProvider } from './glossary'; | ||||
| import { AddonModGlossarySyncProvider } from './sync'; | ||||
| import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||
| import { CorePluginFileDelegate } from '@providers/plugin-file-delegate'; | ||||
| import { CoreUserProvider } from '@core/user/providers/user'; | ||||
| 
 | ||||
| /** | ||||
|  * Handler to prefetch forums. | ||||
| @ -48,7 +49,8 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchH | ||||
|             pluginFileDelegate: CorePluginFileDelegate, | ||||
|             protected glossaryProvider: AddonModGlossaryProvider, | ||||
|             protected commentsProvider: CoreCommentsProvider, | ||||
|             protected syncProvider: AddonModGlossarySyncProvider) { | ||||
|             protected syncProvider: AddonModGlossarySyncProvider, | ||||
|             protected userProvider: CoreUserProvider) { | ||||
| 
 | ||||
|         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils, filterHelper, | ||||
|                 pluginFileDelegate); | ||||
| @ -165,35 +167,29 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchH | ||||
|             // Fetch all entries to get information from.
 | ||||
|             promises.push(this.glossaryProvider.fetchAllEntries(this.glossaryProvider.getEntriesByLetter, | ||||
|                     [glossary.id, 'ALL'], false, false, siteId).then((entries) => { | ||||
|                 const promises = [], | ||||
|                     commentsEnabled = !this.commentsProvider.areCommentsDisabledInSite(), | ||||
|                     avatars = {}; // List of user avatars, preventing duplicates.
 | ||||
|                 const promises = []; | ||||
|                 const commentsEnabled = !this.commentsProvider.areCommentsDisabledInSite(); | ||||
| 
 | ||||
|                 entries.forEach((entry) => { | ||||
|                     // Don't fetch individual entries, it's too many WS calls.
 | ||||
| 
 | ||||
|                     if (entry.userpictureurl) { | ||||
|                         avatars[entry.userpictureurl] = true; | ||||
|                     } | ||||
| 
 | ||||
|                     if (glossary.allowcomments && commentsEnabled) { | ||||
|                         promises.push(this.commentsProvider.getComments('module', glossary.coursemodule, 'mod_glossary', entry.id, | ||||
|                             'glossary_entry', 0, siteId)); | ||||
|                     } | ||||
|                 }); | ||||
| 
 | ||||
|                 // Prefetch intro files, entries files and user avatars.
 | ||||
|                 const avatarFiles = Object.keys(avatars).map((url) => { | ||||
|                     return { fileurl: url }; | ||||
|                 }); | ||||
|                 const files = this.getFilesFromGlossaryAndEntries(module, glossary, entries).concat(avatarFiles); | ||||
|                 const files = this.getFilesFromGlossaryAndEntries(module, glossary, entries); | ||||
|                 promises.push(this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id)); | ||||
| 
 | ||||
|                 // Prefetch user avatars.
 | ||||
|                 promises.push(this.userProvider.prefetchUserAvatars(entries, 'userpictureurl', siteId)); | ||||
| 
 | ||||
|                 return Promise.all(promises); | ||||
|             })); | ||||
| 
 | ||||
|             // Get all categories.
 | ||||
|             promises.push(this.glossaryProvider.getAllCategories(glossary.id)); | ||||
|             promises.push(this.glossaryProvider.getAllCategories(glossary.id, siteId)); | ||||
| 
 | ||||
|             // Prefetch data for link handlers.
 | ||||
|             promises.push(this.courseProvider.getModuleBasicInfo(module.id, siteId)); | ||||
|  | ||||
| @ -375,9 +375,7 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchH | ||||
|             }); | ||||
|         }).then(() => { | ||||
|             // Prefetch user profiles.
 | ||||
|             return this.userProvider.prefetchProfiles(userIds, courseId, siteId).catch(() => { | ||||
|                 // Ignore errors.
 | ||||
|             }); | ||||
|             return this.userProvider.prefetchProfiles(userIds, courseId, siteId); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -522,8 +522,10 @@ export class CoreUserProvider { | ||||
| 
 | ||||
|                 promises.push(this.getProfile(userId, courseId, false, siteId).then((profile) => { | ||||
|                     if (profile.profileimageurl) { | ||||
|                         this.filepoolProvider.addToQueueByUrl(siteId, profile.profileimageurl); | ||||
|                         return this.filepoolProvider.addToQueueByUrl(siteId, profile.profileimageurl); | ||||
|                     } | ||||
|                 }).catch((error) => { | ||||
|                     this.logger.warn(`Ignore error when prefetching user ${userId}`, error); | ||||
|                 })); | ||||
|             } | ||||
|         }); | ||||
| @ -531,6 +533,39 @@ export class CoreUserProvider { | ||||
|         return Promise.all(promises); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Prefetch user avatars. It prevents duplicates. | ||||
|      * | ||||
|      * @param entries List of entries that have the images. | ||||
|      * @param propertyName The name of the property that contains the image. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @return Promise resolved when prefetched. | ||||
|      */ | ||||
|     async prefetchUserAvatars(entries: any[], propertyName: string, siteId?: string): Promise<void> { | ||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|         const treated = {}; | ||||
| 
 | ||||
|         const promises = entries.map(async (entry) => { | ||||
|             const imageUrl = entry[propertyName]; | ||||
| 
 | ||||
|             if (!imageUrl || treated[imageUrl]) { | ||||
|                 // It doesn't have an image or it has already been treated.
 | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             treated[imageUrl] = true; | ||||
| 
 | ||||
|             try { | ||||
|                 await this.filepoolProvider.addToQueueByUrl(siteId, imageUrl); | ||||
|             } catch (ex) { | ||||
|                 this.logger.warn(`Ignore error when prefetching user avatar ${imageUrl}`, entry, ex); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         await Promise.all(promises); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Search participants in a certain course. | ||||
|      * | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user