/** * <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.user; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.olat.core.gui.UserRequest; 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.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.elements.RichTextElement; import org.olat.core.gui.components.form.flexible.elements.SpacerElement; import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; 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.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.id.User; import org.olat.registration.RegistrationManager; import org.olat.registration.TemporaryKeyImpl; import org.olat.user.propertyhandlers.UserPropertyHandler; import com.thoughtworks.xstream.XStream; /** * Provides a controller which lets the user edit their user profile and choose * the fields which are made publicly visible. * * @author twuersch * */ public class ProfileFormController extends FormBasicController { private HomePageConfig conf; private List<UserPropertyHandler> userPropertyHandlers; private Map<String, FormItem> formItems; private Map<String, String> formContext; private RichTextElement textAboutMe; private String usageIdentifier; private Map<String, MultipleSelectionElement> publishCheckboxes; private Identity identity; private boolean isAdministrativeUser; private List<String> propertyNames; /** * Creates this controller. * * @param ureq The user request. * @param wControl The window control. * @param conf The homepage configuration (decides which user profile fields * are visible for everyone). * @param identity The identity of the user. * @param isAdministrativeUser true: user is editing another users profile as * user manager; false: use is editing his own profile */ public ProfileFormController(UserRequest ureq, WindowControl wControl, HomePageConfig conf, Identity identity, boolean isAdministrativeUser) { super(ureq, wControl, "combinedform"); UserManager um = UserManager.getInstance(); setTranslator(um.getPropertyHandlerTranslator(getTranslator())); this.publishCheckboxes = new HashMap<String, MultipleSelectionElement>(); this.conf = conf; this.usageIdentifier = ProfileFormController.class.getCanonicalName(); this.userPropertyHandlers = um.getUserPropertyHandlersFor(this.usageIdentifier, isAdministrativeUser); this.identity = identity; this.formItems = new HashMap<String, FormItem>(); this.formContext = new HashMap<String, String>(); this.isAdministrativeUser = isAdministrativeUser; initForm(ureq); } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose() */ @Override protected void doDispose() { // nothing to dispose. } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest) */ @Override protected void formOK(UserRequest ureq) { fireEvent(ureq, Event.DONE_EVENT); } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formNOK(org.olat.core.gui.UserRequest) */ @Override protected void formNOK(UserRequest ureq) { fireEvent(ureq, Event.FAILED_EVENT); } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formCancelled(org.olat.core.gui.UserRequest) */ @Override protected void formCancelled(UserRequest ureq) { fireEvent(ureq, Event.CANCELLED_EVENT); } /* * (non-Javadoc) * * @see * org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm * (org.olat.core.gui.components.form.flexible.FormItemContainer, * org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest) */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { setFormDescription("form.description"); this.formContext.put("username", this.identity.getName()); // Add the noneditable username field. MultipleSelectionElement usernameCheckbox = uifactory.addCheckboxesHorizontal("checkbox_username", null, formLayout, new String[] {"checkbox_username"}, new String[] {""}, null); usernameCheckbox.select("checkbox_username", true); usernameCheckbox.setEnabled(false); StaticTextElement usernameText = uifactory.addStaticTextElement("username", this.identity.getName(), formLayout); usernameText.setMandatory(true); this.formItems.put("username", usernameText); String currentGroup = null; List<UserPropertyHandler> homepagePropertyHanders = UserManager.getInstance().getUserPropertyHandlersFor(HomePageConfig.class.getCanonicalName(), isAdministrativeUser); // show a form element for each property handler for (UserPropertyHandler userPropertyHandler : this.userPropertyHandlers) { if (userPropertyHandler == null) { continue; } // add spacer if necessary (i.e. when group name changes) String group = userPropertyHandler.getGroup(); if (!group.equals(currentGroup)) { if (currentGroup != null) { SpacerElement spacerElement = uifactory.addSpacerElement("spacer_" + group, formLayout, false); this.formItems.put("spacer_" + group, spacerElement); } currentGroup = group; } if (homepagePropertyHanders.contains(userPropertyHandler)) { // add checkbox to container if configured for homepage usage identifier String checkboxName = "checkbox_" + userPropertyHandler.getName(); MultipleSelectionElement publishCheckbox = uifactory.addCheckboxesHorizontal(checkboxName, null, formLayout, new String[] {userPropertyHandler.i18nFormElementLabelKey()}, new String[] {""}, null); this.publishCheckboxes.put(checkboxName, publishCheckbox); boolean isEnabled = this.conf.isEnabled(userPropertyHandler.getName()); if (isEnabled) { publishCheckbox.select(userPropertyHandler.i18nFormElementLabelKey(), true); } else { publishCheckbox.select(userPropertyHandler.i18nFormElementLabelKey(), false); } // Mandatory homepage properties can not be changed by user UserManager um = UserManager.getInstance(); if (um.isMandatoryUserProperty(HomePageConfig.class.getCanonicalName(), userPropertyHandler)) { publishCheckbox.select(userPropertyHandler.i18nFormElementLabelKey(), true); publishCheckbox.setEnabled(false); } } else { uifactory.addSpacerElement("spacer_" + userPropertyHandler.getName(), formLayout, true); } // add input field to container FormItem formItem = userPropertyHandler.addFormItem(getLocale(), this.identity.getUser(), this.usageIdentifier, this.isAdministrativeUser, formLayout); String propertyName = userPropertyHandler.getName(); this.formItems.put(propertyName, formItem); if (formItem instanceof TextElement) { // it's a text field, so get the value of this property into the text field TextElement textElement = (TextElement)formItem; textElement.setValue(this.identity.getUser().getProperty(propertyName, getLocale())); } else if (formItem instanceof MultipleSelectionElement) { // it's a checkbox, so set the box to checked if the corresponding property is set to "true" MultipleSelectionElement checkbox = (MultipleSelectionElement)formItem; String value = this.identity.getUser().getProperty(propertyName, getLocale()); if (value != null) { checkbox.select(propertyName, value.equals("true")); } else { // assume "false" if the property is not present checkbox.select(propertyName, false); } } // special case for email field if (userPropertyHandler.getName().equals("email")) { RegistrationManager rm = RegistrationManager.getInstance(); String key = this.identity.getUser().getProperty("emchangeKey", null); TemporaryKeyImpl tempKey = rm.loadTemporaryKeyByRegistrationKey(key); if (tempKey != null) { XStream xml = new XStream(); HashMap<String, String> mails = (HashMap<String, String>) xml.fromXML(tempKey.getEmailAddress()); formItem.setExampleKey("email.change.form.info", new String[] {mails.get("changedEMail")}); } } } // add the "about me" text field. this.textAboutMe = uifactory.addRichTextElementForStringData("form.text", "form.text", this.conf.getTextAboutMe(), 10, -1, false, false, null, null, formLayout, ureq.getUserSession(), getWindowControl()); this.textAboutMe.setMaxLength(10000); this.formItems.put("form.text", this.textAboutMe); // Create submit and cancel buttons FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator()); formLayout.add(buttonLayout); uifactory.addFormSubmitButton("save", buttonLayout); uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl()); formItems.put("buttonLayout", buttonLayout); Set<String> userPropertyNames = formItems.keySet(); ((VelocityContainer)this.flc.getComponent()).contextPut("userPropertyNames", userPropertyNames); } /** * Stores the data from the form into a) the user's home page configuration * and b) the user's properties. * * @param config The user's home page configuration (i.e. flags for publicly * visible fields). * @param identity The user's identity */ public void updateFromFormData(final HomePageConfig config, final Identity identity) { User user = identity.getUser(); // For each user property... for (UserPropertyHandler userPropertyHandler : this.userPropertyHandlers) { // ...get the value from the form field and store it into the user // property... FormItem formItem = this.formItems.get(userPropertyHandler.getName()); userPropertyHandler.updateUserFromFormItem(user, formItem); // ...and store the "publish" flag for each property. MultipleSelectionElement checkbox = this.publishCheckboxes.get("checkbox_" + userPropertyHandler.getName()); if (checkbox != null) { // null when not enabled for the org.olat.user.HomePageConfig usage // identifier key if (checkbox.getSelectedKeys().size() == 0) { config.setEnabled(userPropertyHandler.getName(), false); } else { config.setEnabled(userPropertyHandler.getName(), true); } } } // Store the "about me" text. conf.setTextAboutMe(textAboutMe.getValue()); } /** * Take form data and set it in the user fields for the current subject * * @param id The identity to be updated (transient, does not do any db calls) * @return the updated identity object */ public Identity updateIdentityFromFormData(Identity id) { User user = id.getUser(); // update each user field for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) { FormItem formItem = this.formItems.get(userPropertyHandler.getName()); userPropertyHandler.updateUserFromFormItem(user, formItem); } return id; } /* * (non-Javadoc) * * @seeorg.olat.core.gui.components.form.flexible.impl.FormBasicController# * validateFormLogic(org.olat.core.gui.UserRequest) */ @Override protected boolean validateFormLogic(UserRequest ureq) { boolean formOK = true; for (UserPropertyHandler userPropertyHandler : this.userPropertyHandlers) { FormItem formItem = this.formItems.get(userPropertyHandler.getName()); if (!userPropertyHandler.isValid(formItem, this.formContext)) { formOK = false; } else { formItem.clearError(); } } try { String aboutMe = textAboutMe.getValue(); if(aboutMe.length() > 10000) { textAboutMe.setErrorKey("input.toolong", new String[] {"10000"}); formOK = false; } else { textAboutMe.clearError(); } } catch (Exception e) { textAboutMe.setErrorKey("input.toolong", new String[] {"10000"}); formOK = false; } return formOK && super.validateFormLogic(ureq); } /** * Sets the dirty mark for this form. * * @param isDirtyMarking <code>true</code> sets this form dirty. */ public void setDirtyMarking(boolean isDirtyMarking) { mainForm.setDirtyMarking(isDirtyMarking); } }