diff --git a/ccm-cms/src/main/java/org/librecms/ui/PageDetailsModel.java b/ccm-cms/src/main/java/org/librecms/ui/PageDetailsModel.java index a5cfe66ae..c5cf7117a 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/PageDetailsModel.java +++ b/ccm-cms/src/main/java/org/librecms/ui/PageDetailsModel.java @@ -39,6 +39,8 @@ public class PageDetailsModel { private String category; + private String categoryPath; + private List pageProperties; public String getSite() { @@ -65,11 +67,20 @@ public class PageDetailsModel { this.category = category; } + public String getCategoryPath() { + return categoryPath; + } + + public void setCategoryPath(String categoryPath) { + this.categoryPath = categoryPath; + } + public List getPageProperties() { return Collections.unmodifiableList(pageProperties); } - protected void setPageProperties(final List pageProperties) { + protected void setPageProperties( + final List pageProperties) { this.pageProperties = new ArrayList<>(pageProperties); } diff --git a/ccm-cms/src/main/java/org/librecms/ui/PageTreeNodeModel.java b/ccm-cms/src/main/java/org/librecms/ui/PageTreeNodeModel.java index cd9f49d5d..6c0daf3fd 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/PageTreeNodeModel.java +++ b/ccm-cms/src/main/java/org/librecms/ui/PageTreeNodeModel.java @@ -40,11 +40,11 @@ public class PageTreeNodeModel { private boolean pageAssigned; - private Map properties; + private List properties; public PageTreeNodeModel() { children = new ArrayList<>(); - properties = new HashMap<>(); + properties = new ArrayList<>(); } public String getUuid() { @@ -87,12 +87,12 @@ public class PageTreeNodeModel { this.pageAssigned = pageAssigned; } - public Map getProperties() { - return Collections.unmodifiableMap(properties); + public List getProperties() { + return Collections.unmodifiableList(properties); } - public void setProperties(final Map properties) { - this.properties = new HashMap<>(properties); + public void setProperties(final List properties) { + this.properties = new ArrayList<>(properties); } } diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesController.java b/ccm-cms/src/main/java/org/librecms/ui/PagesController.java index 05c594acf..2a07ea8c8 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/PagesController.java +++ b/ccm-cms/src/main/java/org/librecms/ui/PagesController.java @@ -25,6 +25,7 @@ import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryRepository; import org.libreccm.categorization.Domain; import org.libreccm.categorization.DomainRepository; +import org.libreccm.categorization.ObjectNotAssignedToCategoryException; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; @@ -37,6 +38,7 @@ import org.librecms.pages.Pages; import org.librecms.pages.PagesManager; import org.librecms.pages.PagesRepository; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -67,7 +69,7 @@ public class PagesController { @Inject private CategoryManager categoryManager; - + @Inject private CategoryRepository categoryRepo; @@ -138,28 +140,48 @@ public class PagesController { if (siteResult.isEmpty()) { models.put("siteNotFound", true); models.put("site", siteParam); + return PAGES_LIST_TEMPLATE; } + final Site site = siteResult.get(); + final Optional domainResult = domainRepo.findByDomainKey( categoryDomainParam ); if (domainResult.isEmpty()) { models.put("domainNotFound", true); + models.put("site", siteParam); + models.put("siteUuid", site.getUuid()); + models.put("primaryUrl", primaryUrlParam); models.put("domainKey", categoryDomainParam); return PAGES_LIST_TEMPLATE; } if (primaryUrlParam == null || primaryUrlParam.isBlank()) { models.put("primaryUrlNullOrEmpty", true); + models.put("site", siteParam); + models.put("siteUuid", site.getUuid()); + models.put("primaryUrl", primaryUrlParam); + models.put("domainKey", categoryDomainParam); + return PAGES_LIST_TEMPLATE; + } + if (!primaryUrlParam.matches("^([a-z0-9-_]*)$")) { + models.put("primaryUrlInvalid", true); + models.put("site", siteParam); + models.put("siteUuid", site.getUuid()); + models.put("primaryUrl", primaryUrlParam); + models.put("domainKey", categoryDomainParam); return PAGES_LIST_TEMPLATE; } - final Site site = siteResult.get(); final Domain domain = domainResult.get(); final String primaryUrl = primaryUrlParam; if (pagesRepo.findPagesForSite(primaryUrl).isPresent()) { models.put("pagesInstanceAlreadyExisting", true); + models.put("site", siteParam); + models.put("primaryUrl", primaryUrlParam); + models.put("domainKey", categoryDomainParam); return PAGES_LIST_TEMPLATE; } @@ -183,16 +205,7 @@ public class PagesController { final Pages pages = pagesResult.get(); - pagesDetailsModel.setPagesId(pages.getObjectId()); - pagesDetailsModel.setCategoryDomain( - pages.getCategoryDomain().getDomainKey() - ); - pagesDetailsModel.setPrimaryUrl(pages.getPrimaryUrl()); - pagesDetailsModel.setSite(pages.getSite().getDomainOfSite()); - - pagesDetailsModel.setPageTreeRoot( - buildPageTreeNodeModel(pages.getCategoryDomain().getRoot()) - ); + initPagesDetailsModel(pages); return "org/librecms/ui/cms/pages-details.xhtml"; } @@ -211,12 +224,19 @@ public class PagesController { return showPagesNotFound(pagesInstance); } + final Pages pages = pagesResult.get(); + if (primaryUrlParam == null || primaryUrlParam.isBlank()) { models.put("primaryUrlNullOrEmpty", true); return PAGES_LIST_TEMPLATE; } - final Pages pages = pagesResult.get(); + if (!primaryUrlParam.matches("^([a-z0-9-_]*)$")) { + models.put("primaryUrlInvalid", true); + models.put("primaryUrl", primaryUrlParam); + return PAGES_LIST_TEMPLATE; + } + pages.setPrimaryUrl(primaryUrlParam); pagesRepo.save(pages); @@ -245,7 +265,7 @@ public class PagesController { } @POST - @Path("/{pagesInstance}/{category:[\\w\\-/]+}/@add") + @Path("/{pagesInstance}/{category:[\\w\\-@/]+}/@add") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) @@ -259,10 +279,18 @@ public class PagesController { } final Pages pages = pagesResult.get(); - final Optional categoryResult = categoryRepo.findByPath( - pages.getCategoryDomain(), - categoryParam - ); + final Optional categoryResult; + if ("@root".equals(categoryParam)) { + categoryResult = categoryRepo.findByPath( + pages.getCategoryDomain(), + "/" + ); + } else { + categoryResult = categoryRepo.findByPath( + pages.getCategoryDomain(), + categoryParam + ); + } if (categoryResult.isEmpty()) { models.put("categoryNotFound", true); @@ -285,7 +313,7 @@ public class PagesController { } @GET - @Path("/{pagesInstance}/{category:[\\w\\-/]+}/@details") + @Path("/{pagesInstance}/{category:[\\w\\-@/]+}/@details") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) @@ -298,11 +326,20 @@ public class PagesController { return showPagesNotFound(pagesInstance); } final Pages pages = pagesResult.get(); + initPagesDetailsModel(pages); - final Optional categoryResult = categoryRepo.findByPath( - pages.getCategoryDomain(), - categoryParam - ); + final Optional categoryResult; + if ("@root".equals(categoryParam)) { + categoryResult = categoryRepo.findByPath( + pages.getCategoryDomain(), + "/" + ); + } else { + categoryResult = categoryRepo.findByPath( + pages.getCategoryDomain(), + categoryParam + ); + } if (categoryResult.isEmpty()) { models.put("categoryNotFound", true); @@ -320,6 +357,9 @@ public class PagesController { pageDetailsModel.setCategoryDomain( pages.getCategoryDomain().getDomainKey() ); + pageDetailsModel.setCategoryPath( + categoryManager.getCategoryPath(category) + ); pageDetailsModel.setPageProperties( page .getProperties() @@ -335,7 +375,7 @@ public class PagesController { } @POST - @Path("/{pagesInstance}/{category:[\\w\\-/]+}/@remove") + @Path("/{pagesInstance}/{category:[\\w\\-@/]+}/@remove") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) @@ -349,10 +389,18 @@ public class PagesController { } final Pages pages = pagesResult.get(); - final Optional categoryResult = categoryRepo.findByPath( - pages.getCategoryDomain(), - categoryParam - ); + final Optional categoryResult; + if ("@root".equals(categoryParam)) { + categoryResult = categoryRepo.findByPath( + pages.getCategoryDomain(), + "/" + ); + } else { + categoryResult = categoryRepo.findByPath( + pages.getCategoryDomain(), + categoryParam + ); + } if (categoryResult.isEmpty()) { models.put("categoryNotFound", true); @@ -366,6 +414,11 @@ public class PagesController { final Category category = categoryResult.get(); final Page page = pageManager.findPageForCategory(category); + try { + categoryManager.removeObjectFromCategory(page, category); + } catch (ObjectNotAssignedToCategoryException ex) { + throw new RuntimeException(ex); + } pageRepo.delete(page); return String.format("redirect:/pages/%s", pagesInstance); @@ -409,6 +462,11 @@ public class PagesController { return showPageDetails(pagesInstance, categoryParam); } + if (!propertyKey.matches("^([a-z0-9-_]*)$")) { + models.put("propertyKeyInvalid", true); + return showPageDetails(pagesInstance, categoryParam); + } + if (propertyValue == null || propertyValue.isBlank()) { models.put("propertyValueEmpty", true); return showPageDetails(pagesInstance, categoryParam); @@ -426,7 +484,7 @@ public class PagesController { } @POST - @Path("/{pagesInstance}/{category:[\\w\\-/]+}/{propertyKey}/@edit") + @Path("/{pagesInstance}/{category:[\\w\\-/]+}/{propertyKey}/@edit-property") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) @@ -445,7 +503,8 @@ public class PagesController { } @POST - @Path("/{pagesInstance}/{category:[\\w\\-/]+}/{propertyKey}/@remove") + @Path( + "/{pagesInstance}/{category:[\\w\\-/]+}/{propertyKey}/@remove-property") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) @@ -512,6 +571,19 @@ public class PagesController { } } + private void initPagesDetailsModel(final Pages pages) { + pagesDetailsModel.setPagesId(pages.getObjectId()); + pagesDetailsModel.setCategoryDomain( + pages.getCategoryDomain().getDomainKey() + ); + pagesDetailsModel.setPrimaryUrl(pages.getPrimaryUrl()); + pagesDetailsModel.setSite(pages.getSite().getDomainOfSite()); + + pagesDetailsModel.setPageTreeRoot( + buildPageTreeNodeModel(pages.getCategoryDomain().getRoot()) + ); + } + private String showPagesNotFound(final String pagesInstance) { models.put("pagesInstanceNotFound", true); models.put("pagesInstance", pagesInstance); @@ -530,10 +602,15 @@ public class PagesController { node.setCategoryPath(categoryManager.getCategoryPath(category)); node.setCategoryName(category.getName()); node.setPageAssigned(pageResult.isPresent()); + node.setProperties( pageResult .map(Page::getProperties) - .orElse(new HashMap<>()) + .orElse(new HashMap()) + .entrySet() + .stream() + .map(this::buildPagePropertyModel) + .collect(Collectors.toList()) ); node.setChildren( @@ -553,8 +630,8 @@ public class PagesController { final PagePropertyModel model = new PagePropertyModel(); model.setName(property.getKey()); model.setValue(property.getValue()); - + return model; } - + } diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/page-details.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/page-details.xhtml index 24257167c..08d9b3841 100644 --- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/page-details.xhtml +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/page-details.xhtml @@ -15,12 +15,11 @@ @@ -28,32 +27,191 @@

#{CmsAdminMessages.getMessage('pages.page.details.heading', [CmsPageDetailsModel.category, CmsPagesDetailsModel.site])}

- +

#{CmsAdminMessages['pages.page.details.properties.heading']}

- - + + + + + + + + + + + +
+ +
+ +
- + - - + + + diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/pages-details.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/pages-details.xhtml index ba81b1afd..9ed55aec3 100644 --- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/pages-details.xhtml +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/cms/pages-details.xhtml @@ -22,12 +22,27 @@

#{CmsAdminMessages['pages.details.heading']}

- + + + + + + + +
+ +
#{CmsAdminMessages['pages.page.details.properties.name.header']} #{CmsAdminMessages['pages.page.details.properties.value.header']}#{CmsAdminMessages['pages.page.details.properties.actions.header']}#{CmsAdminMessages['pages.page.details.properties.actions.header']}
#{property.name}#{property.value}#{property.name}#{property.value} - + + +
+ + + + + + + + + + + + + + +
#{CmsAdminMessages['pages.page.details.dialog.properties.key']}#{CmsAdminMessages['pages.page.details.dialog.properties.value']}
#{property.name}#{property.value}
+ + +
+ + + + + href="#{basePath}#{node.categoryPath == '/' ? '/@root' : node.categoryPath}/@details"> #{CmsAdminMessages['pages.page.edit']} +
- + --> +
-