- Added a check to avoid publishing an item assigned to an abstract category (#2413)

- Fixed search tab


git-svn-id: https://svn.libreccm.org/ccm/trunk@3218 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2015-02-17 15:19:40 +00:00
parent 5a877a5284
commit 73b453446d
9 changed files with 124 additions and 44 deletions

View File

@ -1090,7 +1090,7 @@ cms.ui.template_not_supportet=The selected mime type is not supported
cms.ui.uploaded_file_not_properly_formatted=The uploaded file is not properly formatted XML:
cms.ui.unique_string_violation=Unique string value constraint violation.
cms.ui.unique_item_name_violation=An item with this name already exists.
=
cms.ui.lifecycle.publish.not_possible_abstract_category=This item can't be (re-)published because it is assigned to an abstract category (a category to which you can't assign items).
cms.ui.item_searchwidget.submit=item search FormSection submit
cms.ui.workflow.task.approval_or_reject_required=Approval or rejection is required.
cms.ui.type.cancelled=Cancelled
@ -1106,3 +1106,4 @@ cms.ui.authoring.invalid_file_type=Files with invalide type connot be loaded int
cms.ui.authoring.couldnt_convert_missing_inso=Could not convert to html format because interMedia INSO filter is not installed
cms.ui.authoring.couldnt_convert_inso_failed=Could not convert to html format because interMedia INSO filter conversion failed
cms.ui.authoring.html_file_missing_body_tags=The file (which should be type HTML) is missing the <body> or </body> tag.
cms.ui.lifecycle.publish.not_possible_abstract_category\ =

View File

@ -1084,7 +1084,7 @@ cms.ui.template_not_supportet=Das ausgew\u00e4hlte Template(mime type) wird nich
cms.ui.uploaded_file_not_properly_formatted=Die hochgeladene Datei ist fehlerhaft
cms.ui.unique_string_violation=String bereits vergeben.
cms.ui.unique_item_name_violation=Ein Item mit diesem Namen existiert bereits.
=
cms.ui.lifecycle.publish.not_possible_abstract_category=Dieses Dokument kann nicht (re-)publiziert werden, da es einer abstrakten Kategorie (einer Kategorie der keine Items mehr zugeordnet werden k\u00f6nnen) zugeordnet ist.
cms.ui.item_searchwidget.submit=item search FormSection submit
cms.ui.workflow.task.approval_or_reject_required=Ablehnung oder Zustimmung ist ben\u00f6tigt
cms.ui.type.cancelled=Abgebrochen
@ -1100,3 +1100,4 @@ cms.ui.authoring.invalid_file_type=Dateien mit ung\u00fcltigem Typ k\u00f6nnen n
cms.ui.authoring.couldnt_convert_missing_inso=Konnte nicht ins html Format umgewandelt werden, da der interMedia INSO Filter nicht installiert ist
cms.ui.authoring.couldnt_convert_inso_failed=Konnte nicht ins html Format umgewandelt werden, da die interMedia INSO Umwandlung fehlschlug
cms.ui.authoring.html_file_missing_body_tags=Der Datei (vom Type HTML) fehlt der <body> oder </body> Tag
cms.ui.lifecycle.publish.not_possible_abstract_category\ =

View File

@ -127,7 +127,7 @@ cms.ui.template_not_supportet=The selected mime type is not supported
cms.ui.uploaded_file_not_properly_formatted=The uploaded file is not properly formatted XML:
cms.ui.unique_string_violation=Unique string value constraint violation.
cms.ui.unique_item_name_violation=An item with this name already exists.
=
cms.ui.lifecycle.publish.not_possible_abstract_category=This item can't be (re-)published because it is assigned to an abstract category (a category to which you can't assign items).
cms.ui.item_searchwidget.submit=item search FormSection submit
cms.ui.workflow.task.approval_or_reject_required=Approval or rejection is required.
cms.ui.type.name_not_unique=Name not unique
@ -144,3 +144,4 @@ cms.ui.authoring.invalid_file_type=
cms.ui.authoring.couldnt_convert_missing_inso=
cms.ui.authoring.couldnt_convert_inso_failed=
cms.ui.authoring.html_file_missing_body_tags=
cms.ui.lifecycle.publish.not_possible_abstract_category\ =

View File

