MOBILE-3903 enrol: Check guest first for course/view links
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…
Reference in New Issue