diff --git a/ccm-cms/src/main/java/org/librecms/contenttypes/Event.java b/ccm-cms/src/main/java/org/librecms/contenttypes/Event.java index e46bbb35c..29cd4e43e 100644 --- a/ccm-cms/src/main/java/org/librecms/contenttypes/Event.java +++ b/ccm-cms/src/main/java/org/librecms/contenttypes/Event.java @@ -45,7 +45,7 @@ import org.librecms.contentsection.ContentItem; import javax.validation.constraints.NotNull; -import static org.librecms.CmsConstants.*; +import static org.librecms.CmsConstants.DB_SCHEMA; /** * @author Alexander Konermann diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/article/MvcArticleCreateStep.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/article/MvcArticleCreateStep.java index 5ea200093..7da8e5e72 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/article/MvcArticleCreateStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/article/MvcArticleCreateStep.java @@ -35,7 +35,6 @@ import javax.enterprise.context.RequestScoped; import javax.inject.Named; import javax.inject.Inject; -import javax.mvc.Models; import javax.transaction.Transactional; /** @@ -56,8 +55,7 @@ public class MvcArticleCreateStep private static final String FORM_PARAM_INITIAL_LOCALE = "locale"; - private static final String FORM_PARAM_SELECTED_WORKFLOW - = "workflow"; + private static final String FORM_PARAM_SELECTED_WORKFLOW = "workflow"; /** * Provides functions for working with content items. diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/EventMessageBundle.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/EventMessageBundle.java new file mode 100644 index 000000000..839206a43 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/EventMessageBundle.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.contenttypes.event; + +import org.libreccm.ui.AbstractMessagesBean; +import org.librecms.contenttypes.Event; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +/** + * Message bundle for the authorings steps for editing an {@link Event}. + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("CmsEventMessageBundle") +public class EventMessageBundle extends AbstractMessagesBean { + + @Override + public String getMessageBundle() { + return EventStepsConstants.BUNDLE; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/EventStepsConstants.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/EventStepsConstants.java new file mode 100644 index 000000000..b9e3d049f --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/EventStepsConstants.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.contenttypes.event; + +/** + * Constants for the authoring steps for editing an {@link Event}. + * + * @author Jens Pelzetter + */ +public final class EventStepsConstants { + + private EventStepsConstants() { + // Nothing + } + + public static final String BUNDLE + = "org.librecms.ui.contenttypes.EventBundle"; + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventCreateStep.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventCreateStep.java new file mode 100644 index 000000000..83a137b70 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventCreateStep.java @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2022 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.contenttypes.event; + +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; +import org.libreccm.workflow.Workflow; +import org.librecms.contentsection.ContentItemManager; +import org.librecms.contentsection.ContentItemRepository; +import org.librecms.contenttypes.Event; +import org.librecms.ui.contentsections.documents.AbstractMvcDocumentCreateStep; + +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.inject.Named; +import javax.transaction.Transactional; + +/** + * Describes the create step for an {@link Event} + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("CmsEventCreateStep") +public class MvcEventCreateStep + extends AbstractMvcDocumentCreateStep { + + private static final String FORM_PARAM_NAME = "name"; + + private static final String FORM_PARAM_TITLE = "title"; + + private static final String FORM_PARAM_SUMMARY = "summary"; + + private static final String FORM_PARAM_INITIAL_LOCALE = "locale"; + + private static final String FORM_PARAM_SELECTED_WORKFLOW = "workflow"; + + /** + * Provides functions for working with content items. + */ + @Inject + private ContentItemManager itemManager; + + /** + * Used to save the event. + */ + @Inject + private ContentItemRepository itemRepo; + + /** + * Provides functions for working with {@link LocalizedString}s. + */ + @Inject + private GlobalizationHelper globalizationHelper; + + /** + * Name of the event. + */ + private String name; + + /** + * Title of the event. + */ + private String title; + + /** + * Summary of the event. + */ + private String summary; + + /** + * The initial locale of the event. + */ + private String initialLocale; + + /** + * The workflow to use for the new event. + */ + private String selectedWorkflow; + + @Override + public String getDocumentType() { + return Event.class.getName(); + } + + @Override + public String getDescription() { + return globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("createstep.description"); + } + + @Override + public String getBundle() { + return EventStepsConstants.BUNDLE; + } + + public String getName() { + return name; + } + + public String getTitle() { + return title; + } + + public String getSummary() { + return summary; + } + + public String getInitialLocale() { + return initialLocale; + } + + @Transactional(Transactional.TxType.REQUIRED) + public String getSelectedWorkflow() { + if (selectedWorkflow == null || selectedWorkflow.isEmpty()) { + return getContentSection() + .getContentTypes() + .stream() + .filter( + type -> type.getContentItemClass().equals( + Event.class.getName() + ) + ) + .findAny() + .map(type -> type.getDefaultWorkflow()) + .map( + workflow -> globalizationHelper.getValueFromLocalizedString( + workflow.getName() + ) + ) + .orElse(""); + } else { + return selectedWorkflow; + } + } + + @Override + public String showCreateStep() { + return "org/librecms/ui/contenttypes/event/create-event.xhtml"; + } + + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String createItem(final Map formParams) { + if (!formParams.containsKey(FORM_PARAM_NAME) + || formParams.get(FORM_PARAM_NAME) == null + || formParams.get(FORM_PARAM_NAME).length == 0) { + addMessage( + "danger", + globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("createstep.name.error.missing") + ); + return showCreateStep(); + } + + name = formParams.get(FORM_PARAM_NAME)[0]; + if (!name.matches("^([a-zA-Z0-9_-]*)$")) { + addMessage( + "danger", + globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("createstep.name.error.invalid") + ); + return showCreateStep(); + } + + if (!formParams.containsKey(FORM_PARAM_TITLE) + || formParams.get(FORM_PARAM_TITLE) == null + || formParams.get(FORM_PARAM_TITLE).length == 0) { + addMessage( + "danger", + globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("createstep.title.error.missing") + ); + return showCreateStep(); + } + title = formParams.get(FORM_PARAM_TITLE)[0]; + + if (!formParams.containsKey(FORM_PARAM_SUMMARY) + || formParams.get(FORM_PARAM_SUMMARY) == null + || formParams.get(FORM_PARAM_SUMMARY).length == 0) { + addMessage( + "danger", + globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("createstep.summary.error.missing") + ); + return showCreateStep(); + } + summary = formParams.get(FORM_PARAM_SUMMARY)[0]; + + if (!formParams.containsKey(FORM_PARAM_INITIAL_LOCALE) + || formParams.get(FORM_PARAM_INITIAL_LOCALE) == null + || formParams.get(FORM_PARAM_INITIAL_LOCALE).length == 0) { + addMessage( + "danger", + globalizationHelper.getLocalizedTextsUtil( + getBundle() + ).getText("createstep.initial_locale.error.missing") + ); + return showCreateStep(); + } + final Locale locale = new Locale( + formParams.get(FORM_PARAM_INITIAL_LOCALE)[0] + ); + + if (!formParams.containsKey(FORM_PARAM_SELECTED_WORKFLOW) + || formParams.get(FORM_PARAM_SELECTED_WORKFLOW) == null + || formParams.get(FORM_PARAM_SELECTED_WORKFLOW).length == 0) { + addMessage( + "danger", + globalizationHelper.getLocalizedTextsUtil( + getBundle() + ).getText("createstep.workflow.none_selected") + ); + return showCreateStep(); + } + selectedWorkflow = formParams.get(FORM_PARAM_SELECTED_WORKFLOW)[0]; + + final Optional workflowResult = getContentSection() + .getWorkflowTemplates() + .stream() + .filter(template -> template.getUuid().equals(selectedWorkflow)) + .findAny(); + + if (!workflowResult.isPresent()) { + addMessage( + "danger", + globalizationHelper.getLocalizedTextsUtil( + getBundle() + ).getText("createstep.workflow.error.not_available") + ); + return showCreateStep(); + } + + if (!getMessages().isEmpty()) { + return showCreateStep(); + } + + final Event event = itemManager.createContentItem( + name, + getContentSection(), + getFolder(), + workflowResult.get(), + Event.class, + locale + ); + + event.getTitle().putValue(locale, title); + event.getDescription().putValue(locale, summary); + itemRepo.save(event); + + return String.format( + "redirect:/%s/documents/%s/%s/@event-basicproperties", + getContentSectionLabel(), + getFolderPath(), + name + ); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventPropertiesStep.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventPropertiesStep.java new file mode 100644 index 000000000..2cf4d5bc4 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventPropertiesStep.java @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2022 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.contenttypes.event; + +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; +import org.librecms.contentsection.ContentItemManager; +import org.librecms.contentsection.ContentItemRepository; +import org.librecms.contentsection.FolderManager; +import org.librecms.contenttypes.Event; +import org.librecms.ui.contentsections.ContentSectionNotFoundException; +import org.librecms.ui.contentsections.ItemPermissionChecker; +import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep; +import org.librecms.ui.contentsections.documents.DocumentNotFoundException; +import org.librecms.ui.contentsections.documents.DocumentUi; +import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef; +import org.librecms.ui.contentsections.documents.MvcAuthoringSteps; + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * Authoring step for editing the basic properties of an {@link Event}. + * + * @author Jens Pelzetter + */ +@RequestScoped +@Path(MvcAuthoringSteps.PATH_PREFIX + "event-basicproperties") +@Controller +@MvcAuthoringStepDef( + bundle = EventStepsConstants.BUNDLE, + descriptionKey = "authoringsteps.basicproperties.description", + labelKey = "authoringsteps.basicproperties.label", + supportedDocumentType = Event.class +) +public class MvcEventPropertiesStep extends AbstractMvcAuthoringStep { + + @Inject + private EventMessageBundle eventMessageBundle; + + /** + * Used for retrieving and saving the events. + */ + @Inject + private ContentItemRepository itemRepo; + + /** + * Provides functions for working with content items. + */ + @Inject + private ContentItemManager itemManager; + + @Inject + private DocumentUi documentUi; + + /** + * Provides functions for working with folders. + */ + @Inject + private FolderManager folderManager; + + /** + * Provides functions for working with {@link LocalizedString}s. + */ + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private ItemPermissionChecker itemPermissionChecker; + + @Inject + private MvcEventPropertiesStepModel eventPropertiesStepModel; + + @Inject + private Models models; + + @Override + public Class getStepClass() { + return MvcEventPropertiesStep.class; + } + + @Override + @Transactional(Transactional.TxType.REQUIRED) + protected void init() throws ContentSectionNotFoundException, + DocumentNotFoundException { + super.init(); + + eventPropertiesStepModel.setName(getDocument().getDisplayName()); + + final Set titleLocales = getDocument() + .getTitle() + .getAvailableLocales(); + + eventPropertiesStepModel.setTitleValues( + getDocument() + .getTitle() + .getValues() + .entrySet() + .stream() + .collect( + Collectors.toMap( + entry -> entry.getKey().toString(), + entry -> entry.getValue() + ) + ) + ); + + eventPropertiesStepModel.setUnusedTitleLocales( + globalizationHelper + .getAvailableLocales() + .stream() + .filter(locale -> !titleLocales.contains(locale)) + .map(Locale::toString) + .collect(Collectors.toList()) + ); + + eventPropertiesStepModel.setDescriptionValues( + getDocument() + .getDescription() + .getValues() + .entrySet() + .stream() + .collect( + Collectors.toMap( + entry -> entry.getKey().toString(), + entry -> entry.getValue() + ) + ) + ); + + final Set descriptionLocales = getDocument() + .getDescription() + .getAvailableLocales(); + + eventPropertiesStepModel.setUnusedDescriptionLocales( + globalizationHelper + .getAvailableLocales() + .stream() + .filter(locale -> !descriptionLocales.contains(locale)) + .map(Locale::toString) + .collect(Collectors.toList()) + ); + + final Event event = (Event) getDocument(); + final DateTimeFormatter isoDateTimeFormatter + = DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.systemDefault()); + + eventPropertiesStepModel.setStartDate( + Optional + .ofNullable(event.getStartDate()) + .map(startDate -> startDate.toInstant()) + .map(startDate -> isoDateTimeFormatter.format(startDate)) + .orElse("") + ); + + eventPropertiesStepModel.setEndDate( + Optional + .ofNullable(event.getEndDate()) + .map(endDate -> endDate.toInstant()) + .map(endDate -> isoDateTimeFormatter.format(endDate)) + .orElse("") + ); + + eventPropertiesStepModel.setMapLink(event.getMapLink()); + } + + @GET + @Path("/") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String showStep( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + return "org/librecms/ui/contenttypes/event/event-basic-properties.xhtml"; + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + eventMessageBundle.getMessage("event.edit.denied") + ); + } + } + + /** + * Updates the name of the current event. + * + * @param sectionIdentifier + * @param documentPath + * @param name + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/name") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String updateName( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("name") @DefaultValue("") final String name + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + if (name.isEmpty() || name.matches("\\s*")) { + models.put("nameMissing", true); + + return showStep(sectionIdentifier, documentPath); + } + + getDocument().setDisplayName(name); + itemRepo.save(getDocument()); + + updateDocumentPath(); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + @POST + @Path("/eventproperties") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String updateEventProperties( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("startDateTime") + final String startDateTime, + @FormParam("endDateTime") + final String endDateTime, + @FormParam("timeZone") + final String timeZone, + @FormParam("mapLink") + final String mapLink + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Event event = (Event) getDocument(); + final DateTimeFormatter isoDateTimeFormatter + = DateTimeFormatter.ISO_DATE_TIME + .withZone(ZoneId.of(timeZone)); + event.setStartDate( + Date.from( + ZonedDateTime.parse( + startDateTime, + isoDateTimeFormatter + ).toInstant() + ) + ); + + event.setEndDate( + Date.from( + ZonedDateTime.parse( + endDateTime, + isoDateTimeFormatter + ).toInstant() + ) + ); + event.setMapLink(mapLink); + + itemRepo.save(event); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + /** + * Updates a localized title of the event. + * + * @param sectionIdentifier + * @param documentPath + * @param localeParam The locale to update. + * @param value The updated title value. + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/title/@add") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String addTitle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Locale locale = new Locale(localeParam); + getDocument().getTitle().putValue(locale, value); + itemRepo.save(getDocument()); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + /** + * Updates a localized title of the event. + * + * @param sectionIdentifier + * @param documentPath + * @param localeParam The locale to update. + * @param value The updated title value. + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/title/@edit/{locale}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String editTitle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Locale locale = new Locale(localeParam); + getDocument().getTitle().putValue(locale, value); + itemRepo.save(getDocument()); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + /** + * Removes a localized title of the event. + * + * @param sectionIdentifier + * @param documentPath + * @param localeParam The locale to remove. + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/title/@remove/{locale}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removeTitle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Locale locale = new Locale(localeParam); + getDocument().getTitle().removeValue(locale); + itemRepo.save(getDocument()); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + /** + * Adds a localized description to the event. + * + * @param sectionIdentifier + * @param documentPath + * @param localeParam The locale of the description. + * @param value The description value. + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/description/@add") + @Transactional(Transactional.TxType.REQUIRED) + public String addDescription( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Locale locale = new Locale(localeParam); + getDocument().getDescription().putValue(locale, value); + itemRepo.save(getDocument()); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + /** + * Updates a localized description of the event. + * + * @param sectionIdentifier + * @param documentPath + * @param localeParam The locale to update. + * @param value The updated description value. + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/description/@edit/{locale}") + @Transactional(Transactional.TxType.REQUIRED) + public String editDescription( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Locale locale = new Locale(localeParam); + getDocument().getDescription().putValue(locale, value); + itemRepo.save(getDocument()); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + /** + * Removes a localized description of the event. + * + * @param sectionIdentifier + * @param documentPath + * @param localeParam The locale to remove. + * + * @return A redirect to this authoring step. + */ + @POST + @Path("/description/@remove/{locale}") + @Transactional(Transactional.TxType.REQUIRED) + public String removeDescription( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Locale locale = new Locale(localeParam); + getDocument().getDescription().removeValue(locale); + itemRepo.save(getDocument()); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventPropertiesStepModel.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventPropertiesStepModel.java new file mode 100644 index 000000000..d57a366bb --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/event/MvcEventPropertiesStepModel.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.contenttypes.event; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("CmsEventPropertiesStep") +public class MvcEventPropertiesStepModel { + + private String name; + + private Map titleValues; + + private List unusedTitleLocales; + + private Map descriptionValues; + + private List unusedDescriptionLocales; + + private String startDate; + + private String endDate; + + private String mapLink; + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public Map getTitleValues() { + return Collections.unmodifiableMap(titleValues); + } + + public void setTitleValues(final Map titleValues) { + this.titleValues = new HashMap<>(titleValues); + } + + public List getUnusedTitleLocales() { + return Collections.unmodifiableList(unusedTitleLocales); + } + + public void setUnusedTitleLocales(List unusedTitleLocales) { + this.unusedTitleLocales = new ArrayList<>(unusedTitleLocales); + } + + public Map getDescriptionValues() { + return Collections.unmodifiableMap(descriptionValues); + } + + public void setDescriptionValues( + final Map descriptionValues + ) { + this.descriptionValues = new HashMap<>(descriptionValues); + } + + public List getUnusedDescriptionLocales() { + return Collections.unmodifiableList(unusedDescriptionLocales); + } + + public void setUnusedDescriptionLocales( + final List unusedDescriptionLocales + ) { + this.unusedDescriptionLocales = new ArrayList<>( + unusedDescriptionLocales + ); + } + + public String getStartDate() { + return startDate; + } + + public void setStartDate(final String startDate) { + this.startDate = startDate; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(final String endDate) { + this.endDate = endDate; + } + + public String getMapLink() { + return mapLink; + } + + public void setMapLink(final String mapLink) { + this.mapLink = mapLink; + } + +}