@ -596,7 +596,7 @@ cms.ui.template_not_supportet=The selected mime type is not supported
cms.ui.uploaded_file_not_properly_formatted=The uploaded file is not properly formatted XML:
cms.ui.unique_string_violation=
cms.ui.unique_item_name_violation=
=
cms.ui.lifecycle.publish.not_possible_abstract_category=This item can't be (re-)published because it is assigned to an abstract category (a category to which you can't assign items).
cms.ui.item_searchwidget.submit=item search FormSection submit
cms.ui.workflow.task.approval_or_reject_required=Approval or rejection is required.
cms.ui.type.name_not_unique=Ce type de contenu a d\u00e9ja un \u00e9l\u00e9ment avec le nom
@ -616,3 +616,4 @@ cms.ui.authoring.invalid_file_type=Fichiers de type invalide connot \u00eatre ch
cms.ui.authoring.couldnt_convert_missing_inso=Impossible de convertir au format HTML car le filtre interMedia INSO n'est pas install\u00e9
cms.ui.authoring.couldnt_convert_inso_failed=Impossible de convertir au format HTML car la conversion de filtre interMedia INSO a \u00e9chou\u00e9
cms.ui.authoring.html_file_missing_body_tags=Le fichier (qui devrait \u00eatre de type HTML) est absent de la <body> ou </ body>
cms.ui.lifecycle.publish.not_possible_abstract_category\ =

View File

