diff --git a/src/main/java/org/olat/course/nodes/co/CourseMailTemplate.java b/src/main/java/org/olat/course/nodes/co/CourseMailTemplate.java index e1bc6a0432ecf8b9849674892d36882febfc7c0c..d13f6f942fae1256e4c28193d4d2a72885191178 100644 --- a/src/main/java/org/olat/course/nodes/co/CourseMailTemplate.java +++ b/src/main/java/org/olat/course/nodes/co/CourseMailTemplate.java @@ -22,11 +22,13 @@ package org.olat.course.nodes.co; import java.util.Locale; import org.apache.velocity.VelocityContext; +import org.olat.basesecurity.BaseSecurity; import org.olat.core.CoreSpringFactory; import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; import org.olat.core.id.User; import org.olat.core.id.UserConstants; +import org.olat.core.util.StringHelper; import org.olat.core.util.mail.MailTemplate; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; @@ -61,6 +63,7 @@ public class CourseMailTemplate extends MailTemplate { if(sender != null) { User user = sender.getUser(); UserManager userManager = CoreSpringFactory.getImpl(UserManager.class); + BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); vContext.put("firstname", user.getProperty(UserConstants.FIRSTNAME, null)); vContext.put(UserConstants.FIRSTNAME, user.getProperty(UserConstants.FIRSTNAME, null)); @@ -71,7 +74,11 @@ public class CourseMailTemplate extends MailTemplate { vContext.put("fullName", fullName); vContext.put("mail", userManager.getUserDisplayEmail(user, locale)); vContext.put("email", userManager.getUserDisplayEmail(user, locale)); - vContext.put("username", sender.getName()); + String loginName = securityManager.findAuthenticationName(recipient); + if(!StringHelper.containsNonWhitespace(loginName)) { + loginName = recipient.getName(); + } + vContext.put("username", loginName); } } } diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java index 505fabde2785eb3c280cb1fac442c2157d87c430..c29f8a9b18cc62dcc16c2f64882b56110f0831b1 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java @@ -803,8 +803,9 @@ public class QTI21AssessmentRunController extends BasicController implements Gen RepositoryEntry courseRe = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); if (!userCourseEnv.isParticipant() && courseNode instanceof IQTESTCourseNode) { + boolean authorMode = !ureq.getUserSession().getRoles().isGuestOnly(); displayCtrl = new AssessmentTestDisplayController(ureq, getWindowControl(), new InMemoryOutcomeListener(), - testEntry, courseRe, courseNode.getIdent(), deliveryOptions, overrideOptions, true, true, true); + testEntry, courseRe, courseNode.getIdent(), deliveryOptions, overrideOptions, true, authorMode, true); } else { displayCtrl = new AssessmentTestDisplayController(ureq, bwControl, this, testEntry, courseRe, courseNode.getIdent(), deliveryOptions, overrideOptions, true, false, false); diff --git a/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java b/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java index 5e5c00cd71c66ecd744208b2634796fab1b703e1..c3938204abbba66e3117756687158de65e936654 100644 --- a/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java +++ b/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java @@ -500,7 +500,15 @@ public class QTI21ArchiveFormat { Identity assessedIdentity = entry.getIdentity(); //user properties - if(assessedIdentity == null) { + if(anonymizerCallback != null) { + String anonymizedName; + if(assessedIdentity == null) { + anonymizedName = translator.translate("anonym.user"); + } else { + anonymizedName = anonymizerCallback.getAnonymizedUserName(assessedIdentity); + } + dataRow.addCell(col++, anonymizedName, null); + } else if(assessedIdentity == null) { for (UserPropertyHandler userPropertyHandler:userPropertyHandlers) { if (userPropertyHandler != null) { if(userPropertyHandlers.get(0) == userPropertyHandler) { @@ -510,9 +518,6 @@ public class QTI21ArchiveFormat { } } } - } else if(anonymizerCallback != null) { - String anonymizedName = anonymizerCallback.getAnonymizedUserName(assessedIdentity); - dataRow.addCell(col++, anonymizedName, null); } else { User assessedUser = assessedIdentity.getUser(); for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) { diff --git a/src/main/java/org/olat/ims/qti21/resultexport/AssessedMemberComparator.java b/src/main/java/org/olat/ims/qti21/resultexport/AssessedMemberComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..4f69438af64dd936f66f50f0605784df909a51ca --- /dev/null +++ b/src/main/java/org/olat/ims/qti21/resultexport/AssessedMemberComparator.java @@ -0,0 +1,61 @@ +/** + * <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> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.ims.qti21.resultexport; + +import java.util.Comparator; + +/** + * + * Initial date: 28 août 2020<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessedMemberComparator implements Comparator<AssessedMember> { + + @Override + public int compare(AssessedMember o1, AssessedMember o2) { + int c = 0; + + String l1 = o1.getLastname(); + String l2 = o2.getLastname(); + if(l1 == null || l2 == null) { + c = compareNullObjects(l1, l2); + } else { + c = l1.compareTo(l2); + } + + if(c == 0) { + String n1 = o1.getNickname(); + String n2 = o2.getNickname(); + if(n1 == null || n2 == null) { + c = compareNullObjects(n1, n2); + } else { + c = n1.compareTo(n2); + } + } + return c; + } + + private final int compareNullObjects(final Object a, final Object b) { + boolean ba = (a == null); + boolean bb = (b == null); + return ba? (bb? 0: -1):(bb? 1: 0); + } +} diff --git a/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java b/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java index 571098bea1a57cc22e9ea99a2917c759ece2a79c..7bd4e0b8a51c9d239498bb6f1ff138dc61098fff 100644 --- a/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java +++ b/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java @@ -86,6 +86,7 @@ import org.olat.ims.qti21.ui.AssessmentResultController; import org.olat.modules.assessment.AssessmentEntry; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; public class QTI21ResultsExportMediaResource implements MediaResource { @@ -108,11 +109,14 @@ public class QTI21ResultsExportMediaResource implements MediaResource { private final Set<RepositoryEntry> testEntries = new HashSet<>(); - private final UserManager userManager; - private final QTI21Service qtiService; + @Autowired + private UserManager userManager; + @Autowired + private QTI21Service qtiService; public QTI21ResultsExportMediaResource(CourseEnvironment courseEnv, List<Identity> identities, - QTICourseNode courseNode, String archivePath, Locale locale) { + QTICourseNode courseNode, String archivePath, Locale locale) { + CoreSpringFactory.autowireObject(this); this.courseNode = courseNode; this.identities = identities; this.courseEnv = courseEnv; @@ -124,8 +128,6 @@ public class QTI21ResultsExportMediaResource implements MediaResource { ureq.getUserSession().setRoles(Roles.userRoles()); velocityHelper = VelocityHelper.getInstance(); - qtiService = CoreSpringFactory.getImpl(QTI21Service.class); - userManager = CoreSpringFactory.getImpl(UserManager.class); entry = courseEnv.getCourseGroupManager().getCourseEntry(); translator = Util.createPackageTranslator(QTI21ResultsExportMediaResource.class, locale); exportFolderName = ZipUtil.concat(archivePath, translator.translate("export.folder.name")); @@ -277,13 +279,16 @@ public class QTI21ResultsExportMediaResource implements MediaResource { assessmentEntryMap.put(assessmentEntry.getIdentity(), assessmentEntry); } - List<AssessedMember> assessedMembers = new ArrayList<>(); + List<AssessedMember> assessedMembers = new ArrayList<>(); for(Identity identity : identities) { if(identity == null || identity.getStatus() == null || identity.getStatus().equals(Identity.STATUS_DELETED)) { continue; } - - String lastname = StringHelper.transformDisplayNameToFileSystemName(identity.getUser().getLastName()); + String lastNameOrAnoymous = identity.getUser().getLastName(); + if(!StringHelper.containsNonWhitespace(lastNameOrAnoymous)) { + lastNameOrAnoymous = "anonym"; + } + String lastname = StringHelper.transformDisplayNameToFileSystemName(lastNameOrAnoymous); String idDir = exportFolderName + "/" + DATA + lastname + "_" + identity.getKey(); idDir = idDir.endsWith(SEP) ? idDir : idDir + SEP; createZipDirectory(zout, idDir); @@ -303,7 +308,7 @@ public class QTI21ResultsExportMediaResource implements MediaResource { String linkToUser = idDir.replace(exportFolderName + "/", "") + "index.html"; String memberEmail = userManager.getUserDisplayEmail(identity, ureq.getLocale()); AssessedMember member = new AssessedMember(identity.getUser().getProperty(UserConstants.NICKNAME, null), - identity.getUser().getLastName(), identity.getUser().getFirstName(), + lastNameOrAnoymous, identity.getUser().getFirstName(), memberEmail, assessments.size(), passed, score, linkToUser); String singleUserInfoHTML = createResultListingHTML(assessments, assessmentDocuments, member); @@ -373,7 +378,7 @@ public class QTI21ResultsExportMediaResource implements MediaResource { } private String createMemberListingHTML(List<AssessedMember> assessedMembers) { - Collections.sort(assessedMembers, (o1, o2) -> o1.getLastname().compareTo(o2.getLastname())); + Collections.sort(assessedMembers, new AssessedMemberComparator()); // now put values to velocityContext VelocityContext ctx = new VelocityContext(); ctx.put("t", translator); diff --git a/src/main/java/org/olat/ims/qti21/ui/report/QuestionOriginMediaResource.java b/src/main/java/org/olat/ims/qti21/ui/report/QuestionOriginMediaResource.java index 0fe31892267a6cd976a0dfa044118f20c184a431..d1b61cbc33ccfdd37716a059e6774e11a0c440bf 100644 --- a/src/main/java/org/olat/ims/qti21/ui/report/QuestionOriginMediaResource.java +++ b/src/main/java/org/olat/ims/qti21/ui/report/QuestionOriginMediaResource.java @@ -31,6 +31,10 @@ import org.apache.logging.log4j.Logger; import org.olat.basesecurity.GroupRoles; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.LicenseModule; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.LicenseType; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.logging.Tracing; @@ -47,6 +51,7 @@ import org.olat.ims.qti21.model.xml.ManifestMetadataBuilder; import org.olat.imscp.xml.manifest.ResourceType; import org.olat.modules.qpool.QPoolService; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.manager.QuestionPoolLicenseHandler; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryRelationType; import org.olat.repository.RepositoryManager; @@ -77,6 +82,7 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { private static final Logger log = Tracing.createLoggerFor(QuestionOriginMediaResource.class); + private boolean licenseEnabled; private final Translator translator; private final List<RepositoryEntry> testEntries; private final ConcurrentMap<RepositoryEntry, TestHolder> holdersMap = new ConcurrentHashMap<>(); @@ -88,17 +94,24 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { @Autowired private QPoolService qpoolService; @Autowired + private LicenseService licenseService; + @Autowired private ReferenceManager referenceManager; @Autowired private RepositoryManager repositoryManager; @Autowired private RepositoryService repositoryService; + @Autowired + private LicenseModule licenseModule; + @Autowired + private QuestionPoolLicenseHandler licenseHandler; public QuestionOriginMediaResource(String label, List<RepositoryEntry> testEntries, Translator translator) { super(label); CoreSpringFactory.autowireObject(this); this.translator = translator; this.testEntries = testEntries; + licenseEnabled = licenseModule.isEnabled(licenseHandler); } @Override @@ -133,11 +146,16 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { headerRow.addCell(col++, translator.translate("report.question.author")); headerRow.addCell(col++, translator.translate("report.question.identifier")); headerRow.addCell(col++, translator.translate("report.question.keywords")); + headerRow.addCell(col++, translator.translate("report.question.taxonomy.level")); headerRow.addCell(col++, translator.translate("report.question.taxonomy.path")); headerRow.addCell(col++, translator.translate("report.question.topic")); headerRow.addCell(col++, translator.translate("report.question.context")); + headerRow.addCell(col++, translator.translate("report.question.correction.time")); headerRow.addCell(col++, translator.translate("report.question.type")); - + if (licenseEnabled) { + headerRow.addCell(col++, translator.translate("report.question.license")); + } + // master headerRow.addCell(col++, translator.translate("report.question.master.identifier")); headerRow.addCell(col++, translator.translate("report.question.master.author")); @@ -190,10 +208,15 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { row.addCell(col++, question.getAuthor()); row.addCell(col++, question.getIdentifier()); row.addCell(col++, question.getKeywords()); + row.addCell(col++, question.getTaxonomyLevel()); row.addCell(col++, question.getTaxonomyPath()); row.addCell(col++, question.getTopic()); row.addCell(col++, question.getEducationalContextLevel()); + row.addCell(col++, question.getCorrectionTime()); row.addCell(col++, question.getType()); + if(licenseEnabled) { + row.addCell(col++, question.getLicense()); + } // master question row.addCell(col++, question.getMasterIdentifier()); @@ -294,7 +317,8 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { } else { QuestionItem item = items.get(0); String authors = getAuthors(item); - infos = new QuestionInformations(authors, item); + String license = getLicense(item); + infos = new QuestionInformations(authors, item, license); } if(StringHelper.containsNonWhitespace(masterIdentifier)) { @@ -309,6 +333,28 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { } return infos; } + + private String getLicense(QuestionItem item) { + License license = null; + if(licenseEnabled) { + license = licenseService.loadLicense(item); + } + + String licenseText = null; + if(license != null) { + LicenseType licenseType = license.getLicenseType(); + if (licenseService.isFreetext(licenseType)) { + licenseText = license.getFreetext(); + } else if (!licenseService.isNoLicense(licenseType)) { + licenseText = license.getLicenseType().getName(); + } + + if(licenseText != null && licenseText.length() > 32000) { + licenseText = licenseText.substring(0, 32000); + } + } + return licenseText; + } private List<CourseToTestHolder> loadCoursesAndTests() { List<CourseToTestHolder> courseToTestList = new ArrayList<>(128); @@ -409,31 +455,39 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { private final String author; private final String keywords; private final String taxonomyPath; + private final String taxonomyLevel; + private final String correctionTime; private final String topic; private final String context; private final String type; private final String masterIdentifier; + private final String license; private MasterInformations masterInformations; - public QuestionInformations(String author, QuestionItem item) { + public QuestionInformations(String author, QuestionItem item, String license) { identifier = item.getIdentifier(); title = item.getTitle(); this.author = author; keywords = item.getKeywords(); taxonomyPath = item.getTaxonomicPath(); + taxonomyLevel = item.getTaxonomyLevelName(); topic = item.getTopic(); context = item.getEducationalContextLevel(); type = item.getItemType(); masterIdentifier = item.getMasterIdentifier(); + correctionTime = item.getCorrectionTime() == null ? "" : item.getCorrectionTime().toString(); + this.license = license; } public QuestionInformations(AssessmentItem assessmentItem, ManifestMetadataBuilder metadata, String testOwners) { identifier = metadata.getOpenOLATMetadataIdentifier(); if(StringHelper.containsNonWhitespace(metadata.getTitle())) { title = metadata.getTitle(); - } else { + } else if (assessmentItem != null) { title = assessmentItem.getTitle(); + } else { + title = "Unkown"; } if(StringHelper.containsNonWhitespace(metadata.getOpenOLATMetadataCreator())) { author = metadata.getOpenOLATMetadataCreator(); @@ -445,6 +499,18 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { keywords = metadata.getGeneralKeywords(); taxonomyPath = metadata.getClassificationTaxonomy(); + + String level = null; + if(StringHelper.containsNonWhitespace(taxonomyPath)) { + int index = taxonomyPath.lastIndexOf('/'); + if(index >= 0) { + level = taxonomyPath.substring(index + 1, taxonomyPath.length()); + } else { + level = taxonomyPath; + } + } + taxonomyLevel = level; + topic = metadata.getOpenOLATMetadataTopic(); context = metadata.getEducationContext(); if(StringHelper.containsNonWhitespace(metadata.getOpenOLATMetadataQuestionType())) { @@ -453,6 +519,13 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { type = QTI21QuestionType.getType(assessmentItem).name(); } masterIdentifier = metadata.getOpenOLATMetadataMasterIdentifier(); + correctionTime = metadata.getOpenOLATMetadataCorrectionTime() == null ? "" : metadata.getOpenOLATMetadataCorrectionTime().toString(); + + String l = metadata.getLicense(); + if(StringHelper.containsNonWhitespace(l) && l.length() > 32000) { + l = l.substring(0, 32000); + } + license = l; } public QuestionInformations(AssessmentItem assessmentItem) { @@ -461,16 +534,19 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { author = null; keywords = null; taxonomyPath = null; + taxonomyLevel = null; topic = assessmentItem.getLabel(); context = null; masterIdentifier = null; + license = null; QTI21QuestionType qType = QTI21QuestionType.getType(assessmentItem); if(qType == null) { type = null; } else { type = qType.name(); - } + } + correctionTime = null; } public String getAuthor() { @@ -488,6 +564,10 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { public String getKeywords() { return keywords; } + + public String getTaxonomyLevel() { + return taxonomyLevel; + } public String getTaxonomyPath() { return taxonomyPath; @@ -500,6 +580,14 @@ public class QuestionOriginMediaResource extends OpenXMLWorkbookResource { public String getEducationalContextLevel() { return context; } + + public String getCorrectionTime() { + return correctionTime; + } + + public String getLicense() { + return license; + } public String getType() { return type; diff --git a/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_de.properties index d0bf6ef456a54e04dc18e44ffe3209d16c3ccf9b..96b9b6721dddf5784ad5f38f80afc8c0ad1acfad 100644 --- a/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_de.properties @@ -7,8 +7,11 @@ report.course.id=Kurs ID report.explain=Report: gew\u00E4hlte Tests inklusive aller enthaltenen Fragen report.question.title=Titel der Frage report.question.author=Ersteller der Frage (Besitzer) +report.question.correction.time=$org.olat.modules.qpool.ui\:question.correctionTime report.question.identifier=Frage ID report.question.keywords=Schlagwort +report.question.license=$org.olat.modules.qpool.ui\:rights.license +report.question.taxonomy.level=Fachbereich report.question.taxonomy.path=Fachbereichpfad report.question.topic=Thema report.question.context=Stufe diff --git a/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_en.properties index d94fb26cbc8944532d68bb42c9524128c64e4bb4..43dabce57308d76405c1198f6c706aedbdaf20f3 100644 --- a/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_en.properties @@ -7,8 +7,11 @@ report.course.id=Course ID report.explain=Report: selected tests including all contained questions report.question.title=Question's title report.question.author=Question's creator (owner) +report.question.correction.time=$org.olat.modules.qpool.ui\:question.correctionTime report.question.identifier=Question ID report.question.keywords=Keywords +report.question.license=$org.olat.modules.qpool.ui\:rights.license +report.question.taxonomy.level=Subject report.question.taxonomy.path=Subject path report.question.topic=Topic report.question.context=Level diff --git a/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_fr.properties index 880a23dec8365f142992d3fd9f8654d76356a2dd..04f180d60f5824bf1b1b7a1f62c8aedd44abb507 100644 --- a/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/ims/qti21/ui/report/_i18n/LocalStrings_fr.properties @@ -7,11 +7,14 @@ report.course.id=ID du cours report.explain=Rapport\: les tests s\u00E9lectionn\u00E9s et toutes leurs questions report.question.author=Cr\u00E9ateur de la question (propri\u00E9taire) report.question.context=Niveau +report.question.correction.time=$org.olat.modules.qpool.ui\:question.correctionTime report.question.identifier=Question ID report.question.keywords=Mots cl\u00E9s +report.question.license=$org.olat.modules.qpool.ui\:rights.license report.question.master.author=Cr\u00E9ateur (propri\u00E9taire master ID) report.question.master.identifier=Question master ID report.question.master.keywords=Mots cl\u00E9s (question master ID) +report.question.taxonomy.level=Sujet report.question.taxonomy.path=Sujet chemin report.question.title=Titre de la question report.question.to.course=Rapport questions diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java b/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java index fd97b219c23205d468fff84b5c8e2e653fcec6af..2616bd58ccf0c5d1adc3eeac897f62d14651dd3a 100644 --- a/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java +++ b/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java @@ -32,6 +32,7 @@ import java.util.UUID; import org.apache.logging.log4j.Logger; import org.apache.velocity.VelocityContext; +import org.olat.basesecurity.BaseSecurity; import org.olat.core.gui.translator.Translator; import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; @@ -87,6 +88,8 @@ public class ReminderServiceImpl implements ReminderService { private UserManager userManager; @Autowired private ReminderRuleEngine ruleEngine; + @Autowired + private BaseSecurity securityManager; @Override public Reminder createReminder(RepositoryEntry entry, Identity creator) { @@ -284,16 +287,21 @@ public class ReminderServiceImpl implements ReminderService { @Override public void putVariablesInMailContext(VelocityContext vContext, Identity recipient) { User user = recipient.getUser(); - vContext.put("firstname", user.getProperty(UserConstants.FIRSTNAME, null)); - vContext.put(UserConstants.FIRSTNAME, user.getProperty(UserConstants.FIRSTNAME, null)); - vContext.put("lastname", user.getProperty(UserConstants.LASTNAME, null)); - vContext.put(UserConstants.LASTNAME, user.getProperty(UserConstants.LASTNAME, null)); + vContext.put("firstname", user.getFirstName()); + vContext.put(UserConstants.FIRSTNAME, user.getFirstName()); + vContext.put("lastname", user.getLastName()); + vContext.put(UserConstants.LASTNAME, user.getLastName()); String fullName = userManager.getUserDisplayName(recipient); vContext.put("fullname", fullName); vContext.put("fullName", fullName); - vContext.put("mail", userManager.getUserDisplayEmail(user, locale)); - vContext.put("email", userManager.getUserDisplayEmail(user, locale)); - vContext.put("username", recipient.getName()); + String email = userManager.getUserDisplayEmail(user, locale); + vContext.put("mail", email); + vContext.put("email", email); + String loginName = securityManager.findAuthenticationName(recipient); + if(!StringHelper.containsNonWhitespace(loginName)) { + loginName = recipient.getName(); + } + vContext.put("username", loginName); // Put variables from greater context if(entry != null) { vContext.put("courseurl", url); diff --git a/src/main/java/org/olat/user/manager/lifecycle/UserLifecycleManagerImpl.java b/src/main/java/org/olat/user/manager/lifecycle/UserLifecycleManagerImpl.java index 59f35b3db4101177308b27721281b29b75ead7fb..765e70c0c607e3eb0f2a822b57bce830482dac91 100644 --- a/src/main/java/org/olat/user/manager/lifecycle/UserLifecycleManagerImpl.java +++ b/src/main/java/org/olat/user/manager/lifecycle/UserLifecycleManagerImpl.java @@ -45,8 +45,10 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DB; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; +import org.olat.core.id.User; import org.olat.core.id.UserConstants; import org.olat.core.logging.Tracing; +import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.mail.MailBundle; @@ -57,6 +59,7 @@ import org.olat.core.util.session.UserSessionManager; import org.olat.repository.RepositoryDeletionModule; import org.olat.user.UserDataDeletable; import org.olat.user.UserLifecycleManager; +import org.olat.user.UserManager; import org.olat.user.UserModule; import org.olat.user.ui.admin.lifecycle.UserAdminLifecycleConfigurationController; import org.springframework.beans.factory.annotation.Autowired; @@ -84,6 +87,8 @@ public class UserLifecycleManagerImpl implements UserLifecycleManager { @Autowired private MailManager mailManager; @Autowired + private UserManager userManager; + @Autowired private BaseSecurity securityManager; @Autowired private UserSessionManager userSessionManager; @@ -331,7 +336,7 @@ public class UserLifecycleManagerImpl implements UserLifecycleManager { String subject = translator.translate(subjectI18nKey); String body = translator.translate(bodyI18nKey); - LifecycleMailTemplate template = new LifecycleMailTemplate(subject, body); + LifecycleMailTemplate template = new LifecycleMailTemplate(subject, body, locale); sendUserEmailTo(identity, template, type); } @@ -356,15 +361,35 @@ public class UserLifecycleManagerImpl implements UserLifecycleManager { return CalendarUtils.startOfDay(date); } - private static final class LifecycleMailTemplate extends MailTemplate { + private final class LifecycleMailTemplate extends MailTemplate { + + private final Locale locale; - public LifecycleMailTemplate(String subject, String body) { + public LifecycleMailTemplate(String subject, String body, Locale locale) { super(subject, body, null); + this.locale = locale; } @Override public void putVariablesInMailContext(VelocityContext vContext, Identity recipient) { - // + if(recipient != null) { + User user = recipient.getUser(); + + vContext.put("firstname", user.getProperty(UserConstants.FIRSTNAME, null)); + vContext.put(UserConstants.FIRSTNAME, user.getProperty(UserConstants.FIRSTNAME, null)); + vContext.put("lastname", user.getProperty(UserConstants.LASTNAME, null)); + vContext.put(UserConstants.LASTNAME, user.getProperty(UserConstants.LASTNAME, null)); + String fullName = userManager.getUserDisplayName(recipient); + vContext.put("fullname", fullName); + vContext.put("fullName", fullName); + vContext.put("mail", userManager.getUserDisplayEmail(user, locale)); + vContext.put("email", userManager.getUserDisplayEmail(user, locale)); + String loginName = securityManager.findAuthenticationName(recipient); + if(!StringHelper.containsNonWhitespace(loginName)) { + loginName = recipient.getName(); + } + vContext.put("username", loginName); + } } }