diff --git a/src/main/java/org/olat/core/commons/services/taskexecutor/manager/PersistentTaskDAO.java b/src/main/java/org/olat/core/commons/services/taskexecutor/manager/PersistentTaskDAO.java index 3070ebd4d0c152bfb50e7839989d243fcbfe28b0..fb1d2f52f307924698aa95a7d5baa7b160f59024 100644 --- a/src/main/java/org/olat/core/commons/services/taskexecutor/manager/PersistentTaskDAO.java +++ b/src/main/java/org/olat/core/commons/services/taskexecutor/manager/PersistentTaskDAO.java @@ -1,5 +1,5 @@ /** - * <a href="http://www.openolat.org"> +12 * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> @@ -118,18 +118,19 @@ public class PersistentTaskDAO { public PersistentTask pickTaskForRun(Long taskKey) { PersistentTask task = dbInstance.getCurrentEntityManager() .find(PersistentTask.class, taskKey, LockModeType.PESSIMISTIC_WRITE); - - if(TaskStatus.newTask.equals(task.getStatus())) { - task.setStatus(TaskStatus.inWork); - task.setExecutorNode(Integer.toString(WebappHelper.getNodeId())); - task.setExecutorBootId(WebappHelper.getBootId()); - task = dbInstance.getCurrentEntityManager().merge(task); - } else if(TaskStatus.inWork.equals(task.getStatus())) { - task.setExecutorNode(Integer.toString(WebappHelper.getNodeId())); - task.setExecutorBootId(WebappHelper.getBootId()); - task = dbInstance.getCurrentEntityManager().merge(task); - } else if(TaskStatus.edition.equals(task.getStatus())) { - task = null; + if(task != null) { + if(TaskStatus.newTask.equals(task.getStatus())) { + task.setStatus(TaskStatus.inWork); + task.setExecutorNode(Integer.toString(WebappHelper.getNodeId())); + task.setExecutorBootId(WebappHelper.getBootId()); + task = dbInstance.getCurrentEntityManager().merge(task); + } else if(TaskStatus.inWork.equals(task.getStatus())) { + task.setExecutorNode(Integer.toString(WebappHelper.getNodeId())); + task.setExecutorBootId(WebappHelper.getBootId()); + task = dbInstance.getCurrentEntityManager().merge(task); + } else if(TaskStatus.edition.equals(task.getStatus())) { + task = null; + } } dbInstance.commit(); return task; diff --git a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties index 58a6a15f118070f664625f696fe30a56803800b5..2c3cbe5d5684143eb2b94a4123671cfbab50a485 100644 --- a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties @@ -26,7 +26,8 @@ mailhelper.error.send.general=Die E-Mail konnte aus unbekannten Problemen nicht mailhelper.error.sender.address=Die E-Mail konnte nicht verschickt werden\: ung\u00FCltige Absenderadresse. Bitte benachrichtigen Sie die Empf\u00E4nger manuell. mailhelper.error.template.general=Die E-Mail konnte nicht verschickt werden\: allgemeiner Fehler im Mailtext. Bitte benachrichtigen Sie die Empf\u00E4nger manuell. mailhelper.error.template.parse=Die E-Mail konnte nicht verschickt werden\: Parsefehler im Mailtext. Bitte benachrichtigen Sie die Empf\u00E4nger manuell. -mailhelper.error.addressinvalid=Eine oder mehrere Adressen sind ung\u00FCltig: {0} +mailhelper.error.addressinvalid=Eine oder mehrere Adressen sind ung\u00FCltig: {0} +mailhelper.error.single.addressinvalid=Die Adressen ist ung\u00FCltig. mailnotification.title=E-Mail-Benachrichtigung mailtemplateform.body=Nachricht diff --git a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_en.properties index 0ae072dac10fb6516b627eb103edaef922561f5d..55e3802a2d884927c35caecef13a482b26a7a364 100644 --- a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_en.properties @@ -60,6 +60,7 @@ mailhelper.error.send.general=Mail could not be sent due to unknown problems. Pl mailhelper.error.sender.address=Mail could not be sent\: invalid sender address. Please notify your recipients manually. mailhelper.error.template.general=Mail could not be sent\: general error in mail text. Please notify your recipients manually. mailhelper.error.template.parse=Mail could not be sent\: parse error in mail text. Please notify your recipients manually. +mailhelper.error.single.addressinvalid=The address is not valid. mailnotification.title=E-mail notification mailtemplateform.body=Mail body mailtemplateform.continue=Next diff --git a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties index e5d29cf63589ab36b576949c95bac00aa995ba4e..4aa05fd197466dc57a2cd4291e6b732938794242 100644 --- a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties @@ -60,6 +60,7 @@ mailhelper.error.send.general=L'e-mail n'a pas pu \u00EAtre envoy\u00E9 pour des mailhelper.error.sender.address=L'e-mail n'a pas pu \u00EAtre envoy\u00E9\: adresse non valable. Veuillez contacter le destinataire manuellement. mailhelper.error.template.general=L'e-mail n'a pas pu \u00EAtre envoy\u00E9\: erreur g\u00E9n\u00E9rale dans le texte de l'e-mail. Veuillez contacter le destinataire manuellement. mailhelper.error.template.parse=L'e-mail n'a pas pu \u00EAtre envoy\u00E9\: erreur de parsing dans le texte de l'e-mail. Veuillez contacter le destinataire manuellement. +mailhelper.error.single.addressinvalid=L'adresse courrielle n'est pas valide. mailnotification.title=Notification par e-mail mailtemplateform.body=Message mailtemplateform.continue=Suivant diff --git a/src/main/java/org/olat/core/util/mail/ui/EMailCalloutCtrl.java b/src/main/java/org/olat/core/util/mail/ui/EMailCalloutCtrl.java index e61ec068c166e963c90ea4b5e8560dc5280d6ade..6d08606e35a3397601fef38fa48acca76ecca0b4 100644 --- a/src/main/java/org/olat/core/util/mail/ui/EMailCalloutCtrl.java +++ b/src/main/java/org/olat/core/util/mail/ui/EMailCalloutCtrl.java @@ -22,14 +22,13 @@ package org.olat.core.util.mail.ui; import java.util.List; import org.olat.admin.user.UserSearchListProvider; -import org.olat.basesecurity.BaseSecurityManager; +import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; import org.olat.basesecurity.events.SingleIdentityChosenEvent; -import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; @@ -39,10 +38,12 @@ import org.olat.core.gui.control.generic.ajax.autocompletion.FlexiAutoCompleterC import org.olat.core.gui.control.generic.ajax.autocompletion.ListProvider; import org.olat.core.id.Identity; import org.olat.core.id.Roles; +import org.olat.core.util.CodeHelper; import org.olat.core.util.StringHelper; import org.olat.core.util.mail.MailHelper; import org.olat.core.util.mail.MailModule; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -52,17 +53,21 @@ import org.olat.user.UserManager; */ public class EMailCalloutCtrl extends FormBasicController { + private TextElement emailEl; private FlexiAutoCompleterController autocompleterC; - private final BaseSecurityModule securityModule; private final boolean allowExternalAddress; + @Autowired + private UserManager userManager; + @Autowired + private BaseSecurity securityManager; + @Autowired + private BaseSecurityModule securityModule; + public EMailCalloutCtrl(UserRequest ureq, WindowControl wControl, boolean allowExternalAddress) { super(ureq, wControl, LAYOUT_VERTICAL); - setBasePackage(MailModule.class); - + setBasePackage(MailModule.class); this.allowExternalAddress = allowExternalAddress; - securityModule = CoreSpringFactory.getImpl(BaseSecurityModule.class); - initForm(ureq); } @@ -72,8 +77,7 @@ public class EMailCalloutCtrl extends FormBasicController { Roles roles = ureq.getUserSession().getRoles(); boolean autoCompleteAllowed = securityModule.isUserAllowedAutoComplete(roles); boolean isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); - boolean ajax = Windows.getWindows(ureq).getWindowManager().isAjaxEnabled(); - if (ajax && autoCompleteAllowed) { + if (autoCompleteAllowed) { ListProvider provider = new UserSearchListProvider(); autocompleterC = new FlexiAutoCompleterController(ureq, getWindowControl(), provider, null, isAdministrativeUser, allowExternalAddress, 60, 3, null, mainForm); autocompleterC.setFormElement(false); @@ -81,6 +85,8 @@ public class EMailCalloutCtrl extends FormBasicController { FormItem item = autocompleterC.getInitialFormItem(); formLayout.add(item); + } else if(allowExternalAddress) { + emailEl = uifactory.addTextElement("email" + CodeHelper.getRAMUniqueID(), "email", null, 256, "", formLayout); } } @@ -101,11 +107,11 @@ public class EMailCalloutCtrl extends FormBasicController { private void processSelection(UserRequest ureq, String mail) { Identity identity = null; if(StringHelper.isLong(mail)) { - identity = BaseSecurityManager.getInstance().loadIdentityByKey(Long.parseLong(mail)); + identity = securityManager.loadIdentityByKey(Long.parseLong(mail)); } if(MailHelper.isValidEmailAddress(mail)) { if(identity == null) { - identity = UserManager.getInstance().findIdentityByEmail(mail); + identity = userManager.findIdentityByEmail(mail); } if(identity == null) { identity = new EMailIdentity(mail, getLocale()); @@ -118,10 +124,34 @@ public class EMailCalloutCtrl extends FormBasicController { } @Override - protected void formOK(UserRequest ureq) { - // + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOk = true; + + if(emailEl != null) { + emailEl.clearError(); + if(!MailHelper.isValidEmailAddress(emailEl.getValue())) { + emailEl.setErrorKey("mailhelper.error.single.addressinvalid", null); + allOk &= false; + } + } + + return allOk & super.validateFormLogic(ureq); } + @Override + protected void formOK(UserRequest ureq) { + if(emailEl != null) { + String mail = emailEl.getValue(); + if(MailHelper.isValidEmailAddress(mail)) { + Identity identity = userManager.findIdentityByEmail(mail); + if(identity == null) { + identity = new EMailIdentity(mail, getLocale()); + } + fireEvent(ureq, new SingleIdentityChosenEvent(identity)); + } + } + } + @Override protected void doDispose() { // diff --git a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java index 07909101ab8b294dbc65c03bfad84f7585168f6e..6e26d3848c88c1e307d6c9bbf76f689c90246fdf 100644 --- a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java +++ b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java @@ -885,7 +885,7 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia @Override public File importFileSubmission(AssessmentTestSession candidateSession, MultipartFileInfos multipartFile) { - File submissionDir = this.getSubmissionDirectory(candidateSession); + File submissionDir = getSubmissionDirectory(candidateSession); try { //add the date in the file @@ -905,7 +905,7 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia if(!datedFilename.equals(renamedFile)) { submittedFile = new File(submissionDir, datedFilename); } - Files.move(multipartFile.getFile().toPath(), submittedFile.toPath(), StandardCopyOption.ATOMIC_MOVE); + Files.move(multipartFile.getFile().toPath(), submittedFile.toPath(), StandardCopyOption.REPLACE_EXISTING); return submittedFile; } catch (IOException e) { log.error("", e); diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/IdentitiesAssessmentTestCorrectionController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/IdentitiesAssessmentTestCorrectionController.java index 78114e8324439400ea6d44f4d1efe0aac48f1f85..498d99e5c7d4c3551edf593435865bf6585ec72d 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/IdentitiesAssessmentTestCorrectionController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/IdentitiesAssessmentTestCorrectionController.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import org.olat.basesecurity.GroupRoles; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; @@ -42,6 +43,7 @@ import org.olat.core.id.Identity; import org.olat.course.nodes.IQTESTCourseNode; import org.olat.course.run.environment.CourseEnvironment; import org.olat.fileresource.FileResourceManager; +import org.olat.group.BusinessGroupService; import org.olat.ims.qti21.AssessmentItemSession; import org.olat.ims.qti21.AssessmentTestHelper; import org.olat.ims.qti21.AssessmentTestSession; @@ -90,6 +92,8 @@ public class IdentitiesAssessmentTestCorrectionController extends BasicControlle @Autowired private QTI21Service qtiService; + @Autowired + private BusinessGroupService businessGroupService; public IdentitiesAssessmentTestCorrectionController(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, AssessmentToolOptions asOptions, IQTESTCourseNode courseNode) { @@ -130,6 +134,10 @@ public class IdentitiesAssessmentTestCorrectionController extends BasicControlle listenTo(overviewCtrl); } + public int getNumberOfAssessedIdentities() { + return assessedIdentities == null ? 0 : assessedIdentities.size(); + } + public AssessmentTestCorrection getTestCorrections() { return testCorrections; } @@ -223,8 +231,17 @@ public class IdentitiesAssessmentTestCorrectionController extends BasicControlle } private Set<Identity> getAssessedIdentities() { - List<Identity> identities = asOptions.getIdentities(); - return new HashSet<>(identities); + List<Identity> identities; + if(asOptions.getGroup() != null) { + identities = businessGroupService.getMembers(asOptions.getGroup(), GroupRoles.participant.name()); + } else { + identities = asOptions.getIdentities(); + } + Set<Identity> uniqueIdentities = new HashSet<>(); + if(identities != null) { + uniqueIdentities.addAll(identities); + } + return uniqueIdentities; } private Map<Identity,AssessmentTestSession> getLastSessions(Set<Identity> identitiesSet) { diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java index d208d656568256e2db5fb27e6922a460b6f00934..556e387c9bb4fa06d411b0eb5121a18b3fac7aa8 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java @@ -107,11 +107,16 @@ public class QTI21CorrectionToolController extends BasicController { public void doStartCorrection(UserRequest ureq) { correctionCtrl = new IdentitiesAssessmentTestCorrectionController(ureq, getWindowControl(), courseEnv, asOptions, courseNode); - listenTo(correctionCtrl); - cmc = new CloseableModalController(getWindowControl(), "close", correctionCtrl.getInitialComponent(), - true, translate("correction")); - cmc.activate(); - listenTo(cmc); + if(correctionCtrl.getNumberOfAssessedIdentities() == 0) { + showWarning("grade.nobody"); + correctionCtrl = null; + } else { + listenTo(correctionCtrl); + cmc = new CloseableModalController(getWindowControl(), "close", correctionCtrl.getInitialComponent(), + true, translate("correction")); + cmc.activate(); + listenTo(cmc); + } } private void doUpdateCourseNode(AssessmentTestCorrection corrections, List<AssessmentTestSession> testSessionsToComplete) { diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties index cb212d9623bee9f0c51e64497e47adcc1a8b1ea1..6ab91a6108a626700bff1b4bb14a9ff36c82ed10 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties @@ -1,9 +1,10 @@ #Tue Nov 15 16:25:36 CET 2016 assessed.identity=Benutzer correction=Korrigieren -correction.min.max.score=Result must ziwschen {0} und {1} sein +correction.min.max.score=Resultat muss zwischen {0} und {1} sein correction.test.title=Korrigieren grade.no.items=Es gibt kein Resultat f\u00FCr diese Frage zu korrigieren. +grade.nobody=Es gibt kein Resultat zu korrigieren. next.item=Zur n\u00E4chsten Frage not.responded=Die Frage wurde nicht beantworter overview.tests=\u00DCbersicht und abschliessen diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties index 83a388634a86ec8685bed401bcec5a2dc7a94ec2..67924b2b719730c2ce8654c706b70c24ebb630cd 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties @@ -4,6 +4,7 @@ correction=Correction correction.min.max.score=Score need to be between {0} and {1}. correction.test.title=Grade grade.no.items=There is no results to correct for this question. +grade.nobody=There is no results to correct next.item=Next question not.responded=The question was not responded overview.tests=Overview and closing diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties index cb62293fa7592cae44530e734595b69529c3bff0..598ba5d2bc0faa72d891ec9eb49e1c440df00c2a 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties @@ -4,6 +4,7 @@ correction=Corriger correction.min.max.score=Le r\u00E9sultat doit \u00EAtre entre {0} et {1}. correction.test.title=Corriger grade.no.items=Il n'y a pas de r\u00E9sultats \u00E0 corriger pour cette question. +grade.nobody=Il n'y a pas de r\u00E9sultats \u00E0 corriger. next.item=Question suivante not.responded=Il n'a pas \u00E9t\u00E9 r\u00E9pondue \u00E0 la question overview.tests=Aper\u00E7u and cl\u00F4ture diff --git a/src/main/java/org/olat/modules/portfolio/ui/InvitationEditRightsController.java b/src/main/java/org/olat/modules/portfolio/ui/InvitationEditRightsController.java index 311f7cbe82c955df8e85c40f2ffe8c17ba2bcd96..e59376b0d4e6a94077303e80e21dbcc8c11dd20d 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/InvitationEditRightsController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/InvitationEditRightsController.java @@ -47,7 +47,6 @@ import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; import org.olat.core.util.StringHelper; -import org.olat.core.util.WebappHelper; import org.olat.core.util.mail.ContactList; import org.olat.core.util.mail.MailBundle; import org.olat.core.util.mail.MailContext; @@ -360,7 +359,7 @@ public class InvitationEditRightsController extends FormBasicController { MailContext context = new MailContextImpl(binder, null, getWindowControl().getBusinessControl().getAsString()); MailBundle bundle = new MailBundle(); bundle.setContext(context); - bundle.setFrom(WebappHelper.getMailConfig("mailReplyTo")); + bundle.setFromId(getIdentity()); bundle.setContactList(contactList); bundle.setContent(translate("invitation.mail.subject"), translate("invitation.mail.body", bodyArgs)); diff --git a/src/main/java/org/olat/modules/portfolio/ui/PublishController.java b/src/main/java/org/olat/modules/portfolio/ui/PublishController.java index 4467d9a62bfbd978791c34dcc8244997e9052246..d78e4b4fd49ce638a1ff3c750240bf96e8d21a7c 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/PublishController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/PublishController.java @@ -47,7 +47,6 @@ import org.olat.core.gui.control.generic.wizard.StepsMainRunController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.core.id.Identity; import org.olat.core.util.StringHelper; -import org.olat.core.util.WebappHelper; import org.olat.core.util.mail.ContactList; import org.olat.core.util.mail.MailBundle; import org.olat.core.util.mail.MailContext; @@ -404,7 +403,7 @@ public class PublishController extends BasicController implements TooledControll MailContext context = new MailContextImpl(binder, null, getWindowControl().getBusinessControl().getAsString()); MailBundle bundle = new MailBundle(); bundle.setContext(context); - bundle.setFrom(WebappHelper.getMailConfig("mailReplyTo")); + bundle.setFromId(getIdentity()); bundle.setContactList(contactList); bundle.setContent(mailTemplate.getSubjectTemplate(), mailTemplate.getBodyTemplate()); MailerResult result = mailManager.sendMessage(bundle); diff --git a/src/main/java/org/olat/modules/portfolio/ui/wizard/MemberMailController.java b/src/main/java/org/olat/modules/portfolio/ui/wizard/MemberMailController.java index f6f2dd3454f1edb8b97a0119a3000ac940933f4c..e8df5e53bb25b5be8e9fb1eee4cbe4783928a9a4 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/wizard/MemberMailController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/wizard/MemberMailController.java @@ -93,7 +93,6 @@ public class MemberMailController extends StepFormBasicController { subjectEl.setMandatory(true); bodyEl = uifactory.addTextAreaElement("bodyElem", "mail.body", -1, 15, 60, true, mailTemplate.getBodyTemplate(), formLayout); - bodyEl.setHelpText(translate("mailtemplateform.body.hover")); bodyEl.setHelpUrlForManualPage("E-Mail"); bodyEl.setMandatory(true); }