@ -46,8 +46,8 @@ import javax.servlet.http.HttpServletRequest;
*/
public class ItemSearchPopup extends ItemSearch {
private static final org.apache.log4j.Logger s_log = org.apache.log4j.Logger.getLogger(
ItemSearchPopup.class);
// private static final org.apache.log4j.Logger s_log = org.apache.log4j.Logger.getLogger(
// ItemSearchPopup.class);
public static final String WIDGET_PARAM = "widget";
public static final String URL_PARAM = "useURL";
public static final String QUERY = "query";
@ -59,32 +59,34 @@ public class ItemSearchPopup extends ItemSearch {
* {@link ContentItem#DRAFT} or {@link ContentItem#LIVE}
* @param limitToContentSection limit the search to the current content section
*/
public ItemSearchPopup(String context, boolean limitToContentSection) {
public ItemSearchPopup(final String context, final boolean limitToContentSection) {
super(context, limitToContentSection);
}
// Hide results by default
@Override
public void register(Page p) {
super.register(p);
p.addGlobalStateParam(new StringParameter(WIDGET_PARAM));
p.addGlobalStateParam(new StringParameter(URL_PARAM));
p.addGlobalStateParam(new StringParameter(QUERY));
public void register(final Page page) {
super.register(page);
page.addGlobalStateParam(new StringParameter(WIDGET_PARAM));
page.addGlobalStateParam(new StringParameter(URL_PARAM));
page.addGlobalStateParam(new StringParameter(QUERY));
}
@Override
protected ItemSearchSection createSearchSection(String context, boolean limitToContentSection) {
protected ItemSearchSection createSearchSection(final String context,
final boolean limitToContentSection) {
return new ItemSearchSectionPopup(context, limitToContentSection);
}
private static class ItemSearchSectionPopup extends ItemSearchSection {
public ItemSearchSectionPopup(String context, boolean limitToContentSection) {
public ItemSearchSectionPopup(final String context,
final boolean limitToContentSection) {
super(context, limitToContentSection);
}
@Override
protected Component createResultsPane(QueryGenerator generator) {
protected Component createResultsPane(final QueryGenerator generator) {
return new PopupResultsPane(generator);
}
@ -92,8 +94,11 @@ public class ItemSearchPopup extends ItemSearch {
/**
* The default context is Live.No need to append &context=live explicitly.
* @param request
* @param oid
* @return
*/
public static String getItemURL(HttpServletRequest request, OID oid) {
public static String getItemURL(final HttpServletRequest request, final OID oid) {
// redirect doesn't use /ccm prefix for some reason, so just returning the raw string.
//ParameterMap map = new ParameterMap();
//map.setParameter("oid", oid.toString());
@ -108,7 +113,7 @@ public class ItemSearchPopup extends ItemSearch {
private static class PopupResultsPane extends ResultsPane {
public PopupResultsPane(QueryGenerator generator) {
public PopupResultsPane(final QueryGenerator generator) {
super(generator);
setRelativeURLs(true);
setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
@ -116,15 +121,16 @@ public class ItemSearchPopup extends ItemSearch {
}
@Override
protected Element generateDocumentXML(PageState state, Document doc) {
Element element = super.generateDocumentXML(state, doc);
protected Element generateDocumentXML(final PageState state,
final Document doc) {
final Element element = super.generateDocumentXML(state, doc);
element.addAttribute("class", "jsButton");
String widget = (String) state.getValue(new StringParameter(WIDGET_PARAM));
String searchWidget = (String) state.getValue(new StringParameter("searchWidget"));
final String widget = (String) state.getValue(new StringParameter(WIDGET_PARAM));
final String searchWidget = (String) state.getValue(new StringParameter("searchWidget"));
boolean useURL = "true".equals(state.getValue(new StringParameter(URL_PARAM)));
final boolean useURL = "true".equals(state.getValue(new StringParameter(URL_PARAM)));
String fillString;
if (useURL) {
@ -133,26 +139,38 @@ public class ItemSearchPopup extends ItemSearch {
fillString = doc.getOID().get("id").toString();
}
String title = doc.getTitle();
final String title = doc.getTitle();
Element jsLabel = Search.newElement("jsAction");
final Element jsLabel = Search.newElement("jsAction");
jsLabel.addAttribute("name", "fillItem"
+ doc.getOID().get("id") + "()");
jsLabel.setText(generateJSLabel((BigDecimal) doc.getOID().get("id"),
widget, searchWidget, fillString, title));
widget,
searchWidget,
fillString,
title));
jsLabel.addAttribute("action",
String.format(
"window.opener.document.%s.value = \"%s\"; self.close(); return false;",
widget,
fillString));
element.addContent(jsLabel);
return element;
}
private String generateJSLabel(BigDecimal id, String widget, String searchWidget,
String fill, String title) {
return " <script language=javascript> "
private String generateJSLabel(final BigDecimal id,
final String widget,
final String searchWidget,
final String fill,
final String title) {
return " <script language=\"javascript\"> "
+ " <!-- \n"
+ " function fillItem" + id + "() { \n"
+ " alert('test');\n"
+ " window.opener.document." + widget + ".value=\"" + fill + "\";\n"
+ " window.opener.document." + searchWidget + ".value=\"" + title.replace(
"\"", "\\\"") + "\";\n"
//+ " window.opener.document." + searchWidget + ".value=\"" + title.replace(
//"\"", "\\\"") + "\";\n"
+ " self.close(); \n"
+ " return false; \n"
+ " } \n"

View File

@ -24,6 +24,8 @@ import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentItem;
@ -34,7 +36,7 @@ import com.arsdigita.cms.ui.item.ContentItemRequestLocal;
import com.arsdigita.toolbox.ui.LayoutPanel;
import com.arsdigita.web.RedirectSignal;
import com.arsdigita.web.URL;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
/**
@ -55,6 +57,7 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
private final LayoutPanel m_selectPane;
private final LayoutPanel m_lockedPane;
private final LayoutPanel m_errorPane;
private final LayoutPanel m_cantPublishPane;
public ItemLifecycleAdminPane(final ContentItemRequestLocal item) {
m_item = item;
@ -107,6 +110,12 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
final Label errorMsg = new Label(gz("cms.ui.lifecycle.publish.error"));
m_errorPane.setBody(errorMsg);
m_cantPublishPane = new LayoutPanel();
add(m_cantPublishPane);
final Label cantPublish = new Label(gz("cms.ui.lifecycle.publish.not_possible_abstract_category"));
m_cantPublishPane.setBody(cantPublish);
connect(selectForm, m_detailPane);
}
@ -146,6 +155,8 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
push(state, m_lockedPane);
state.getResponse().addIntHeader("Refresh", 5);
}
} else if(isAssignedToAbstractCategory(m_item.getContentItem(state))) {
push(state, m_cantPublishPane);
} else {
if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) {
if (m_lifecycle.getLifecycle(state) == null) {
@ -168,4 +179,32 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
return CMS.getContext().getSecurityManager().canAccess(
state.getRequest(), SCHEDULE_PUBLICATION, item);
}
/**
* Checks if the item is assigned to an abstract category.
*
* A category is abstract if not items can assigned to it.
*
* @param item
* @return {@code true} if assigned to a abstract category, {@code false} if not.
*/
private boolean isAssignedToAbstractCategory(final ContentItem item) {
final CategoryCollection categories = item.getCategoryCollection();
boolean result = false;
Category category;
while(categories.next()) {
category = categories.getCategory();
if (category.isAbstract()) {
result = true;
break;
}
}
categories.close();
return result;
}
}

View File

@ -244,7 +244,8 @@ public class ResourceTypeConfig {
if (m_buttons.getCancelButton().isSelected(state)) {
fireCompletionEvent(state);
throw new FormProcessException(KernelGlobalizationUtil.globalization("kernel.cancelled"));
throw new FormProcessException(KernelGlobalizationUtil.globalize(
"kernel.cancelled"));
}
}
});

View File

@ -63,23 +63,34 @@
</div>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="./@score"/>%&nbsp;
<xsl:value-of select="./@score"/>%&#x20;
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:if>
<xsl:value-of disable-output-escaping="yes" select="./search:jsAction"/>
<span>
<a>
<xsl:attribute name="href">
<xsl:choose>
<xsl:when test="/bebop:page/@class='cms-admin'">
<xsl:when test="/bebop:page/@class='cms-admin'
and not(./@class = 'jsButton')">
<xsl:value-of select="concat($context-prefix, '/ccm/', ./@contentSectionName, '/admin/item.jsp?item_id=', ./@id, '&amp;set_tab=1')"/>
</xsl:when>
<xsl:when test="./@class = 'jsButton'">
<xsl:value-of select="'#'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="./@url"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:if test="./search:jsAction">
<xsl:attribute name="onClick">
<xsl:value-of select="./search:jsAction/@action"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="./@title"/>
</a>
</span>
@ -96,6 +107,7 @@
<!--
Show search results for admin pages. These a still using tables, so there is a
special processing for the results.
-->
<xsl:template match="search:object" mode="admin">
<xsl:param name="layoutTree" select="."/>

View File

@ -44,11 +44,11 @@
<xsl:when test="$data-tree//bebop:currentPane/bebop:form//bebop:layoutPanel/bebop:body[//bebop:formWidget]
| $data-tree//bebop:currentPane/bebop:form//bebop:layoutPanel/bebop:right[//bebop:formWidget]">
<form>
<!--<xsl:attribute name="method"
select="if ($data-tree//bebop:form/@method)
then $data-tree//bebop:form/@method
else 'post'"/>-->
<xsl:attribute name="method" select="'post'"/>
<xsl:attribute name="method"
select="if ($data-tree//bebop:form/@method)
then $data-tree//bebop:form/@method
else 'post'"/>
<!--<xsl:attribute name="method" select="'post'"/>-->
<xsl:call-template name="foundry:process-datatree-attributes"/>
<xsl:apply-templates select="$data-tree//bebop:currentPane/bebop:form//bebop:layoutPanel/bebop:body
| $data-tree//bebop:currentPane/bebop:form//bebop:layoutPanel/bebop:right"/>
@ -96,13 +96,19 @@
<xsl:choose>
<xsl:when test="$data-tree//bebop:currentPane/bebop:form//bebop:layoutPanel/bebop:left[//bebop:formWidget]">
<form>
<!--<xsl:attribute name="method"
select="if ($data-tree//bebop:form/@method)
then $data-tree//bebop:form/@method
else 'post'"/>-->
<xsl:attribute name="method" select="'post'"/>
<xsl:attribute name="method"
select="if ($data-tree//bebop:form/@method)
then $data-tree//bebop:form/@method
else 'post'"/>
<!--<xsl:attribute name="method" select="'post'"/>-->
<xsl:call-template name="foundry:process-datatree-attributes"/>
<xsl:apply-templates select="$data-tree//bebop:currentPane/bebop:form//bebop:layoutPanel/bebop:left"/>
<xsl:message>
<xsl:value-of select="concat('Applying template for bebop:pageState to ',
count($data-tree//bebop:currentPane/bebop:form//bebop:pageState),
' objects...')"/>
</xsl:message>
<xsl:apply-templates select="$data-tree//bebop:currentPane/bebop:form//bebop:pageState"/>
</form>
</xsl:when>