MOBILE-3903 enrol: Check guest first for course/view links

main
Dani Palou 2021-11-04 11:48:53 +01:00
parent 2de6c75f2a
commit 432f9b03ec
1 changed files with 76 additions and 76 deletions

View File

@ -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);
});
} }
} }