Bugfixes for managing the index item of a category.

pull/20/head
Jens Pelzetter 2022-01-25 20:16:01 +01:00
parent 5b1150b8be
commit 2cd477eae2
3 changed files with 346 additions and 62 deletions

View File

@ -18,8 +18,6 @@
*/
package org.librecms.ui.contentsections;
import com.arsdigita.cms.ui.authoring.multipartarticle.SectionPreviewPanel;
import org.libreccm.api.Identifier;
import org.libreccm.api.IdentifierParser;
import org.libreccm.categorization.Categorization;
@ -33,8 +31,12 @@ import org.libreccm.core.CcmObject;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.PermissionChecker;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemVersion;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentSectionRepository;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.privileges.AdminPrivileges;
import java.time.ZoneId;
@ -87,6 +89,12 @@ public class CategoriesController {
@Inject
private CategorySystemModel categorySystemModel;
/**
* The {@link ContentItemManager}.
*/
@Inject
private ContentItemManager itemManager;
/**
* The {@link ContentSectionModel} which stores the data of the current
* content section for the view.
@ -252,7 +260,7 @@ public class CategoriesController {
"sectionIdentifier", sectionIdentifier
);
}
final Optional<DomainOwnership> domainResult = section
.getDomains()
.stream()
@ -824,6 +832,41 @@ public class CategoriesController {
}
}
/**
* Sets the index element of the root category.
*
* @param sectionIdentifier The identifier of the current
* {@link ContentSection}.
* @param context The mapping context of the assigned category
* system.
* @param indexElementUuid The UUID of the new index element.
*
* @return A redirect to the category page or the template for generating an
* error view.
*/
@POST
@Path(
"/{context}/categories/@index-element/{indexElementUuid}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String setIndexElement(
@PathParam("sectionIdentifier") final String sectionIdentifier,
@PathParam("context") final String context,
@PathParam("indexElementUuid") final String indexElementUuid
) {
final RetrieveResult<Category> result = retrieveCategory(
sectionIdentifier, context, "/"
);
return setIndexObject(
result,
sectionIdentifier,
context,
context,
indexElementUuid
);
}
/**
* Sets the index element of a category.
*
@ -837,7 +880,7 @@ public class CategoriesController {
* @return A redirect to the category page or the template for generating an
* error view.
*/
@GET
@POST
@Path(
"/{context}/categories/{categoryPath:(.+)?}/@index-element/{indexElementUuid}")
@AuthorizationRequired
@ -851,41 +894,95 @@ public class CategoriesController {
final RetrieveResult<Category> result = retrieveCategory(
sectionIdentifier, context, categoryPath
);
return setIndexObject(
result,
sectionIdentifier,
context,
categoryPath,
indexElementUuid
);
// if (result.isSuccessful()) {
// final Category category = result.getResult();
// final Optional<Categorization> categorizationResult = category
// .getObjects()
// .stream()
// .filter(
// categorization -> Objects.equals(
// categorization.getUuid(), indexElementUuid
// )
// ).findAny();
// if (categorizationResult.isPresent()) {
// final CcmObject object = categorizationResult
// .get()
// .getCategorizedObject();
// try {
// categoryManager.setIndexObject(category, object);
// if (object instanceof ContentItem) {
// final ContentItem item = (ContentItem) object;
// final ContentItem live = itemManager.getDraftVersion(
// item,
// ContentItem.class
// );
// categoryManager.setIndexObject(category, live);
// }
// } catch (ObjectNotAssignedToCategoryException ex) {
// models.put("sectionIdentifier", sectionIdentifier);
// models.put("context", context);
// models.put("categoryPath", categoryPath);
// models.put("categorizationUuid", indexElementUuid);
// return "org/librecms/ui/contentsection/categorysystems/categorization-not-found.xhtml";
// }
// } else {
// models.put("sectionIdentifier", sectionIdentifier);
// models.put("context", context);
// models.put("categoryPath", categoryPath);
// models.put("categorizationUuid", indexElementUuid);
// return "org/librecms/ui/contentsection/categorysystems/categorization-not-found.xhtml";
// }
// return String.format(
// "redirect:/%s/categorysystems/%s/categories/%s#objects-sections",
// sectionIdentifier,
// context,
// categoryPath
// );
// } else {
// return result.getFailedResponseTemplate();
// }
}
/**
* Resets the index object of the root category. The object is still
* associated with the category after this, but no longer the index object
* of the category.
*
* @param sectionIdentifier The identifier of the current
* {@link ContentSection}.
* @param context The mapping context of the assigned category
* system.
*
* @return A redirect to the category page or the template for generating an
* error view.
*/
@POST
@Path("/{context}/categories/@index-element/reset")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String resetIndexElement(
@PathParam("sectionIdentifier") final String sectionIdentifier,
@PathParam("context") final String context
) {
final RetrieveResult<Category> result = retrieveCategory(
sectionIdentifier, context, "/"
);
if (result.isSuccessful()) {
final Category category = result.getResult();
final Optional<Categorization> categorizationResult = category
.getObjects()
.stream()
.filter(
categorization -> Objects.equals(
categorization.getUuid(), indexElementUuid
)
).findAny();
if (categorizationResult.isPresent()) {
final CcmObject object = categorizationResult
.get()
.getCategorizedObject();
try {
categoryManager.setIndexObject(category, object);
} catch (ObjectNotAssignedToCategoryException ex) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("context", context);
models.put("categoryPath", categoryPath);
models.put("categorizationUuid", indexElementUuid);
return "org/librecms/ui/contentsection/categorysystems/categorization-not-found.xhtml";
}
} else {
models.put("sectionIdentifier", sectionIdentifier);
models.put("context", context);
models.put("categoryPath", categoryPath);
models.put("categorizationUuid", indexElementUuid);
return "org/librecms/ui/contentsection/categorysystems/categorization-not-found.xhtml";
}
categoryManager.resetIndexObject(category);
return String.format(
"redirect:/%s/categorysystems/%s/categories/%s#objects-sections",
"redirect:/%s/categorysystems/%s/categories/",
sectionIdentifier,
context,
categoryPath
context
);
} else {
return result.getFailedResponseTemplate();
@ -893,7 +990,9 @@ public class CategoriesController {
}
/**
* Rests (removes) the index element of a category.
* Resets the index object of a category. The object is still associated
* with the category after this, but no longer the index object of the
* category.
*
* @param sectionIdentifier The identifier of the current
* {@link ContentSection}.
@ -904,7 +1003,7 @@ public class CategoriesController {
* @return A redirect to the category page or the template for generating an
* error view.
*/
@GET
@POST
@Path("/{context}/categories/{categoryPath:(.+)?}/@index-element/reset")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
@ -920,7 +1019,7 @@ public class CategoriesController {
final Category category = result.getResult();
categoryManager.resetIndexObject(category);
return String.format(
"redirect:/%s/categorysystems/%s/categories/%s#objects-sections",
"redirect:/%s/categorysystems/%s/categories/%s",
sectionIdentifier,
context,
categoryPath
@ -1220,7 +1319,47 @@ public class CategoriesController {
}
/**
* Reorders subcategories.
* Reorders objects assigned to the root category.
*
* @param sectionIdentifier The identifier of the current
* {@link ContentSection}.
* @param context The mapping context of the assigned category
* system.
* @param objectIdentifier The identifier of the object to move.
* @param direction The direction of the move.
*
* @return A redirect to the details page of the parent category or the
* template for building an error message.
*/
@POST
@Path(
"/{context}/categories/@objects/{objectIdentifier}/order"
)
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String orderObjects(
@PathParam("sectionIdentifier") final String sectionIdentifier,
@PathParam("context") final String context,
@PathParam("objectIdentifier") final String objectIdentifier,
@FormParam("direction") final String direction
) {
final RetrieveResult<Category> result = retrieveCategory(
sectionIdentifier,
context,
"/"
);
return orderObjects(
result,
sectionIdentifier,
context,
objectIdentifier,
direction
);
}
/**
* Reorders objects assigned to a category.
*
* @param sectionIdentifier The identifier of the current
* {@link ContentSection}.
@ -1246,9 +1385,147 @@ public class CategoriesController {
@FormParam("direction") final String direction
) {
final RetrieveResult<Category> result = retrieveCategory(
sectionIdentifier, context, categoryPath
sectionIdentifier,
context,
categoryPath
);
return orderObjects(
result,
sectionIdentifier,
context,
objectIdentifier,
direction
);
//
// if (result.isSuccessful()) {
// final Category category = result.getResult();
//
// final Optional<Categorization> categorizationResult = category
// .getObjects()
// .stream()
// .filter(
// categorization -> Objects.equals(
// categorization.getUuid(), objectIdentifier
// )
// ).findAny();
// if (categorizationResult.isPresent()) {
// final CcmObject object = categorizationResult
// .get()
// .getCategorizedObject();
// try {
// switch (direction) {
// case "DECREASE":
// categoryManager.decreaseObjectOrder(
// object, category
// );
// break;
// case "INCREASE":
// categoryManager.increaseObjectOrder(
// object, category
// );
// break;
// default:
// // Nothing
// break;
// }
// } catch (ObjectNotAssignedToCategoryException ex) {
// return String.format(
// "redirect:/%s/categorysystems/%s/categories/%s#objects-sections",
// sectionIdentifier,
// context,
// categoryManager.getCategoryPath(category)
// );
// }
// }
//
// return String.format(
// "redirect:/%s/categorysystems/%s/categories/%s",
// sectionIdentifier,
// context,
// categoryManager.getCategoryPath(category)
// );
// } else {
// return result.getFailedResponseTemplate();
// }
}
private String setIndexObject(
final RetrieveResult<Category> result,
@PathParam("sectionIdentifier") final String sectionIdentifier,
@PathParam("context") final String context,
@PathParam("categoryPath") final String categoryPath,
@PathParam("indexElementUuid") final String indexElementUuid
) {
if (result.isSuccessful()) {
final Category category = result.getResult();
final List<Categorization> categorizationResult = category
.getObjects()
.stream()
.filter(
categorization -> Objects.equals(
categorization.getCategorizedObject().getUuid(),
indexElementUuid
)
)
.collect(Collectors.toList());
if (!categorizationResult.isEmpty()) {
for (final Categorization categorization : categorizationResult) {
final CcmObject object = categorization
.getCategorizedObject();
try {
categoryManager.setIndexObject(category, object);
if (object instanceof ContentItem) {
final ContentItem item = (ContentItem) object;
final ContentItem live = itemManager
.getDraftVersion(
item,
ContentItem.class
);
categoryManager.setIndexObject(category, live);
}
} catch (ObjectNotAssignedToCategoryException ex) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("context", context);
models.put("categoryPath", categoryPath);
models.put("categorizationUuid", indexElementUuid);
return "org/librecms/ui/contentsection/categorysystems/categorization-not-found.xhtml";
}
}
} else {
models.put("sectionIdentifier", sectionIdentifier);
models.put("context", context);
models.put("categoryPath", categoryPath);
models.put("categorizationUuid", indexElementUuid);
return "org/librecms/ui/contentsection/categorysystems/categorization-not-found.xhtml";
}
if ("/".equals(categoryPath)
|| category.getParentCategory() == null) {
return String.format(
"redirect:/%s/categorysystems/%s/categories/",
sectionIdentifier,
context
);
} else {
return String.format(
"redirect:/%s/categorysystems/%s/categories/%s",
sectionIdentifier,
context,
categoryPath
);
}
} else {
return result.getFailedResponseTemplate();
}
}
private String orderObjects(
final RetrieveResult<Category> result,
final String sectionIdentifier,
final String context,
final String objectIdentifier,
final String direction
) {
if (result.isSuccessful()) {
final Category category = result.getResult();
@ -1358,7 +1635,7 @@ public class CategoriesController {
);
}
final ContentSection section = sectionResult.get();
if (permissionChecker.isPermitted(
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_CATEGORIES, section
)) {
return RetrieveResult.failed(
@ -1477,6 +1754,15 @@ public class CategoriesController {
category
.getObjects()
.stream()
.filter(
categorization -> categorization
.getCategorizedObject() instanceof ContentItem
)
.filter(
categorization -> ((ContentItem) categorization
.getCategorizedObject())
.getVersion() == ContentItemVersion.DRAFT
)
.map(this::buildCategorizedObjectModel)
.collect(Collectors.toList())
);

View File

@ -223,7 +223,7 @@ public class CategoryModel {
}
public void setObjects(final List<CategorizedObjectModel> objects) {
this.objects = new ArrayList<>();
this.objects = new ArrayList<>(objects);
}
public long getCategoryOrder() {

View File

@ -451,23 +451,15 @@
<th scope="col">
#{CmsAdminMessages['contentsections.categorystems.category.objects.name']}
</th>
</tr>
<tr>
<th scope="col">
#{CmsAdminMessages['contentsections.categorystems.category.objects.title']}
</th>
</tr>
<tr>
<th scope="col">
#{CmsAdminMessages['contentsections.categorystems.category.objects.type']}
</th>
</tr>
<tr>
<th scope="col">
#{CmsAdminMessages['contentsections.categorystems.category.objects.index']}
</th>
</tr>
<tr>
<th colspan="3">
#{CmsAdminMessages['contentsections.categorystems.category.objects.actions']}
</th>
@ -498,7 +490,7 @@
</td>
<td class="actions-order-col">
<c:if test="#{object.objectOrder != 1}">
<form action="#"
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{category.path}/@objects/#{object.objectId}/order"
method="post">
<input name="direction"
value="DECREASE"
@ -513,7 +505,7 @@
</td>
<td class="actions-order-col">
<c:if test="#{object.objectOrder lt CategorySystemModel.selectedCategory.objects.size()}">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/@objects/#{object.objectId}/order"
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{category.path}/@objects/#{object.objectId}/order"
method="post">
<input name="direction"
value="INCREASE"
@ -529,18 +521,24 @@
<td class="actions-setindex-col">
<c:choose>
<c:when test="#{object.indexObject}">
<a class="btn btn-danger"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/@index-element/#{object.objectUuid}">
<bootstrap:svgIcon icon="bookmark-x" />
<span>#{CmsAdminMessages['contentsections.categorystems.category.objects.index_object.reset']}</span>
</a>
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{category.path}/@index-element/reset"
method="post">
<button class="btn btn-danger"
type="submit">
<bootstrap:svgIcon icon="bookmark-x" />
<span>#{CmsAdminMessages['contentsections.categorystems.category.objects.index_object.reset']}</span>
</button>
</form>
</c:when>
<c:otherwise>
<a class="btn btn-info"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/@index-element/reset">
<bootstrap:svgIcon icon="bookmark-star" />
<span>#{CmsAdminMessages['contentsections.categorystems.category.objects.index_object.set']}</span>
</a>
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/categorysystems/#{CategorySystemModel.selectedCategorySystem.context}/categories#{category.path}/@index-element/#{object.objectUuid}"
method="post">
<button class="btn btn-info"
type="submit">
<bootstrap:svgIcon icon="bookmark-star" />
<span>#{CmsAdminMessages['contentsections.categorystems.category.objects.index_object.set']}</span>
</button>
</form>
</c:otherwise>
</c:choose>
</td>