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