MOBILE-3903 enrol: Check guest first for course/view links
This commit is contained in:
		
							parent
							
								
									2de6c75f2a
								
							
						
					
					
						commit
						432f9b03ec
					
				| @ -90,7 +90,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
| 
 | 
 | ||||||
|                         return; |                         return; | ||||||
|                     } else { |                     } else { | ||||||
|                         this.actionEnrol(courseId, url, pageParams).catch(() => { |                         this.actionOpen(courseId, url, pageParams).catch(() => { | ||||||
|                             // Ignore errors.
 |                             // Ignore errors.
 | ||||||
|                         }); |                         }); | ||||||
|                     } |                     } | ||||||
| @ -124,14 +124,14 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Action to perform when an enrol link is clicked. |      * Try to open the course, asking the user to enrol if needed. | ||||||
|      * |      * | ||||||
|      * @param courseId Course ID. |      * @param courseId Course ID. | ||||||
|      * @param url Treated URL. |      * @param url Treated URL. | ||||||
|      * @param pageParams Params to send to the new page. |      * @param pageParams Params to send to the new page. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     protected async actionEnrol(courseId: number, url: string, pageParams: Params): Promise<void> { |     protected async actionOpen(courseId: number, url: string, pageParams: Params): Promise<void> { | ||||||
|         const modal = await CoreDomUtils.showModalLoading(); |         const modal = await CoreDomUtils.showModalLoading(); | ||||||
|         let course: CoreCourseAnyCourseData | { id: number } | undefined; |         let course: CoreCourseAnyCourseData | { id: number } | undefined; | ||||||
| 
 | 
 | ||||||
| @ -167,95 +167,102 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
|      * @param modal Modal, to dismiss when needed. |      * @param modal Modal, to dismiss when needed. | ||||||
|      * @return The course after self enrolling or undefined if the user has access but is not enrolled. |      * @return The course after self enrolling or undefined if the user has access but is not enrolled. | ||||||
|      */ |      */ | ||||||
|     protected checkSelfUserCanSelfEnrolOrAccess( |     protected async checkSelfUserCanSelfEnrolOrAccess( | ||||||
|         courseId: number, |         courseId: number, | ||||||
|         url: string, |         url: string, | ||||||
|         modal: CoreIonLoadingElement, |         modal: CoreIonLoadingElement, | ||||||
|     ): Promise<CoreEnrolledCourseData | undefined> { |     ): Promise<CoreEnrolledCourseData | undefined> { | ||||||
|         // User is not enrolled in the course. Check if can self enrol.
 |         const isEnrolUrl = !!url.match(/(\/enrol\/index\.php)|(\/course\/enrol\.php)/); | ||||||
|         return this.canSelfEnrol(courseId).then(async () => { |  | ||||||
|             modal.dismiss(); |  | ||||||
| 
 | 
 | ||||||
|             const isEnrolUrl = !!url.match(/(\/enrol\/index\.php)|(\/course\/enrol\.php)/); |         if (!isEnrolUrl) { | ||||||
|  |             // Not an enrol URL, check if the user can access the course (e.g. guest access).
 | ||||||
|  |             const canAccess = await this.canAccess(courseId); | ||||||
|  |             if (canAccess) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|             // The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
 |         // User cannot access the course or it's an enrol URL. Check if can self enrol.
 | ||||||
|             if (!isEnrolUrl) { |         const canSelfEnrol = await this.canSelfEnrol(courseId); | ||||||
|                 try { |  | ||||||
|                     await CoreDomUtils.showConfirm(Translate.instant('core.courses.confirmselfenrol')); |  | ||||||
|                 } catch { |  | ||||||
|                     // User cancelled. Check if the user can view the course contents (guest access or similar).
 |  | ||||||
|                     await CoreCourse.getSections(courseId, false, true); |  | ||||||
| 
 | 
 | ||||||
|  |         if (!canSelfEnrol) { | ||||||
|  |             if (isEnrolUrl) { | ||||||
|  |                 // Cannot self enrol, check if the user can access the course (e.g. guest access).
 | ||||||
|  |                 const canAccess = await this.canAccess(courseId); | ||||||
|  |                 if (canAccess) { | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Enrol URL or user confirmed.
 |             // Cannot self enrol and cannot access. Show error and allow the user to open the link in browser.
 | ||||||
|             try { |             modal.dismiss(); | ||||||
|                 return this.selfEnrol(courseId); |             const notEnrolledMessage = Translate.instant('core.courses.notenroled'); | ||||||
|             } catch (error) { |             const body = CoreTextUtils.buildSeveralParagraphsMessage( | ||||||
|                 if (error) { |                 [notEnrolledMessage, Translate.instant('core.confirmopeninbrowser')], | ||||||
|                     CoreDomUtils.showErrorModal(error); |             ); | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 throw error; |  | ||||||
|             } |  | ||||||
|         }, async (error) => { |  | ||||||
|             // Can't self enrol. Check if the user can view the course contents (guest access or similar).
 |  | ||||||
|             try { |             try { | ||||||
|                 await CoreCourse.getSections(courseId, false, true); |                 await CoreDomUtils.showConfirm(body); | ||||||
|  | 
 | ||||||
|  |                 CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(url, undefined, { showBrowserWarning: false }); | ||||||
|             } catch { |             } catch { | ||||||
|                 // Error. Show error message and allow the user to open the link in browser.
 |                 // User cancelled.
 | ||||||
|                 modal.dismiss(); |             }; | ||||||
| 
 | 
 | ||||||
|                 if (error) { |             throw new CoreError(notEnrolledMessage); | ||||||
|                     error = CoreTextUtils.getErrorMessageFromError(error) || error; |         } | ||||||
|                 } |  | ||||||
|                 if (!error) { |  | ||||||
|                     error = Translate.instant('core.courses.notenroled'); |  | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 const body = CoreTextUtils.buildSeveralParagraphsMessage( |         // The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
 | ||||||
|                     [error, Translate.instant('core.confirmopeninbrowser')], |         modal.dismiss(); | ||||||
|                 ); |  | ||||||
| 
 | 
 | ||||||
|                 try { |         if (!isEnrolUrl) { | ||||||
|                     await CoreDomUtils.showConfirm(body); |             await CoreDomUtils.showConfirm(Translate.instant('core.courses.confirmselfenrol')); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|                     CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(url, undefined, { showBrowserWarning: false }); |         try { | ||||||
|                 } catch { |             return await this.selfEnrol(courseId); | ||||||
|                     // User cancelled.
 |         } catch (error) { | ||||||
|                 }; |             if (error) { | ||||||
| 
 |                 CoreDomUtils.showErrorModal(error); | ||||||
|                 throw error; |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return undefined; |             throw error; | ||||||
|         }); |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if user can access the course. | ||||||
|  |      * | ||||||
|  |      * @param courseId Course ID. | ||||||
|  |      * @return Promise resolved with boolean: whether user can access the course. | ||||||
|  |      */ | ||||||
|  |     protected canAccess(courseId: number): Promise<boolean> { | ||||||
|  |         return CoreUtils.promiseWorks(CoreCourse.getSections(courseId, false, true)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Check if a user can be "automatically" self enrolled in a course. |      * Check if a user can be "automatically" self enrolled in a course. | ||||||
|      * |      * | ||||||
|      * @param courseId Course ID. |      * @param courseId Course ID. | ||||||
|      * @return Promise resolved if user can be enrolled in a course, rejected otherwise. |      * @return Promise resolved with boolean: whether the user can be enrolled in a course. | ||||||
|      */ |      */ | ||||||
|     protected async canSelfEnrol(courseId: number): Promise<void> { |     protected async canSelfEnrol(courseId: number): Promise<boolean> { | ||||||
|         // Check that the course has self enrolment enabled.
 |         try { | ||||||
|  |             // Check that the course has self enrolment enabled.
 | ||||||
|  |             const methods = await CoreCourses.getCourseEnrolmentMethods(courseId); | ||||||
| 
 | 
 | ||||||
|         const methods = await CoreCourses.getCourseEnrolmentMethods(courseId); |             let isSelfEnrolEnabled = false; | ||||||
|         let isSelfEnrolEnabled = false; |             let instances = 0; | ||||||
|         let instances = 0; |             methods.forEach((method) => { | ||||||
|         methods.forEach((method) => { |                 if (method.type == 'self' && method.status) { | ||||||
|             if (method.type == 'self' && method.status) { |                     isSelfEnrolEnabled = true; | ||||||
|                 isSelfEnrolEnabled = true; |                     instances++; | ||||||
|                 instances++; |                 } | ||||||
|             } |             }); | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         if (!isSelfEnrolEnabled || instances != 1) { |             return isSelfEnrolEnabled && instances === 1; | ||||||
|             // Self enrol not enabled or more than one instance.
 |         } catch { | ||||||
|             throw new CoreError('Self enrol not enabled in course'); |             return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -272,12 +279,9 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
|         try { |         try { | ||||||
|             await CoreCourses.selfEnrol(courseId, password); |             await CoreCourses.selfEnrol(courseId, password); | ||||||
| 
 | 
 | ||||||
|             // Success self enrolling the user, invalidate the courses list.
 |  | ||||||
|             await CoreUtils.ignoreErrors(CoreCourses.invalidateUserCourses()); |  | ||||||
| 
 |  | ||||||
|             try { |             try { | ||||||
|                 // Sometimes the list of enrolled courses takes a while to be updated. Wait for it.
 |                 // Sometimes the list of enrolled courses takes a while to be updated. Wait for it.
 | ||||||
|                 return this.waitForEnrolled(courseId, true); |                 return await this.waitForEnrolled(courseId, true); | ||||||
|             } finally { |             } finally { | ||||||
|                 modal.dismiss(); |                 modal.dismiss(); | ||||||
|             } |             } | ||||||
| @ -297,7 +301,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
| 
 | 
 | ||||||
|                 password = await CoreDomUtils.showPrompt(body, title, placeholder); |                 password = await CoreDomUtils.showPrompt(body, title, placeholder); | ||||||
| 
 | 
 | ||||||
|                 return this.selfEnrol(courseId, password); |                 await this.selfEnrol(courseId, password); | ||||||
|             } else { |             } else { | ||||||
|                 throw error; |                 throw error; | ||||||
|             } |             } | ||||||
| @ -319,21 +323,17 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
|         // Check if user is enrolled in the course.
 |         // Check if user is enrolled in the course.
 | ||||||
|         await CoreUtils.ignoreErrors(CoreCourses.invalidateUserCourses()); |         await CoreUtils.ignoreErrors(CoreCourses.invalidateUserCourses()); | ||||||
|         try { |         try { | ||||||
|             return CoreCourses.getUserCourse(courseId); |             return await CoreCourses.getUserCourse(courseId); | ||||||
|         } catch { |         } catch { | ||||||
| 
 |  | ||||||
|             // Not enrolled, wait a bit and try again.
 |             // Not enrolled, wait a bit and try again.
 | ||||||
|             if (Date.now() - this.waitStart > 60000) { |             if (Date.now() - this.waitStart > 60000) { | ||||||
|                 // Max time reached, stop.
 |                 // Max time reached, stop.
 | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return new Promise((resolve, reject): void => { |             await CoreUtils.wait(5000); | ||||||
|                 setTimeout(() => { | 
 | ||||||
|                     this.waitForEnrolled(courseId) |             return await this.waitForEnrolled(courseId); | ||||||
|                         .then(resolve).catch(reject); |  | ||||||
|                 }, 5000); |  | ||||||
|             }); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user