Index: lams_build/lib/lams/lams-monitoring.jar =================================================================== diff -u -r1b3256ab2070e6b8b91c1c5df04b5ad0e52635a2 -r8fc48568c579f2b32041d489a8ebf02075847fa3 Binary files differ Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 Binary files differ Index: lams_central/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r76986ed39cc2a2f0ca8e98ea1d8f2e36fed03903 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 76986ed39cc2a2f0ca8e98ea1d8f2e36fed03903) +++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -438,7 +438,8 @@ label.course.groups.grouping.use.confirm =Are you sure you want to use grouping "[0]"? Groups will be created for this lesson and learners assigned to them. label.course.groups.locked =Some users in this group already used the grouping. The group is now locked: you can not remove it or move users to another group. label.course.groups.locked.transfer =Are you sure you want to move these users to a locked group? You will not be allowed to move them to another group later. -label.tab.advanced.field.restart =Learners always start from the first activity +label.tab.advanced.field.force.restart =Learners always start from the first activity +label.tab.advanced.field.allow.restart =Learners can restart the lesson error.firstname.invalid.characters =First name contains invalid characters error.lastname.invalid.characters =Last name contains invalid characters error.username.invalid.characters =Username can only contain alphanumeric characters and no spaces. Index: lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java =================================================================== diff -u -rd0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java (.../AuthoringAction.java) (revision d0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java (.../AuthoringAction.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -205,7 +205,6 @@ public ActionForward getToolOutputDefinitionsJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, JSONException { - String wddxPacket; IAuthoringService authoringService = getAuthoringService(); Long toolContentID = WebUtil.readLongParam(request, "toolContentID"); Integer definitionType = ToolOutputDefinition.DATA_OUTPUT_DEFINITION_TYPE_CONDITION; @@ -479,7 +478,7 @@ if (learningDesignID != null) { User user = (User) getUserManagementService().findById(User.class, userID); Lesson lesson = getMonitoringService().initializeLessonWithoutLDcopy(title, "", learningDesignID, user, - null, false, false, true, false, false, true, true, false, null, null); + null, false, false, true, false, false, true, true, false, false, null, null); Organisation organisation = getMonitoringService().getOrganisation(organisationID); List staffList = new LinkedList(); Index: lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java =================================================================== diff -u -rd0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java (.../HomeAction.java) (revision d0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa) +++ lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java (.../HomeAction.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -198,7 +198,7 @@ return mapping.findForward("lessonIntro"); } - if (lesson.getLearnerRestart()) { + if (lesson.getForceLearnerRestart()) { // start the lesson from the beginning each time getLessonService().removeLearnerProgress(lessonId, user.getUserID()); } @@ -217,6 +217,7 @@ req.setAttribute(AttributeNames.PARAM_LESSON_ID, String.valueOf(lessonId)); req.setAttribute(AttributeNames.PARAM_EXPORT_PORTFOLIO_ENABLED, String.valueOf(isPortfolioEnabled)); + req.setAttribute("allowRestart", lesson.getAllowLearnerRestart()); req.setAttribute(AttributeNames.PARAM_PRESENCE_ENABLED, String.valueOf(lesson.getLearnerPresenceAvailable())); req.setAttribute(AttributeNames.PARAM_PRESENCE_IM_ENABLED, String.valueOf(lesson.getLearnerImAvailable())); @@ -453,15 +454,14 @@ url += URLEncoder.encode(Configuration.get(ConfigurationKeys.SERVER_URL), "UTF8"); res.sendRedirect(url); return null; + } + + req.getSession().invalidate(); - } else { - req.getSession().invalidate(); + // clear system shared session. + SessionManager.getSession().invalidate(); - // clear system shared session. - SessionManager.getSession().invalidate(); - - return mapping.findForward("index"); - } + return mapping.findForward("index"); } private ActionForward displayMessage(ActionMapping mapping, HttpServletRequest req, String messageKey) { Index: lams_central/src/java/org/lamsfoundation/lams/webservice/LessonManagerSoapBindingImpl.java =================================================================== diff -u -raa6023fdecba00eb9a7df76e834e681f7d58462d -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/src/java/org/lamsfoundation/lams/webservice/LessonManagerSoapBindingImpl.java (.../LessonManagerSoapBindingImpl.java) (revision aa6023fdecba00eb9a7df76e834e681f7d58462d) +++ lams_central/src/java/org/lamsfoundation/lams/webservice/LessonManagerSoapBindingImpl.java (.../LessonManagerSoapBindingImpl.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -85,7 +85,7 @@ // 1. init lesson Lesson lesson = LessonManagerSoapBindingImpl.monitoringService.initializeLesson(title, desc, ldId, orgMap.getOrganisation().getOrganisationId(), userMap.getUser().getUserId(), customCSV, false, - false, true, false, false, false, false, false, null, null); + false, true, false, false, false, false, false, false, null, null); // 2. create lessonClass for lesson createLessonClass(lesson, orgMap.getOrganisation(), userMap.getUser()); // 3. start lesson @@ -111,7 +111,7 @@ // 1. init lesson Lesson lesson = LessonManagerSoapBindingImpl.monitoringService.initializeLesson(title, desc, ldId, orgMap.getOrganisation().getOrganisationId(), userMap.getUser().getUserId(), customCSV, false, - false, true, false, false, false, false, false, null, null); + false, true, false, false, false, false, false, false, null, null); // 2. create lessonClass for lesson createLessonClass(lesson, orgMap.getOrganisation(), userMap.getUser()); // 3. schedule lesson Index: lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonJoinServlet.java =================================================================== diff -u -rd0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonJoinServlet.java (.../LessonJoinServlet.java) (revision d0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa) +++ lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonJoinServlet.java (.../LessonJoinServlet.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.webservice.xml; import java.io.IOException; @@ -264,7 +263,8 @@ Boolean learnerImAvailable; Boolean liveEditEnabled; Boolean enableNotifications; - Boolean learnerRestart; + Boolean forceLearnerRestart; + Boolean allowLearnerRestart; Integer ownerUserId; Organisation org = (Organisation) LessonJoinServlet.userService.findById(Organisation.class, orgId); String learnerGroupName; @@ -285,7 +285,8 @@ learnerImAvailable = l.getLearnerImAvailable(); liveEditEnabled = l.getLiveEditEnabled(); enableNotifications = l.getEnableLessonNotifications(); - learnerRestart = l.getLearnerRestart(); + forceLearnerRestart = l.getForceLearnerRestart(); + allowLearnerRestart = l.getAllowLearnerRestart(); ownerUserId = l.getUser().getUserId(); learnerGroupName = l.getLessonClass().getLearnersGroup().getGroupName(); staffGroupName = l.getLessonClass().getStaffGroup().getGroupName(); @@ -302,7 +303,8 @@ learnerImAvailable = false; liveEditEnabled = false; enableNotifications = false; - learnerRestart = false; + forceLearnerRestart = false; + allowLearnerRestart = false; ownerUserId = ld.getUser().getUserId(); learnerGroupName = org.getName() + " Learners"; staffGroupName = org.getName() + " Staff"; @@ -312,8 +314,8 @@ } Lesson lesson = LessonJoinServlet.monitoringService.initializeLesson(lessonName, lessonDescription, ldId, orgId, ownerUserId, null, enableLessonIntro, displayDesignImage, learnerExportAvailable, - learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, enableNotifications, learnerRestart, - null, null); + learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, enableNotifications, forceLearnerRestart, + allowLearnerRestart, null, null); LessonJoinServlet.monitoringService.createLessonClassForLesson(lesson.getLessonId().longValue(), org, learnerGroupName, learnerList, staffGroupName, staffList, ownerUserId); LessonJoinServlet.monitoringService.startLesson(lesson.getLessonId().longValue(), ownerUserId); Index: lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java =================================================================== diff -u -r5ea5e36c009862ebc75c7d0575ddd056e76f957e -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java (.../LessonManagerServlet.java) (revision 5ea5e36c009862ebc75c7d0575ddd056e76f957e) +++ lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java (.../LessonManagerServlet.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -147,7 +147,8 @@ boolean presenceEnable = WebUtil.readBooleanParam(request, CentralConstants.PARAM_LEARNER_PRESENCE_ENABLE, false); boolean imEnable = WebUtil.readBooleanParam(request, CentralConstants.PARAM_LEARNER_IM_ENABLE, false); - boolean enableNotifications = WebUtil.readBooleanParam(request, CentralConstants.PARAM_ENABLE_NOTIFICATIONS, false); + boolean enableNotifications = WebUtil.readBooleanParam(request, CentralConstants.PARAM_ENABLE_NOTIFICATIONS, + false); Long ldId = null; Long lsId = null; @@ -375,7 +376,7 @@ // 1. init lesson Lesson lesson = LessonManagerServlet.monitoringService.initializeLesson(title, desc, ldId, organisation.getOrganisationId(), user.getUserId(), customCSV, false, false, exportPortfolioEnable, - presenceEnable, imEnable, true, enableNotifications, false, null, null); + presenceEnable, imEnable, true, enableNotifications, false, false, null, null); // 2. create lessonClass for lesson createLessonClass(lesson, organisation, user); // 3. start lesson @@ -402,8 +403,8 @@ // 1. init lesson Lesson lesson = LessonManagerServlet.monitoringService.initializeLesson(title, desc, ldId, orgMap.getOrganisation().getOrganisationId(), userMap.getUser().getUserId(), customCSV, false, - false, exportPortfolioEnable, presenceEnable, imEnable, true, enableNotifications, false, null, - null); + false, exportPortfolioEnable, presenceEnable, imEnable, true, enableNotifications, false, false, + null, null); // 2. create lessonClass for lesson createLessonClass(lesson, orgMap.getOrganisation(), userMap.getUser()); // 3. schedule lesson Index: lams_central/web/addLesson.jsp =================================================================== diff -u -rfa2ad14fcf969120bc068f9b22e1fcebf62ce39d -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_central/web/addLesson.jsp (.../addLesson.jsp) (revision fa2ad14fcf969120bc068f9b22e1fcebf62ce39d) +++ lams_central/web/addLesson.jsp (.../addLesson.jsp) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -190,7 +190,8 @@

-
+
+



Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/lesson/Lesson.hbm.xml =================================================================== diff -u -rc85eeb30f32d1551d97688e0153f5c81839f03d3 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/lesson/Lesson.hbm.xml (.../Lesson.hbm.xml) (revision c85eeb30f32d1551d97688e0153f5c81839f03d3) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/lesson/Lesson.hbm.xml (.../Lesson.hbm.xml) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -76,9 +76,12 @@ - + + + Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch2040064.sql =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch2040064.sql (.../patch2040064.sql) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch2040064.sql (.../patch2040064.sql) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -1,6 +1,9 @@ -- Turn off autocommit, so nothing is committed if there is an error SET AUTOCOMMIT = 0; +-- LDEV-3839: Lesson restart + +-- Tables for archiving learner progress CREATE TABLE lams_learner_progress_archive ( learner_progress_id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, @@ -45,5 +48,10 @@ REFERENCES lams_learning_activity (activity_id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +-- make restart an option +ALTER TABLE lams_lesson CHANGE COLUMN learner_restart force_restart tinyint(1) DEFAULT '0', + ADD COLUMN allow_restart tinyint(1) DEFAULT '0'; + + COMMIT; SET AUTOCOMMIT = 1; \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/lesson/Lesson.java =================================================================== diff -u -rd0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_common/src/java/org/lamsfoundation/lams/lesson/Lesson.java (.../Lesson.java) (revision d0b6f213cba1026b0c9fdbdaa5dd44a49eddd3aa) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/Lesson.java (.../Lesson.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -161,10 +161,17 @@ /** * Should Learner start the lesson from the beginning each time he enters it. + * Content is not removed, LessonProgress is deleted, not archived. */ - private Boolean learnerRestart; + private Boolean forceLearnerRestart; /** + * Should Learners be allowed to restart the lesson after finishing it. + * Content is not removed, LessonProgress is archived and then deleted. + */ + private Boolean allowLearnerRestart; + + /** * For lesson conditional release */ private Set precedingLessons; @@ -185,11 +192,12 @@ Integer previousLessonStateId, LearningDesign learningDesign, Set learnerProgresses, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, - Boolean enableLessonNotifications, Boolean learnerRestart, Integer scheduledNumberDaysTolessonFinish) { + Boolean enableLessonNotifications, Boolean forceLearnerRestart, Boolean allowLearnerRestart, + Integer scheduledNumberDaysTolessonFinish) { this(null, name, description, createDateTime, null, null, user, lessonStateId, previousLessonStateId, enableLessonIntro, displayDesignImage, learnerExportAvailable, false, learningDesign, null, null, learnerProgresses, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, - enableLessonNotifications, learnerRestart, scheduledNumberDaysTolessonFinish); + enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, scheduledNumberDaysTolessonFinish); } /** full constructor */ @@ -198,8 +206,8 @@ Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean lockedForEdit, LearningDesign learningDesign, LessonClass lessonClass, Organisation organisation, Set learnerProgresses, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean learnerRestart, - Integer scheduledNumberDaysToLessonFinish) { + Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, + Boolean allowLearnerRestart, Integer scheduledNumberDaysToLessonFinish) { this.lessonId = lessonId; this.lessonName = name; this.lessonDescription = description; @@ -221,7 +229,8 @@ this.learnerProgresses = learnerProgresses; this.liveEditEnabled = liveEditEnabled; this.enableLessonNotifications = enableLessonNotifications; - this.learnerRestart = learnerRestart; + this.forceLearnerRestart = forceLearnerRestart; + this.allowLearnerRestart = allowLearnerRestart; this.gradebookUserLessons = new HashSet(); this.marksReleased = false; this.scheduledNumberDaysToLessonFinish = scheduledNumberDaysToLessonFinish; @@ -242,11 +251,12 @@ public static Lesson createNewLessonWithoutClass(String lessonName, String lessonDescription, User user, LearningDesign ld, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, - Boolean enableLessonNotifications, Boolean learnerRestart, Integer scheduledNumberDaysToLessonFinish) { + Boolean enableLessonNotifications, Boolean forceLearnerRestart, Boolean allowLearnerRestart, + Integer scheduledNumberDaysToLessonFinish) { return new Lesson(lessonName, lessonDescription, new Date(System.currentTimeMillis()), user, Lesson.CREATED, null, ld, new HashSet(), enableLessonIntro, displayDesignImage, learnerExportAvailable, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, enableLessonNotifications, - learnerRestart, scheduledNumberDaysToLessonFinish); + forceLearnerRestart, allowLearnerRestart, scheduledNumberDaysToLessonFinish); } // --------------------------------------------------------------------- @@ -591,14 +601,22 @@ this.marksReleased = marksReleased; } - public Boolean getLearnerRestart() { - return learnerRestart; + public Boolean getForceLearnerRestart() { + return forceLearnerRestart; } - public void setLearnerRestart(Boolean learnerRestart) { - this.learnerRestart = learnerRestart; + public void setForceLearnerRestart(Boolean forceLearnerRestart) { + this.forceLearnerRestart = forceLearnerRestart; } + public Boolean getAllowLearnerRestart() { + return allowLearnerRestart; + } + + public void setAllowLearnerRestart(Boolean allowLearnerRestart) { + this.allowLearnerRestart = allowLearnerRestart; + } + public Set getPrecedingLessons() { return precedingLessons; } Index: lams_learning/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_learning/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -125,6 +125,7 @@ label.learner.progress.support =Support Activities label.submit.button =Submit label.learner.progress.review.activity =Review activity +message.learner.progress.restart.confirm =Are you sure you want to start the lesson from the beginning? label.schedule.gate.reach =You have reached the gate on label.schedule.gate.offset.1 =The gate will only be opened label.schedule.gate.offset.2 =after. Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerServiceProxy.java =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerServiceProxy.java (.../LearnerServiceProxy.java) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerServiceProxy.java (.../LearnerServiceProxy.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -26,7 +26,7 @@ import javax.servlet.ServletContext; import org.lamsfoundation.lams.learning.web.util.ActivityMapping; -import org.lamsfoundation.lams.monitoring.service.IMonitoringService; +import org.lamsfoundation.lams.lesson.service.ILessonService; import org.lamsfoundation.lams.tool.service.ILamsToolService; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.springframework.web.context.WebApplicationContext; @@ -81,8 +81,8 @@ return (ILamsToolService) LearnerServiceProxy.getDomainService(serlvetContext, "lamsToolService"); } - public static final IMonitoringService getMonitoringService(ServletContext servletContext) { - return (IMonitoringService) LearnerServiceProxy.getDomainService(servletContext, "monitoringService"); + public static final ILessonService getLessonService(ServletContext servletContext) { + return (ILessonService) LearnerServiceProxy.getDomainService(servletContext, "lessonService"); } /** Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java (.../CompleteActivityAction.java) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java (.../CompleteActivityAction.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -89,7 +89,9 @@ if (lessonFinishCallbackUrl != null) { request.setAttribute("lessonFinishUrl", lessonFinishCallbackUrl); } - request.setAttribute("lessonID", progress.getLesson().getLessonId()); + if (progress.getLesson().getAllowLearnerRestart()) { + request.setAttribute("lessonID", progress.getLesson().getLessonId()); + } } ActionForward forward = null; Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java (.../LearnerAction.java) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java (.../LearnerAction.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -55,7 +55,7 @@ import org.lamsfoundation.lams.lesson.LearnerProgressArchive; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.dto.LessonDTO; -import org.lamsfoundation.lams.monitoring.service.IMonitoringService; +import org.lamsfoundation.lams.lesson.service.ILessonService; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; @@ -317,11 +317,9 @@ attemptID, attemptedActivities, completedActivities, learnerProgress.getCurrentActivity(), learnerProgress.getLessonComplete(), learnerProgress.getStartDate(), learnerProgress.getFinishDate()); - // move learner to the beginning of lesson the same way Monitor can - IMonitoringService monitoringService = LearnerServiceProxy - .getMonitoringService(getServlet().getServletContext()); - monitoringService.forceCompleteActivitiesByUser(userID, userID, lessonID, - learnerProgress.getLesson().getLearningDesign().getFirstActivity().getActivityId(), true); + // remove learner progress + ILessonService lessonService = LearnerServiceProxy.getLessonService(getServlet().getServletContext()); + lessonService.removeLearnerProgress(lessonID, userID); IUserManagementService userManagementService = LearnerServiceProxy .getUserManagementService(getServlet().getServletContext()); @@ -567,7 +565,6 @@ ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); Object[] ret = learnerService.getStructuredActivityURLs(learnerId, lessonId); - ; request.setAttribute("progressList", ret[0]); request.setAttribute("currentActivityID", ret[1]); @@ -596,18 +593,8 @@ FlashMessage flashMessage = null; ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); ActivityMapping activityMapping = LearnerServiceProxy.getActivityMapping(this.getServlet().getServletContext()); - Long lessonId = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); try { - String url; - Activity targetActivity = forceMoveShared(request, learnerService, lessonId); - - if (!targetActivity.isFloating()) { - url = activityMapping.getDisplayActivityAction(null); - } else { - url = activityMapping.getActivityURL(targetActivity); - } - // TODO: update for moving to Floating Activity in Flash Learner flashMessage = new FlashMessage("forceMove", activityMapping.getDisplayActivityAction(null)); } catch (Exception e) { Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LessonCompleteActivityAction.java =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LessonCompleteActivityAction.java (.../LessonCompleteActivityAction.java) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LessonCompleteActivityAction.java (.../LessonCompleteActivityAction.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -87,7 +87,9 @@ request.setAttribute("lessonFinishUrl", lessonFinishCallbackUrl); } - request.setAttribute("lessonID", learnerProgress.getLesson().getLessonId()); + if (learnerProgress.getLesson().getAllowLearnerRestart()) { + request.setAttribute("lessonID", learnerProgress.getLesson().getLessonId()); + } return mapping.findForward("lessonComplete"); } Index: lams_learning/web/css/main.css =================================================================== diff -u -r4f1fbc9702e76416a24447db351e1aa3e0f996f5 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/web/css/main.css (.../main.css) (revision 4f1fbc9702e76416a24447db351e1aa3e0f996f5) +++ lams_learning/web/css/main.css (.../main.css) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -51,10 +51,14 @@ width: 50px; } -td#exportButtonCell { +td#exportButtonCell{ padding: 3px 2px 5px 0px; } +td#restartButtonCell { + padding: 1px 2px 0px 0px; +} + div#lessonTitleRow { overflow: hidden; text-overflow:ellipsis; Index: lams_learning/web/includes/javascript/main.js =================================================================== diff -u -r9438790401b957cdd70a4d6ab2a76da70176c6eb -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/web/includes/javascript/main.js (.../main.js) (revision 9438790401b957cdd70a4d6ab2a76da70176c6eb) +++ lams_learning/web/includes/javascript/main.js (.../main.js) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -7,6 +7,12 @@ "no"); } +function restartLesson(){ + if (confirm(LABELS.CONFIRM_RESTART)) { + $('#contentFrame').attr('src',APP_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId); + } +} + function viewNotebookEntries(){ openPopUp(APP_URL + "notebook.do?method=viewAll&lessonID=" + lessonId, "Notebook", Index: lams_learning/web/lessonComplete.jsp =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/web/lessonComplete.jsp (.../lessonComplete.jsp) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_learning/web/lessonComplete.jsp (.../lessonComplete.jsp) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -29,6 +29,14 @@ + +
@@ -54,10 +62,13 @@

-

- - -

+ <%-- lessonID is set in CompleteActivityAction and LessonCompleteActivityAction only if lesson.allowLearnerRestart is on --%> + +

+ + +

+

Index: lams_learning/web/main.jsp =================================================================== diff -u -re26df2fe8b638cd0b6ff7be060c07d593cd5b01d -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_learning/web/main.jsp (.../main.jsp) (revision e26df2fe8b638cd0b6ff7be060c07d593cd5b01d) +++ lams_learning/web/main.jsp (.../main.jsp) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -35,7 +35,9 @@ TOSTART_ACTIVITY : '', - SUPPORT_ACTIVITY : '' + SUPPORT_ACTIVITY : '', + + CONFIRM_RESTART : '' }, parentURL = "${notifyCloseURL}", @@ -97,17 +99,27 @@

- + + + Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java =================================================================== diff -u -r2592aad04b8de7be2f430cb66273f9bf78f75b11 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 2592aad04b8de7be2f430cb66273f9bf78f75b11) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.monitoring.service; import java.io.IOException; @@ -62,8 +61,8 @@ Lesson initializeLessonWithoutLDcopy(String lessonName, String lessonDescription, long learningDesignID, User user, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, - Boolean enableLessonNotifications, Boolean learnerRestart, Integer scheduledNumberDaysToLessonFinish, - Lesson precedingLesson); + Boolean enableLessonNotifications, Boolean forceLearnerRestart, Boolean allowLearnerRestart, + Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson); /** *

@@ -111,8 +110,8 @@ Lesson initializeLesson(String lessonName, String lessonDescription, long learningDesignId, Integer organisationId, Integer userID, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled, Boolean enableNotifications, Boolean learnerRestart, - Integer numberDaysToLessonFinish, Long precedingLessonId); + Boolean liveEditEnabled, Boolean enableNotifications, Boolean forceLearnerRestart, + Boolean allowLearnerRestart, Integer numberDaysToLessonFinish, Long precedingLessonId); /** * Initialize a new lesson so as to start the learning process for a normal or preview learning session. It needs to Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== diff -u -r65dc0e557544d65bf37488fbd11567599181ad84 -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 65dc0e557544d65bf37488fbd11567599181ad84) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -359,7 +359,8 @@ Integer organisationId, Integer userID, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, Boolean enableLessonNotifications, - Boolean learnerRestart, Integer scheduledNumberDaysToLessonFinish, Long precedingLessonId) { + Boolean forceLearnerRestart, Boolean allowLearnerRestart, Integer scheduledNumberDaysToLessonFinish, + Long precedingLessonId) { securityService.isGroupMonitor(organisationId, userID, "intializeLesson", true); @@ -389,7 +390,8 @@ Lesson initializedLesson = initializeLesson(lessonName, lessonDescription, originalLearningDesign, user, runSeqFolder, LearningDesign.COPY_TYPE_LESSON, customCSV, enableLessonIntro, displayDesignImage, learnerExportAvailable, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, - enableLessonNotifications, learnerRestart, scheduledNumberDaysToLessonFinish, precedingLesson); + enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, scheduledNumberDaysToLessonFinish, + precedingLesson); Long initializedLearningDesignId = initializedLesson.getLearningDesign().getLearningDesignId(); logEventService.logEvent(LogEvent.TYPE_TEACHER_LESSON_CREATE, userID, initializedLearningDesignId, @@ -411,24 +413,24 @@ return initializeLesson(lessonName, lessonDescription, originalLearningDesign, user, null, LearningDesign.COPY_TYPE_PREVIEW, customCSV, false, false, false, learnerPresenceAvailable, - learnerImAvailable, liveEditEnabled, true, false, null, null); + learnerImAvailable, liveEditEnabled, true, false, false, null, null); } @Override public Lesson initializeLessonWithoutLDcopy(String lessonName, String lessonDescription, long learningDesignID, User user, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean learnerRestart, - Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { + Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, + Boolean allowLearnerRestart, Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { LearningDesign learningDesign = authoringService.getLearningDesign(learningDesignID); if (learningDesign == null) { throw new MonitoringServiceException( "Learning design for id=" + learningDesignID + " is missing. Unable to initialize lesson."); } Lesson lesson = createNewLesson(lessonName, lessonDescription, user, learningDesign, enableLessonIntro, displayDesignImage, learnerExportAvailable, learnerPresenceAvailable, learnerImAvailable, - liveEditEnabled, enableLessonNotifications, learnerRestart, scheduledNumberDaysToLessonFinish, - precedingLesson); + liveEditEnabled, enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, + scheduledNumberDaysToLessonFinish, precedingLesson); writeAuditLog(MonitoringService.AUDIT_LESSON_CREATED_KEY, new Object[] { lessonName, learningDesign.getTitle(), learnerExportAvailable }); return lesson; @@ -438,7 +440,8 @@ User user, WorkspaceFolder workspaceFolder, int copyType, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, Boolean enableLessonNotifications, - Boolean learnerRestart, Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { + Boolean forceLearnerRestart, Boolean allowLearnerRestart, Integer scheduledNumberDaysToLessonFinish, + Lesson precedingLesson) { // copy the current learning design LearningDesign copiedLearningDesign = authoringService.copyLearningDesign(originalLearningDesign, new Integer(copyType), user, workspaceFolder, true, null, customCSV); @@ -454,8 +457,8 @@ Lesson lesson = createNewLesson(title, lessonDescription, user, copiedLearningDesign, enableLessonIntro, displayDesignImage, learnerExportAvailable, learnerPresenceAvailable, learnerImAvailable, - liveEditEnabled, enableLessonNotifications, learnerRestart, scheduledNumberDaysToLessonFinish, - precedingLesson); + liveEditEnabled, enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, + scheduledNumberDaysToLessonFinish, precedingLesson); writeAuditLog(MonitoringService.AUDIT_LESSON_CREATED_KEY, new Object[] { lessonName, copiedLearningDesign.getTitle(), learnerExportAvailable }); return lesson; @@ -503,7 +506,7 @@ } else { newLesson = initializeLesson(title, desc, ldId, organisationId, creatorUserId, customCSV, enableLessonIntro, displayDesignImage, learnerExportAvailable, learnerPresenceAvailable, - learnerImAvailable, liveEditEnabled, enableLessonNotifications, false, + learnerImAvailable, liveEditEnabled, enableLessonNotifications, false, false, scheduledNumberDaysToLessonFinish, precedingLessonId); } @@ -1953,12 +1956,12 @@ private Lesson createNewLesson(String lessonName, String lessonDescription, User user, LearningDesign copiedLearningDesign, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean learnerExportAvailable, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean learnerRestart, - Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { + Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, + Boolean allowLearnerRestart, Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { Lesson newLesson = Lesson.createNewLessonWithoutClass(lessonName, lessonDescription, user, copiedLearningDesign, enableLessonIntro, displayDesignImage, learnerExportAvailable, learnerPresenceAvailable, - learnerImAvailable, liveEditEnabled, enableLessonNotifications, learnerRestart, - scheduledNumberDaysToLessonFinish); + learnerImAvailable, liveEditEnabled, enableLessonNotifications, forceLearnerRestart, + allowLearnerRestart, scheduledNumberDaysToLessonFinish); if (precedingLesson != null) { HashSet precedingLessons = new HashSet(); precedingLessons.add(precedingLesson); @@ -2522,7 +2525,8 @@ null, lesson.isEnableLessonIntro(), lesson.isDisplayDesignImage(), lesson.getLearnerExportAvailable(), lesson.getLearnerPresenceAvailable(), lesson.getLearnerImAvailable(), lesson.getLiveEditEnabled(), - lesson.getEnableLessonNotifications(), lesson.getLearnerRestart(), null, null); + lesson.getEnableLessonNotifications(), lesson.getForceLearnerRestart(), + lesson.getAllowLearnerRestart(), null, null); // save LessonClasses newLesson = this.createLessonClassForLesson(newLesson.getLessonId(), group, learnerGroupName, Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java =================================================================== diff -u -r24972f27104335665c4f9c5be4fa0dda5e4a566b -r8fc48568c579f2b32041d489a8ebf02075847fa3 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java (.../MonitoringAction.java) (revision 24972f27104335665c4f9c5be4fa0dda5e4a566b) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java (.../MonitoringAction.java) (revision 8fc48568c579f2b32041d489a8ebf02075847fa3) @@ -75,7 +75,6 @@ import org.lamsfoundation.lams.monitoring.service.IMonitoringService; import org.lamsfoundation.lams.monitoring.service.MonitoringServiceProxy; import org.lamsfoundation.lams.security.ISecurityService; -import org.lamsfoundation.lams.timezone.service.ITimezoneService; import org.lamsfoundation.lams.tool.exception.LamsToolServiceException; import org.lamsfoundation.lams.usermanagement.Organisation; import org.lamsfoundation.lams.usermanagement.Role; @@ -141,8 +140,6 @@ private static IAuditService auditService; - private static ITimezoneService timezoneService; - private static ILessonService lessonService; private static ISecurityService securityService; @@ -166,33 +163,24 @@ return new FlashMessage(methodKey, getMonitoringService().getMessageService().getMessage("error.user.noprivilege"), FlashMessage.ERROR); - } else { - String[] msg = new String[1]; - msg[0] = e.getMessage(); - return new FlashMessage(methodKey, - getMonitoringService().getMessageService().getMessage("error.system.error", msg), - FlashMessage.CRITICAL_ERROR); } - } + String[] msg = new String[1]; + msg[0] = e.getMessage(); + return new FlashMessage(methodKey, + getMonitoringService().getMessageService().getMessage("error.system.error", msg), + FlashMessage.CRITICAL_ERROR); - private FlashMessage handleCriticalError(String methodKey, String messageKey) { - String message = getMonitoringService().getMessageService().getMessage(messageKey); - LamsDispatchAction.log.error("Error occured " + methodKey + " error "); - MonitoringAction.auditService = getAuditService(); - MonitoringAction.auditService.log(MonitoringAction.class.getName() + ":" + methodKey, message); - - return new FlashMessage(methodKey, message, FlashMessage.CRITICAL_ERROR); } private ActionForward redirectToURL(ActionMapping mapping, HttpServletResponse response, String url) throws IOException { - if (url != null) { - String fullURL = WebUtil.convertToFullURL(url); - response.sendRedirect(response.encodeRedirectURL(fullURL)); - return null; - } else { + if (url == null) { return mapping.findForward(MonitoringAction.NOT_SUPPORTED_SCREEN); } + + String fullURL = WebUtil.convertToFullURL(url); + response.sendRedirect(response.encodeRedirectURL(fullURL)); + return null; } /** @@ -220,7 +208,8 @@ Boolean learnerPresenceAvailable = WebUtil.readBooleanParam(request, "learnerPresenceAvailable", false); Boolean learnerImAvailable = WebUtil.readBooleanParam(request, "learnerImAvailable", false); Boolean liveEditEnabled = WebUtil.readBooleanParam(request, "liveEditEnabled", false); - Boolean learnerRestart = WebUtil.readBooleanParam(request, "learnerRestart", false); + Boolean forceRestart = WebUtil.readBooleanParam(request, "forceRestart", false); + Boolean allowRestart = WebUtil.readBooleanParam(request, "allowRestart", false); Lesson newLesson = null; if ((copyType != null) && copyType.equals(LearningDesign.COPY_TYPE_PREVIEW)) { @@ -230,7 +219,7 @@ try { newLesson = getMonitoringService().initializeLesson(title, desc, ldId, organisationId, getUserId(), customCSV, false, false, learnerExportAvailable, learnerPresenceAvailable, learnerImAvailable, - liveEditEnabled, false, learnerRestart, null, null); + liveEditEnabled, false, forceRestart, allowRestart, null, null); } catch (SecurityException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a monitor in the organisation"); return null; @@ -328,7 +317,8 @@ Date schedulingDatetime = schedulingEnable ? MonitoringAction.LESSON_SCHEDULING_DATETIME_FORMAT.parse(request.getParameter("schedulingDatetime")) : null; - boolean learnerRestart = WebUtil.readBooleanParam(request, "learnerRestart", false); + boolean forceRestart = WebUtil.readBooleanParam(request, "forceRestart", false); + boolean allowRestart = WebUtil.readBooleanParam(request, "allowRestart", false); boolean precedingLessonEnable = WebUtil.readBooleanParam(request, "precedingLessonEnable", false); Long precedingLessonId = precedingLessonEnable ? WebUtil.readLongParam(request, "precedingLessonId", true) @@ -389,7 +379,7 @@ try { lesson = getMonitoringService().initializeLesson(lessonInstanceName, introDescription, ldId, organisationId, userId, null, introEnable, introImage, portfolioEnable, presenceEnable, - imEnable, enableLiveEdit, notificationsEnable, learnerRestart, timeLimitIndividual, + imEnable, enableLiveEdit, notificationsEnable, forceRestart, allowRestart, timeLimitIndividual, precedingLessonId); getMonitoringService().createLessonClassForLesson(lesson.getLessonId(), organisation, @@ -1246,10 +1236,8 @@ // old branching is just a rectangle like Tool // new branching has start and finish points, it's exploded BranchingActivity ba = (BranchingActivity) monitoringService.getActivityById(activity.getActivityId()); - activityJSON.put("x", - MonitoringAction.getActivityCoordinate(ba.getStartXcoord())); - activityJSON.put("y", - MonitoringAction.getActivityCoordinate(ba.getStartYcoord())); + activityJSON.put("x", MonitoringAction.getActivityCoordinate(ba.getStartXcoord())); + activityJSON.put("y", MonitoringAction.getActivityCoordinate(ba.getStartYcoord())); } else if (activity.isOptionsWithSequencesActivity() && flaFormat) { // old optional sequences is just a long rectangle // new optional sequences has start and finish points, it's exploded @@ -1478,20 +1466,6 @@ return MonitoringAction.auditService; } - /** - * Get TimezoneService bean. - * - * @return - */ - private ITimezoneService getTimezoneService() { - if (MonitoringAction.timezoneService == null) { - WebApplicationContext ctx = WebApplicationContextUtils - .getRequiredWebApplicationContext(getServlet().getServletContext()); - MonitoringAction.timezoneService = (ITimezoneService) ctx.getBean("timezoneService"); - } - return MonitoringAction.timezoneService; - } - private ILessonService getLessonService() { if (MonitoringAction.lessonService == null) { WebApplicationContext ctx = WebApplicationContextUtils @@ -1616,8 +1590,6 @@ * Creates a list of users out of string with comma-delimited user IDs. */ private List parseUserList(HttpServletRequest request, String paramName, Collection users) { - IUserManagementService userManagementService = MonitoringServiceProxy - .getUserManagementService(getServlet().getServletContext()); String userIdList = request.getParameter(paramName); String[] userIdArray = userIdList.split(","); List result = new ArrayList(userIdArray.length);

+ - +
+ + + +
- +