/** * INTERNAL METHOD<br> * Get the email address from system settings or the evaluation * * @param eval * @return an email address * @throws IllegalStateException if a from address cannot be found */ public String getFromEmailOrFail(EvalEvaluation eval) { String from = (String) settings.get(EvalSettings.FROM_EMAIL_ADDRESS); if (eval.getReminderFromEmail() != null && !"".equals(eval.getReminderFromEmail())) { from = eval.getReminderFromEmail(); } if (from == null) { throw new IllegalStateException( "Could not get a from email address from system settings or the evaluation"); } return from; }
/* (non-Javadoc) * @see uk.org.ponder.rsf.flow.ActionResultInterceptor#interceptActionResult(uk.org.ponder.rsf.flow.ARIResult, uk.org.ponder.rsf.viewstate.ViewParameters, java.lang.Object) */ public void interceptActionResult( ARIResult result, ViewParameters incoming, Object actionReturn) { // for evaluation creation if (incoming instanceof EvalViewParameters && result.resultingView instanceof EvalViewParameters) { EvalViewParameters in = (EvalViewParameters) incoming; EvalViewParameters outgoing = (EvalViewParameters) result.resultingView; if (in.evaluationId != null) { outgoing.evaluationId = in.evaluationId; } else { EvalEvaluation eval = (EvalEvaluation) evaluationBeanLocator.locateBean(EvaluationBeanLocator.NEW_1); if (eval != null) { outgoing.evaluationId = eval.getId(); } } } }
/* (non-Javadoc) * @see uk.org.ponder.rsf.view.ComponentProducer#fillComponents(uk.org.ponder.rsf.components.UIContainer, uk.org.ponder.rsf.viewstate.ViewParameters, uk.org.ponder.rsf.view.ComponentChecker) */ public void fillComponents( UIContainer tofill, ViewParameters viewparams, ComponentChecker checker) { EvalViewParameters evalViewParams = (EvalViewParameters) viewparams; if (evalViewParams.evaluationId == null) { throw new IllegalArgumentException("Cannot access this view unless the evaluationId is set"); } String actionBean = "setupEvalBean."; String evaluationOTP = "evaluationBeanLocator." + evalViewParams.evaluationId + "."; /** * This is the evaluation we are working with on this page, this should ONLY be read from, do * not change any of these fields */ EvalEvaluation evaluation = evaluationService.getEvaluationById(evalViewParams.evaluationId); String currentEvalState = evaluationService.returnAndFixEvalState(evaluation, true); // local variables used in the render logic String currentUserId = commonLogic.getCurrentUserId(); boolean userAdmin = commonLogic.isUserAdmin(currentUserId); boolean createTemplate = authoringService.canCreateTemplate(currentUserId); boolean beginEvaluation = evaluationService.canBeginEvaluation(currentUserId); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG, locale); DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale); /* * top links here */ UIInternalLink.make( tofill, "summary-link", UIMessage.make("summary.page.title"), new SimpleViewParameters(SummaryProducer.VIEW_ID)); if (userAdmin) { UIInternalLink.make( tofill, "administrate-link", UIMessage.make("administrate.page.title"), new SimpleViewParameters(AdministrateProducer.VIEW_ID)); UIInternalLink.make( tofill, "control-scales-link", UIMessage.make("controlscales.page.title"), new SimpleViewParameters(ControlScalesProducer.VIEW_ID)); } if (createTemplate) { UIInternalLink.make( tofill, "control-templates-link", UIMessage.make("controltemplates.page.title"), new SimpleViewParameters(ControlTemplatesProducer.VIEW_ID)); UIInternalLink.make( tofill, "control-items-link", UIMessage.make("controlitems.page.title"), new SimpleViewParameters(ControlItemsProducer.VIEW_ID)); } if (beginEvaluation) { UIInternalLink.make( tofill, "control-evaluations-link", UIMessage.make("controlevaluations.page.title"), new SimpleViewParameters(ControlEvaluationsProducer.VIEW_ID)); } else { throw new SecurityException( "User attempted to access " + VIEW_ID + " when they are not allowed"); } UIInternalLink.make( tofill, "eval-settings-link", UIMessage.make("evalsettings.page.title"), new EvalViewParameters(EvaluationSettingsProducer.VIEW_ID, evalViewParams.evaluationId)); if (EvalConstants.EVALUATION_STATE_PARTIAL.equals(evaluation.getState())) { // creating a new eval UIMessage.make(tofill, "eval-start-text", "starteval.page.title"); } UIForm form = UIForm.make(tofill, "evalSettingsForm"); // REOPENING eval (SPECIAL CASE) Date reOpenDueDate = null; Date reOpenStopDate = null; boolean reOpening = false; if (evalViewParams.reOpening) { Boolean enableReOpen = (Boolean) settings.get(EvalSettings.ENABLE_EVAL_REOPEN); if (enableReOpen) { // check if already active, do nothing if not closed if (EvalUtils.checkStateAfter( currentEvalState, EvalConstants.EVALUATION_STATE_CLOSED, false)) { // force the due and stop dates to something reasonable Calendar calendar = new GregorianCalendar(); calendar.setTime(new Date()); calendar.add(Calendar.DATE, 1); reOpenDueDate = calendar.getTime(); Boolean useStopDate = (Boolean) settings.get(EvalSettings.EVAL_USE_STOP_DATE); if (useStopDate) { // assign stop date to equal due date for now reOpenStopDate = calendar.getTime(); } // finally force the state to appear active currentEvalState = EvalConstants.EVALUATION_STATE_ACTIVE; form.parameters.add( new UIELBinding(actionBean + "reOpening", true)); // so we know we are reopening reOpening = true; } } } // EVALUATION TITLE/INSTRUCTIONS if (EvalUtils.checkStateBefore(currentEvalState, EvalConstants.EVALUATION_STATE_ACTIVE, true)) { UIInput.make(form, "title", evaluationOTP + "title"); } else { UIOutput.make(tofill, "title_disabled", evaluation.getTitle()); } if (EvalUtils.checkStateBefore(currentEvalState, EvalConstants.EVALUATION_STATE_CLOSED, true)) { UIInput instructionsInput = UIInput.make(form, "instructions:", evaluationOTP + "instructions"); instructionsInput.decorators = new DecoratorList(new UITextDimensionsDecorator(60, 4)); richTextEvolver.evolveTextInput(instructionsInput); } else { UIVerbatim.make(tofill, "instructions_disabled", evaluation.getInstructions()); } // only put up the controls/auto binding if this is not already set if (evaluation.getTemplate() == null) { // Make bottom table containing the list of templates if no template set if (evalViewParams.templateId == null) { // get the templates usable by this user List<EvalTemplate> templateList = authoringService.getTemplatesForUser(currentUserId, null, false); if (templateList.size() > 0) { UIBranchContainer chooseTemplate = UIBranchContainer.make(form, "chooseTemplate:"); String[] values = new String[templateList.size()]; String[] labels = new String[templateList.size()]; // TODO - this is not a good way to do this UISelect radios = UISelect.make( chooseTemplate, "templateRadio", null, null, actionBean + "templateId", null); String selectID = radios.getFullID(); for (int i = 0; i < templateList.size(); i++) { EvalTemplate template = templateList.get(i); values[i] = template.getId().toString(); labels[i] = template.getTitle(); UIBranchContainer radiobranch = UIBranchContainer.make(chooseTemplate, "templateOptions:", i + ""); UISelectChoice.make(radiobranch, "radioValue", selectID, i); UISelectLabel.make(radiobranch, "radioLabel", selectID, i); EvalUser owner = commonLogic.getEvalUserById(template.getOwner()); UIOutput.make(radiobranch, "radioOwner", owner.displayName); UIInternalLink.make( radiobranch, "viewPreview_link", UIMessage.make("starteval.view.preview.link"), new EvalViewParameters(PreviewEvalProducer.VIEW_ID, null, template.getId())); } // need to assign the choices and labels at the end here since we used nulls at the // beginning radios.optionlist = UIOutputMany.make(values); radios.optionnames = UIOutputMany.make(labels); } else { throw new IllegalStateException( "User got to evaluation settings when they have no access to any templates... " + "producer suicide was the only way out"); } } else { // just bind in the template explicitly to the evaluation form.parameters.add( new UIELBinding( evaluationOTP + "template", new ELReference("templateBeanLocator." + evalViewParams.templateId))); } } else { EvalTemplate template = authoringService.getTemplateById(evaluation.getTemplate().getId()); UIBranchContainer showTemplateBranch = UIBranchContainer.make(tofill, "showTemplate:"); UIMessage.make( showTemplateBranch, "eval_template_title", "evalsettings.template.title.display", new Object[] {template.getTitle()}); UIInternalLink.make( showTemplateBranch, "eval_template_preview_link", UIMessage.make("evalsettings.template.preview.link"), new EvalViewParameters(PreviewEvalProducer.VIEW_ID, null, template.getId())); if (!template.getLocked().booleanValue() && authoringService.canModifyTemplate(currentUserId, template.getId())) { UIInternalLink.make( showTemplateBranch, "eval_template_modify_link", UIMessage.make("general.command.edit"), new TemplateViewParameters(ModifyTemplateItemsProducer.VIEW_ID, template.getId())); } } // EVALUATION DATES Date today = new Date(); UIMessage.make( tofill, "current_date", "evalsettings.dates.current", new Object[] {dateFormat.format(today), timeFormat.format(today)}); // retrieve the global setting for use of date only or date and time picker Boolean useDateTime = (Boolean) settings.get(EvalSettings.EVAL_USE_DATE_TIME); // Start Date UIBranchContainer showStartDate = UIBranchContainer.make(form, "showStartDate:"); generateDateSelector( showStartDate, "startDate", evaluationOTP + "startDate", null, currentEvalState, EvalConstants.EVALUATION_STATE_ACTIVE, useDateTime); // Due Date UIBranchContainer showDueDate = UIBranchContainer.make(form, "showDueDate:"); generateDateSelector( showDueDate, "dueDate", evaluationOTP + "dueDate", reOpenDueDate, currentEvalState, EvalConstants.EVALUATION_STATE_GRACEPERIOD, useDateTime); // Stop Date - Show the "Stop date" text box only if allowed in the System settings Boolean useStopDate = (Boolean) settings.get(EvalSettings.EVAL_USE_STOP_DATE); if (useStopDate) { UIBranchContainer showStopDate = UIBranchContainer.make(form, "showStopDate:"); generateDateSelector( showStopDate, "stopDate", evaluationOTP + "stopDate", reOpenStopDate, currentEvalState, EvalConstants.EVALUATION_STATE_CLOSED, useDateTime); } // EVALUATION RESULTS VIEWING/SHARING // radio buttons for the results sharing options UISelect resultsSharingRadios = UISelect.make( form, "dummyRadioSharing", EvalToolConstants.EVAL_RESULTS_SHARING_VALUES, EvalToolConstants.EVAL_RESULTS_SHARING_LABELS_PROPS, evaluationOTP + "resultsSharing", null) .setMessageKeys(); String resultsSharingId = resultsSharingRadios.getFullID(); for (int i = 0; i < EvalToolConstants.EVAL_RESULTS_SHARING_VALUES.length; ++i) { UIBranchContainer radiobranch = UIBranchContainer.make(form, "resultsSharingChoice:", i + ""); UISelectChoice choice = UISelectChoice.make(radiobranch, "radioValue", resultsSharingId, i); UISelectLabel.make(radiobranch, "radioLabel", resultsSharingId, i) .decorate(new UILabelTargetDecorator(choice)); } // show the view date only if allowed by system settings if (((Boolean) settings.get(EvalSettings.EVAL_USE_VIEW_DATE)).booleanValue()) { UIBranchContainer showViewDate = UIBranchContainer.make(form, "showViewDate:"); generateDateSelector( showViewDate, "viewDate", evaluationOTP + "viewDate", null, currentEvalState, EvalConstants.EVALUATION_STATE_VIEWABLE, useDateTime); } // all types of users view results on the same date or we can configure the results viewing // separately boolean sameViewDateForAll = (Boolean) settings.get(EvalSettings.EVAL_USE_SAME_VIEW_DATES); // Student view date Boolean studentViewResults = (Boolean) settings.get(EvalSettings.STUDENT_ALLOWED_VIEW_RESULTS); UIBranchContainer showResultsToStudents = UIBranchContainer.make(form, "showResultsToStudents:"); generateSettingsControlledCheckbox( showResultsToStudents, "studentViewResults", evaluationOTP + "studentViewResults", studentViewResults, form, EvalUtils.checkStateAfter(currentEvalState, EvalConstants.EVALUATION_STATE_VIEWABLE, true)); generateViewDateControl( showResultsToStudents, "studentsViewDate", evaluationOTP + "studentsDate", studentViewResults, useDateTime, sameViewDateForAll); // Instructor view date Boolean instructorViewResults = (Boolean) settings.get(EvalSettings.INSTRUCTOR_ALLOWED_VIEW_RESULTS); UIBranchContainer showResultsToInst = UIBranchContainer.make(form, "showResultsToInst:"); generateSettingsControlledCheckbox( showResultsToInst, "instructorViewResults", evaluationOTP + "instructorViewResults", instructorViewResults, form, EvalUtils.checkStateAfter(currentEvalState, EvalConstants.EVALUATION_STATE_VIEWABLE, true)); generateViewDateControl( showResultsToInst, "instructorsViewDate", evaluationOTP + "instructorsDate", instructorViewResults, useDateTime, sameViewDateForAll); // RESPONDENT SETTINGS // Student Allowed Leave Unanswered Boolean studentUnanswersAllowed = (Boolean) settings.get(EvalSettings.STUDENT_ALLOWED_LEAVE_UNANSWERED); UIBranchContainer showBlankQuestionAllowedToStut = UIBranchContainer.make(form, "showBlankQuestionAllowedToStut:"); generateSettingsControlledCheckbox( showBlankQuestionAllowedToStut, "blankResponsesAllowed", evaluationOTP + "blankResponsesAllowed", studentUnanswersAllowed, form, EvalUtils.checkStateAfter(currentEvalState, EvalConstants.EVALUATION_STATE_ACTIVE, true)); // Student Modify Responses Boolean studentModifyReponses = (Boolean) settings.get(EvalSettings.STUDENT_MODIFY_RESPONSES); UIBranchContainer showModifyResponsesAllowedToStu = UIBranchContainer.make(form, "showModifyResponsesAllowedToStu:"); generateSettingsControlledCheckbox( showModifyResponsesAllowedToStu, "modifyResponsesAllowed", evaluationOTP + "modifyResponsesAllowed", studentModifyReponses, form, EvalUtils.checkStateAfter(currentEvalState, EvalConstants.EVALUATION_STATE_ACTIVE, true)); // ADMIN SETTINGS SECTION UISelect authControlSelect = UISelect.make( form, "auth-control-choose", EvalToolConstants.AUTHCONTROL_VALUES, EvalToolConstants.AUTHCONTROL_LABELS, evaluationOTP + "authControl") .setMessageKeys(); if (EvalUtils.checkStateAfter(currentEvalState, EvalConstants.EVALUATION_STATE_ACTIVE, true)) { RSFUtils.disableComponent(authControlSelect); } if (userAdmin) { // If the person is an admin (any kind), then we need to show these instructor opt in/out // settings UIMessage.make( form, "instructor-opt-instructions", "evalsettings.admin.settings.instructions"); UIMessage.make(form, "instructor-opt-header", "evalsettings.instructor.opt.desc"); // If "EvalSettings.INSTRUCTOR_MUST_USE_EVALS_FROM_ABOVE" is set as configurable // i.e. NULL in the database then show the instructor opt select box. Else just show the value // as label String instUseFromAboveValue = (String) settings.get(EvalSettings.INSTRUCTOR_MUST_USE_EVALS_FROM_ABOVE); if (instUseFromAboveValue == null || EvalToolConstants.ADMIN_BOOLEAN_CONFIGURABLE.equals(instUseFromAboveValue)) { UISelect instOpt = UISelect.make( form, "instructorOpt", EvalToolConstants.INSTRUCTOR_OPT_VALUES, EvalToolConstants.INSTRUCTOR_OPT_LABELS, evaluationOTP + "instructorOpt") .setMessageKeys(); if (EvalUtils.checkStateAfter( currentEvalState, EvalConstants.EVALUATION_STATE_INQUEUE, true)) { RSFUtils.disableComponent(instOpt); } } else { int index = ArrayUtil.indexOf(EvalToolConstants.INSTRUCTOR_OPT_VALUES, instUseFromAboveValue); String instUseFromAboveLabel = EvalToolConstants.INSTRUCTOR_OPT_LABELS[index]; // Displaying the label corresponding to INSTRUCTOR_MUST_USE_EVALS_FROM_ABOVE value set as // system property UIMessage.make(form, "instructorOptLabel", instUseFromAboveLabel); // Doing the binding of this INSTRUCTOR_MUST_USE_EVALS_FROM_ABOVE value so that it can be // saved in the database form.parameters.add( new UIELBinding(evaluationOTP + "instructorOpt", instUseFromAboveValue)); } } // EVALUATION REMINDERS SECTION // email available template link UIInternalLink.make( form, "emailAvailable_link", UIMessage.make("evalsettings.available.mail.link"), new EmailViewParameters( PreviewEmailProducer.VIEW_ID, null, EvalConstants.EMAIL_TEMPLATE_AVAILABLE, evaluation.getId())); // email reminder control UISelect reminderDaysSelect = UISelect.make( form, "reminderDays", EvalToolConstants.REMINDER_EMAIL_DAYS_VALUES, EvalToolConstants.REMINDER_EMAIL_DAYS_LABELS, evaluationOTP + "reminderDays") .setMessageKeys(); if (EvalUtils.checkStateAfter( currentEvalState, EvalConstants.EVALUATION_STATE_GRACEPERIOD, true)) { RSFUtils.disableComponent(reminderDaysSelect); } // email reminder template link UIInternalLink.make( form, "emailReminder_link", UIMessage.make("evalsettings.reminder.mail.link"), new EmailViewParameters( PreviewEmailProducer.VIEW_ID, null, EvalConstants.EMAIL_TEMPLATE_REMINDER, evaluation.getId())); // email from address control String defaultEmail = (String) settings.get(EvalSettings.FROM_EMAIL_ADDRESS); UIMessage.make( form, "eval-from-email-note", "evalsettings.email.sent.from", new String[] {defaultEmail}); UIInput.make(form, "reminderFromEmail", evaluationOTP + "reminderFromEmail"); // EVALUATION EXTRAS SECTION Boolean categoriesEnabled = (Boolean) settings.get(EvalSettings.ENABLE_EVAL_CATEGORIES); if (categoriesEnabled) { UIBranchContainer extrasBranch = UIBranchContainer.make(form, "showEvalExtras:"); // eval category if (categoriesEnabled) { UIBranchContainer categoryBranch = UIBranchContainer.make(extrasBranch, "showCategory:"); UIInput.make(categoryBranch, "eval-category", evaluationOTP + "evalCategory"); if (evaluation.getEvalCategory() != null) { UILink.make( categoryBranch, "eval-category-direct-link", UIMessage.make("general.direct.link"), commonLogic.getEntityURL( EvalCategoryEntityProvider.ENTITY_PREFIX, evaluation.getEvalCategory())) .decorate(new UITooltipDecorator(UIMessage.make("general.direct.link.title"))); } } } // EVAL SETTINGS SAVING CONTROLS // if this evaluation is already saved, show "Save Settings" button else this is the "Continue // to Assign to Courses" button String messageKey = "evalsettings.save.settings.link"; if (EvalConstants.EVALUATION_STATE_PARTIAL.equals(evaluation.getState())) { messageKey = "evalsettings.continue.assigning.link"; } if (reOpening) { messageKey = "evalsettings.reopening.eval.link"; } UICommand.make( form, "continueAssigning", UIMessage.make(messageKey), actionBean + "completeSettingsAction"); UIMessage.make(tofill, "cancel-button", "general.cancel.button"); // this fills in the javascript call (areaId, selectId, selectValue, reminderId) // NOTE: RSF bug causes us to have to generate the ids manually // (http://www.caret.cam.ac.uk/jira/browse/RSF-65) UIInitBlock.make( tofill, "initJavascript", "EvalSystem.initEvalSettings", new Object[] { "evaluation_reminder_area", authControlSelect.getFullID() + "-selection", EvalConstants.EVALUATION_AUTHCONTROL_NONE, reminderDaysSelect.getFullID() + "-selection" }); }
/* (non-Javadoc) * @see org.sakaiproject.evaluation.logic.EvalEmailsLogic#sendEvalCreatedNotifications(java.lang.Long, boolean) */ public String[] sendEvalCreatedNotifications(Long evaluationId, boolean includeOwner) { log.debug("evaluationId: " + evaluationId + ", includeOwner: " + includeOwner); EvalEvaluation eval = getEvaluationOrFail(evaluationId); String from = getFromEmailOrFail(eval); EvalEmailTemplate emailTemplate = getEmailTemplateOrFail(EvalConstants.EMAIL_TEMPLATE_CREATED, evaluationId); Map<String, String> replacementValues = new HashMap<String, String>(); replacementValues.put("HelpdeskEmail", from); // setup the opt-in, opt-out, and add questions variables int addItems = ((Integer) settings.get(EvalSettings.ADMIN_ADD_ITEMS_NUMBER)).intValue(); if (!eval.getInstructorOpt().equals(EvalConstants.INSTRUCTOR_REQUIRED) || (addItems > 0)) { if (eval.getInstructorOpt().equals(EvalConstants.INSTRUCTOR_OPT_IN)) { // if eval is opt-in notify instructors that they may opt in replacementValues.put("ShowOptInText", "true"); } else if (eval.getInstructorOpt().equals(EvalConstants.INSTRUCTOR_OPT_OUT)) { // if eval is opt-out notify instructors that they may opt out replacementValues.put("ShowOptOutText", "true"); } if (addItems > 0) { // if eval allows instructors to add questions notify instructors they may add questions replacementValues.put("ShowAddItemsText", "true"); } } String message = emailTemplate.getMessage(); // get the associated groups for this evaluation Map<Long, List<EvalGroup>> evalGroups = evaluationService.getEvalGroupsForEval(new Long[] {evaluationId}, true, null); // only one possible map key so we can assume evaluationId List<EvalGroup> groups = evalGroups.get(evaluationId); if (log.isDebugEnabled()) { log.debug("Found " + groups.size() + " groups for new evaluation: " + evaluationId); } List<String> sentEmails = new ArrayList<String>(); // loop through contexts and send emails to correct users in each evalGroupId for (int i = 0; i < groups.size(); i++) { EvalGroup group = (EvalGroup) groups.get(i); if (EvalConstants.GROUP_TYPE_INVALID.equals(group.type)) { continue; // skip processing for invalid groups } Set<String> userIdsSet = commonLogic.getUserIdsForEvalGroup(group.evalGroupId, EvalConstants.PERM_BE_EVALUATED); // add in the owner or remove them based on the setting if (includeOwner) { userIdsSet.add(eval.getOwner()); } else { if (userIdsSet.contains(eval.getOwner())) { userIdsSet.remove(eval.getOwner()); } } // skip ahead if there is no one to send to if (userIdsSet.size() == 0) continue; // turn the set into an array String[] toUserIds = (String[]) userIdsSet.toArray(new String[] {}); if (log.isDebugEnabled()) { log.debug( "Found " + toUserIds.length + " users (" + toUserIds + ") to send " + EvalConstants.EMAIL_TEMPLATE_CREATED + " notification to for new evaluation (" + evaluationId + ") and evalGroupId (" + group.evalGroupId + ")"); } // replace the text of the template with real values message = makeEmailMessage(message, eval, group, replacementValues); String subject = makeEmailMessage(emailTemplate.getSubject(), eval, group, replacementValues); // send the actual emails for this evalGroupId String[] emailAddresses = commonLogic.sendEmailsToUsers(from, toUserIds, subject, message, true); log.info( "Sent evaluation created message to " + emailAddresses.length + " users (attempted to send to " + toUserIds.length + ")"); // store sent emails to return for (int j = 0; j < emailAddresses.length; j++) { sentEmails.add(emailAddresses[j]); } commonLogic.registerEntityEvent(EVENT_EMAIL_CREATED, eval); } return (String[]) sentEmails.toArray(new String[] {}); }
/** * INTERNAL METHOD<br> * Builds the email message from a template and a bunch of variables (passed in and otherwise) * * @param messageTemplate * @param eval * @param group * @param replacementValues a map of String -> String representing $keys in the template to * replace with text values * @return the processed message template with replacements and logic handled */ public String makeEmailMessage( String messageTemplate, EvalEvaluation eval, EvalGroup group, Map<String, String> replacementValues) { // replace the text of the template with real values if (replacementValues == null) { replacementValues = new HashMap<String, String>(); } replacementValues.put("EvalTitle", eval.getTitle()); // use a date which is related to the current users locale DateFormat df = DateFormat.getDateInstance( DateFormat.MEDIUM, commonLogic.getUserLocale(commonLogic.getCurrentUserId())); replacementValues.put("EvalStartDate", df.format(eval.getStartDate())); String dueDate = "--------"; if (eval.getDueDate() != null) { dueDate = df.format(eval.getDueDate()); } replacementValues.put("EvalDueDate", dueDate); String viewDate = null; if (eval.getViewDate() != null) { viewDate = df.format(eval.getDueDate()); } else { viewDate = dueDate; } replacementValues.put("EvalResultsDate", viewDate); replacementValues.put("EvalGroupTitle", group.title); // ensure that the if-then variables are set to false if they are unset if (!replacementValues.containsKey("ShowAddItemsText")) { replacementValues.put("ShowAddItemsText", "false"); } if (!replacementValues.containsKey("ShowOptInText")) { replacementValues.put("ShowOptInText", "false"); } if (!replacementValues.containsKey("ShowOptOutText")) { replacementValues.put("ShowOptOutText", "false"); } // generate URLs to the evaluation String evalEntityURL = null; if (group != null && group.evalGroupId != null) { // get the URL directly to the evaluation with group context included Long assignGroupId = evaluationService.getAssignGroupId(eval.getId(), group.evalGroupId); EvalAssignGroup assignGroup = evaluationService.getAssignGroupById(assignGroupId); if (assignGroup != null) { evalEntityURL = commonLogic.getEntityURL(assignGroup); } } if (evalEntityURL == null) { // just get the URL to the evaluation without group context evalEntityURL = commonLogic.getEntityURL(eval); } // all URLs are identical because the user permissions determine access uniquely replacementValues.put("URLtoTakeEval", evalEntityURL); replacementValues.put("URLtoAddItems", evalEntityURL); replacementValues.put("URLtoOptIn", evalEntityURL); replacementValues.put("URLtoOptOut", evalEntityURL); replacementValues.put("URLtoViewResults", evalEntityURL); replacementValues.put("URLtoSystem", commonLogic.getServerUrl()); return TextTemplateLogicUtils.processTextTemplate(messageTemplate, replacementValues); }
/* (non-Javadoc) * @see org.sakaiproject.evaluation.logic.EvalEmailsLogic#sendEvalResultsNotifications(java.lang.Long, boolean, boolean, java.lang.String) */ public String[] sendEvalResultsNotifications( Long evaluationId, boolean includeEvaluatees, boolean includeAdmins, String jobType) { log.debug( "evaluationId: " + evaluationId + ", includeEvaluatees: " + includeEvaluatees + ", includeAdmins: " + includeAdmins); /*TODO deprecated? if(EvalConstants.EVAL_INCLUDE_ALL.equals(includeConstant)) { } boolean includeEvaluatees = true; if (includeEvaluatees) { // TODO Not done yet log.error("includeEvaluatees Not implemented"); } */ EvalEvaluation eval = getEvaluationOrFail(evaluationId); String from = getFromEmailOrFail(eval); EvalEmailTemplate emailTemplate = getEmailTemplateOrFail(EvalConstants.EMAIL_TEMPLATE_RESULTS, evaluationId); // get the associated eval groups for this evaluation Map<Long, List<EvalGroup>> evalGroupIds = evaluationService.getEvalGroupsForEval(new Long[] {evaluationId}, false, null); // only one possible map key so we can assume evaluationId List<EvalGroup> groups = evalGroupIds.get(evaluationId); if (log.isDebugEnabled()) log.debug("Found " + groups.size() + " groups for available evaluation: " + evaluationId); Map<String, EvalGroup> groupsMap = new HashMap<String, EvalGroup>(); for (EvalGroup evalGroup : groups) { groupsMap.put(evalGroup.evalGroupId, evalGroup); } // get the associated eval assign groups for this evaluation Map<Long, List<EvalAssignGroup>> evalAssignGroups = evaluationService.getAssignGroupsForEvals(new Long[] {evaluationId}, false, null); // only one possible map key so we can assume evaluationId List<EvalAssignGroup> assignGroups = evalAssignGroups.get(evaluationId); if (log.isDebugEnabled()) log.debug( "Found " + assignGroups.size() + " assign groups for available evaluation: " + evaluationId); List<String> sentEmails = new ArrayList<String>(); // loop through groups and send emails to correct users in each evalGroupId for (int i = 0; i < assignGroups.size(); i++) { EvalAssignGroup evalAssignGroup = assignGroups.get(i); String evalGroupId = evalAssignGroup.getEvalGroupId(); EvalGroup group = groupsMap.get(evalGroupId); if (group == null || EvalConstants.GROUP_TYPE_INVALID.equals(group.type)) { log.warn( "Invalid group returned for groupId (" + evalGroupId + "), could not send results notifications"); continue; } /* * Notification of results may occur on separate dates for owner, * instructors, and students. Job type is used to distinguish the * intended recipient group. */ // always send results email to eval.getOwner() Set<String> userIdsSet = new HashSet<String>(); if (jobType.equals(EvalConstants.JOB_TYPE_VIEWABLE)) { userIdsSet.add(eval.getOwner()); } // if results are not private if (!EvalConstants.SHARING_PRIVATE.equals(eval.getResultsSharing())) { // at present, includeAdmins is always true if (includeAdmins && evalAssignGroup.getInstructorsViewResults().booleanValue() && jobType.equals(EvalConstants.JOB_TYPE_VIEWABLE_INSTRUCTORS)) { userIdsSet.addAll( commonLogic.getUserIdsForEvalGroup(evalGroupId, EvalConstants.PERM_BE_EVALUATED)); } // at present, includeEvaluatees is always true if (includeEvaluatees && evalAssignGroup.getStudentsViewResults().booleanValue() && jobType.equals(EvalConstants.JOB_TYPE_VIEWABLE_STUDENTS)) { userIdsSet.addAll( commonLogic.getUserIdsForEvalGroup(evalGroupId, EvalConstants.PERM_TAKE_EVALUATION)); } } if (userIdsSet.size() > 0) { // turn the set into an array String[] toUserIds = (String[]) userIdsSet.toArray(new String[] {}); log.debug( "Found " + toUserIds.length + " users (" + toUserIds + ") to send " + EvalConstants.EMAIL_TEMPLATE_RESULTS + " notification to for available evaluation (" + evaluationId + ") and group (" + evalGroupId + ")"); // replace the text of the template with real values Map<String, String> replacementValues = new HashMap<String, String>(); replacementValues.put("HelpdeskEmail", from); String message = makeEmailMessage(emailTemplate.getMessage(), eval, group, replacementValues); String subject = makeEmailMessage(emailTemplate.getSubject(), eval, group, replacementValues); // send the actual emails for this evalGroupId String[] emailAddresses = commonLogic.sendEmailsToUsers(from, toUserIds, subject, message, true); log.info( "Sent evaluation results message to " + emailAddresses.length + " users (attempted to send to " + toUserIds.length + ")"); // store sent emails to return for (int j = 0; j < emailAddresses.length; j++) { sentEmails.add(emailAddresses[j]); } commonLogic.registerEntityEvent(EVENT_EMAIL_RESULTS, eval); } } return (String[]) sentEmails.toArray(new String[] {}); }
/* (non-Javadoc) * @see org.sakaiproject.evaluation.logic.EvalEmailsLogic#sendEvalAvailableNotifications(java.lang.Long, boolean) */ public String[] sendEvalAvailableNotifications(Long evaluationId, boolean includeEvaluatees) { log.debug("evaluationId: " + evaluationId + ", includeEvaluatees: " + includeEvaluatees); Set<String> userIdsSet = null; String message = null; boolean studentNotification = true; EvalEvaluation eval = getEvaluationOrFail(evaluationId); String from = getFromEmailOrFail(eval); EvalEmailTemplate emailTemplate = getEmailTemplateOrFail(EvalConstants.EMAIL_TEMPLATE_AVAILABLE, evaluationId); // get the instructor opt-in email template EvalEmailTemplate emailOptInTemplate = getEmailTemplateOrFail(EvalConstants.EMAIL_TEMPLATE_AVAILABLE_OPT_IN, null); // get the associated assign groups for this evaluation Map<Long, List<EvalAssignGroup>> evalAssignGroups = evaluationService.getAssignGroupsForEvals(new Long[] {evaluationId}, true, null); List<EvalAssignGroup> assignGroups = evalAssignGroups.get(evaluationId); List<String> sentEmails = new ArrayList<String>(); // loop through groups and send emails to correct users group for (int i = 0; i < assignGroups.size(); i++) { EvalAssignGroup assignGroup = assignGroups.get(i); EvalGroup group = commonLogic.makeEvalGroupObject(assignGroup.getEvalGroupId()); if (eval.getInstructorOpt().equals(EvalConstants.INSTRUCTOR_REQUIRED)) { // notify students userIdsSet = commonLogic.getUserIdsForEvalGroup( group.evalGroupId, EvalConstants.PERM_TAKE_EVALUATION); studentNotification = true; } else { // instructor may opt-in or opt-out if (assignGroup.getInstructorApproval().booleanValue()) { // instructor has opted-in, notify students userIdsSet = commonLogic.getUserIdsForEvalGroup( group.evalGroupId, EvalConstants.PERM_TAKE_EVALUATION); studentNotification = true; } else { if (eval.getInstructorOpt().equals(EvalConstants.INSTRUCTOR_OPT_IN) && includeEvaluatees) { // instructor has not opted-in, notify instructors userIdsSet = commonLogic.getUserIdsForEvalGroup( group.evalGroupId, EvalConstants.PERM_BE_EVALUATED); studentNotification = false; } else { userIdsSet = new HashSet<String>(); } } } // skip ahead if there is no one to send to if (userIdsSet.size() == 0) continue; // turn the set into an array String[] toUserIds = (String[]) userIdsSet.toArray(new String[] {}); if (log.isDebugEnabled()) { log.debug( "Found " + toUserIds.length + " users (" + toUserIds + ") to send " + EvalConstants.EMAIL_TEMPLATE_CREATED + " notification to for available evaluation (" + evaluationId + ") and group (" + group.evalGroupId + ")"); } // replace the text of the template with real values Map<String, String> replacementValues = new HashMap<String, String>(); replacementValues.put("HelpdeskEmail", from); // choose from 2 templates EvalEmailTemplate currentTemplate = emailTemplate; if (!studentNotification) { currentTemplate = emailOptInTemplate; } message = makeEmailMessage(currentTemplate.getMessage(), eval, group, replacementValues); String subject = makeEmailMessage(currentTemplate.getSubject(), eval, group, replacementValues); // send the actual emails for this evalGroupId String[] emailAddresses = commonLogic.sendEmailsToUsers(from, toUserIds, subject, message, true); log.info( "Sent evaluation available message to " + emailAddresses.length + " users (attempted to send to " + toUserIds.length + ")"); // store sent emails to return for (int j = 0; j < emailAddresses.length; j++) { sentEmails.add(emailAddresses[j]); } commonLogic.registerEntityEvent(EVENT_EMAIL_AVAILABLE, eval); } return (String[]) sentEmails.toArray(new String[] {}); }