com.liferay.journal.web.internal.portlet.action.UpdateArticleMVCActionCommand Maven / Gradle / Ivy
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.journal.web.internal.portlet.action;
import com.liferay.asset.display.page.portlet.AssetDisplayPageEntryFormProcessor;
import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.service.AssetEntryLocalService;
import com.liferay.dynamic.data.mapping.form.values.factory.DDMFormValuesFactory;
import com.liferay.dynamic.data.mapping.service.DDMStructureLocalService;
import com.liferay.dynamic.data.mapping.util.DDMFormValuesToFieldsConverter;
import com.liferay.journal.constants.JournalContentPortletKeys;
import com.liferay.journal.constants.JournalPortletKeys;
import com.liferay.journal.model.JournalArticle;
import com.liferay.journal.service.JournalArticleLocalService;
import com.liferay.journal.service.JournalArticleService;
import com.liferay.journal.util.JournalConverter;
import com.liferay.journal.util.JournalHelper;
import com.liferay.journal.web.internal.asset.model.JournalArticleAssetRenderer;
import com.liferay.journal.web.internal.util.JournalArticleUtil;
import com.liferay.layout.model.LayoutClassedModelUsage;
import com.liferay.layout.service.LayoutClassedModelUsageLocalService;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.feature.flag.FeatureFlagManagerUtil;
import com.liferay.portal.kernel.language.Language;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil;
import com.liferay.portal.kernel.portlet.PortletURLFactoryUtil;
import com.liferay.portal.kernel.portlet.bridges.mvc.BaseMVCActionCommand;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand;
import com.liferay.portal.kernel.portlet.url.builder.PortletURLBuilder;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.service.PortletLocalService;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.ServiceContextFactory;
import com.liferay.portal.kernel.servlet.MultiSessionMessages;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.upload.UploadPortletRequest;
import com.liferay.portal.kernel.util.FriendlyURLNormalizer;
import com.liferay.portal.kernel.util.HashMapBuilder;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.HttpComponentsUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.Localization;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.servlet.http.HttpServletRequest;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Eudaldo Alonso
*/
@Component(
property = {
"javax.portlet.name=" + JournalPortletKeys.JOURNAL,
"mvc.command.name=/journal/add_article",
"mvc.command.name=/journal/update_article"
},
service = MVCActionCommand.class
)
public class UpdateArticleMVCActionCommand extends BaseMVCActionCommand {
@Override
protected void doProcessAction(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
String actionName = ParamUtil.getString(
actionRequest, ActionRequest.ACTION_NAME);
UploadPortletRequest uploadPortletRequest =
_portal.getUploadPortletRequest(actionRequest);
long groupId = ParamUtil.getLong(uploadPortletRequest, "groupId");
String oldUrlTitle = StringPool.BLANK;
String tempOldUrlTitle = StringPool.BLANK;
if (!actionName.equals("/journal/add_article")) {
JournalArticle article = _journalArticleService.getArticle(
groupId, ParamUtil.getString(uploadPortletRequest, "articleId"),
ParamUtil.getDouble(uploadPortletRequest, "version"));
tempOldUrlTitle = article.getUrlTitle();
}
JournalArticle article = JournalArticleUtil.addOrUpdateArticle(
actionName, _assetDisplayPageEntryFormProcessor,
_ddmFormValuesFactory, _ddmFormValuesToFieldsConverter,
_ddmStructureLocalService, _journalArticleService,
_journalConverter, _journalHelper, _localization, _portal,
actionRequest);
if (!tempOldUrlTitle.equals(article.getUrlTitle())) {
oldUrlTitle = tempOldUrlTitle;
}
// Journal content
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
String portletResource = ParamUtil.getString(
actionRequest, "portletResource");
long refererPlid = ParamUtil.getLong(actionRequest, "refererPlid");
if (Validator.isNotNull(portletResource) && (refererPlid > 0)) {
AssetEntry assetEntry = _assetEntryLocalService.fetchEntry(
JournalArticle.class.getName(), article.getResourcePrimKey());
PortletPreferences portletPreferences =
PortletPreferencesFactoryUtil.getStrictPortletSetup(
_layoutLocalService.getLayout(refererPlid),
portletResource);
if (portletPreferences != null) {
portletPreferences.setValue(
"groupId", String.valueOf(article.getGroupId()));
Portlet portlet = _portletLocalService.getPortletById(
portletResource);
if (!FeatureFlagManagerUtil.isEnabled(
themeDisplay.getCompanyId(), "LPD-27566") ||
(portlet == null) ||
!Objects.equals(
portlet.getPortletName(),
JournalContentPortletKeys.JOURNAL_CONTENT)) {
portletPreferences.setValue(
"articleId", article.getArticleId());
if (assetEntry != null) {
portletPreferences.setValue(
"assetEntryId",
String.valueOf(assetEntry.getEntryId()));
}
}
else {
portletPreferences.setValue(
"articleExternalReferenceCode",
article.getExternalReferenceCode());
}
portletPreferences.store();
}
if (assetEntry != null) {
ServiceContext serviceContext =
ServiceContextFactory.getInstance(
JournalArticle.class.getName(), uploadPortletRequest);
serviceContext.setAttribute(
"updateAutoTags",
ParamUtil.getBoolean(actionRequest, "updateAutoTags"));
_updateLayoutClassedModelUsage(
groupId,
_portal.getClassNameId(JournalArticle.class.getName()),
article.getResourcePrimKey(), portletResource, refererPlid,
serviceContext);
}
}
// Asset display page
int workflowAction = ParamUtil.getInteger(
actionRequest, "workflowAction", WorkflowConstants.ACTION_PUBLISH);
if (workflowAction != WorkflowConstants.ACTION_SAVE_DRAFT) {
String referringPortletResource = ParamUtil.getString(
actionRequest, "referringPortletResource");
if (Validator.isNotNull(referringPortletResource)) {
MultiSessionMessages.add(
actionRequest,
referringPortletResource + "requestProcessed");
}
else if (Validator.isNotNull(portletResource)) {
MultiSessionMessages.add(
actionRequest, portletResource + "requestProcessed");
}
if (FeatureFlagManagerUtil.isEnabled(
themeDisplay.getCompanyId(), "LPD-15596")) {
if (article.isPending()) {
User user = themeDisplay.getUser();
Date displayDate = _portal.getDate(
ParamUtil.getInteger(
uploadPortletRequest, "displayDateMonth"),
ParamUtil.getInteger(
uploadPortletRequest, "displayDateDay"),
ParamUtil.getInteger(
uploadPortletRequest, "displayDateYear"),
ParamUtil.getInteger(
uploadPortletRequest, "displayDateHour"),
ParamUtil.getInteger(
uploadPortletRequest, "displayDateMinute"),
user.getTimeZone(), null);
if (displayDate != null) {
MultiSessionMessages.add(
actionRequest, "articlePendingScheduled",
article.getId());
}
else {
MultiSessionMessages.add(
actionRequest, "articlePending", article.getId());
}
}
else if (article.isScheduled()) {
MultiSessionMessages.add(
actionRequest, "articleScheduled", article.getId());
}
else {
if (actionName.equals("/journal/add_article")) {
MultiSessionMessages.add(
actionRequest, "articleCreated", article.getId());
}
else {
MultiSessionMessages.add(
actionRequest, "articleUpdated", article.getId());
}
}
}
}
if (!FeatureFlagManagerUtil.isEnabled(
themeDisplay.getCompanyId(), "LPD-15596")) {
if (actionName.equals("/journal/add_article")) {
MultiSessionMessages.add(
actionRequest, "articleCreated", article.getId());
}
else {
MultiSessionMessages.add(
actionRequest, "articleUpdated", article.getId());
}
}
HttpServletRequest httpServletRequest = _portal.getHttpServletRequest(
actionRequest);
Map friendlyURLMap = _localization.getLocalizationMap(
actionRequest, "friendlyURL");
Map friendlyURLWarningMessages =
_getFriendlyURLWarningMessages(
actionRequest, article.getFriendlyURLMap(), friendlyURLMap);
for (Map.Entry entry :
friendlyURLWarningMessages.entrySet()) {
SessionMessages.add(
httpServletRequest, entry.getKey(), entry.getValue());
}
_sendEditArticleRedirect(actionRequest, article, oldUrlTitle);
boolean hideDefaultSuccessMessage = ParamUtil.getBoolean(
actionRequest, "hideDefaultSuccessMessage");
if (hideDefaultSuccessMessage) {
hideDefaultSuccessMessage(actionRequest);
}
else {
SessionMessages.remove(
httpServletRequest,
_portal.getPortletId(actionRequest) +
SessionMessages.KEY_SUFFIX_HIDE_DEFAULT_SUCCESS_MESSAGE);
}
hideDefaultSuccessMessage(actionRequest);
}
private Map _getFriendlyURLWarningMessages(
ActionRequest actionRequest, Map currentFriendlyURLMap,
Map originalFriendlyURLMap) {
List excludedGroupIds = new ArrayList<>();
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
Group group = themeDisplay.getScopeGroup();
excludedGroupIds.add(group.getGroupId());
if (group.isStagingGroup()) {
excludedGroupIds.add(group.getLiveGroupId());
}
else if (group.hasStagingGroup()) {
Group stagingGroup = group.getStagingGroup();
excludedGroupIds.add(stagingGroup.getGroupId());
}
List friendlyURLChangedMessages = new ArrayList<>();
List friendlyURLDuplicatedLocales = new ArrayList<>();
Map> friendlyURLGroupIdsMap = new HashMap<>();
HttpServletRequest httpServletRequest = _portal.getHttpServletRequest(
actionRequest);
for (Map.Entry entry :
currentFriendlyURLMap.entrySet()) {
Locale locale = entry.getKey();
String originalFriendlyURL = originalFriendlyURLMap.get(locale);
String normalizedOriginalFriendlyURL =
_friendlyURLNormalizer.normalizeWithEncoding(
originalFriendlyURL);
String currentFriendlyURL = entry.getValue();
if (Validator.isNotNull(originalFriendlyURL) &&
!currentFriendlyURL.equals(normalizedOriginalFriendlyURL)) {
friendlyURLChangedMessages.add(
_language.format(
httpServletRequest, "for-locale-x-x-was-changed-to-x",
new Object[] {
"" + locale.getLanguage() + "",
"" +
HtmlUtil.escapeURL(originalFriendlyURL) +
"",
"" + currentFriendlyURL + ""
}));
}
List groupIds = friendlyURLGroupIdsMap.computeIfAbsent(
currentFriendlyURL,
key -> ListUtil.remove(
_journalArticleLocalService.getGroupIdsByUrlTitle(
themeDisplay.getCompanyId(), key),
excludedGroupIds));
if (!groupIds.isEmpty() &&
((groupIds.size() > 1) ||
!Objects.equals(
groupIds.get(0), themeDisplay.getScopeGroupId()))) {
friendlyURLDuplicatedLocales.add(locale);
}
}
if (friendlyURLChangedMessages.isEmpty() &&
friendlyURLDuplicatedLocales.isEmpty()) {
return Collections.emptyMap();
}
return HashMapBuilder.put(
"friendlyURLChanged_requestProcessedWarning",
() -> {
if (friendlyURLChangedMessages.isEmpty()) {
return null;
}
friendlyURLChangedMessages.add(
0,
_language.get(
httpServletRequest,
"the-following-friendly-urls-were-changed-to-ensure-" +
"uniqueness"));
return StringUtil.merge(friendlyURLChangedMessages, "
");
}
).put(
"friendlyURLDuplicated_requestProcessedWarning",
() -> {
if (friendlyURLDuplicatedLocales.isEmpty()) {
return null;
}
Locale siteDefaultLocale = _portal.getSiteDefaultLocale(group);
if ((friendlyURLDuplicatedLocales.size() > 1) &&
friendlyURLDuplicatedLocales.remove(siteDefaultLocale)) {
friendlyURLDuplicatedLocales.add(0, siteDefaultLocale);
}
if (friendlyURLDuplicatedLocales.size() > 3) {
return _language.format(
themeDisplay.getLocale(),
StringBundler.concat(
"the-content-has-been-published-but-might-cause-",
"errors.-the-url-used-in-x-and-x-more-",
"translations-already-exists-in-other-sites-or-",
"asset-libraries"),
new String[] {
_getLocaleDisplayNames(
themeDisplay.getLocale(),
friendlyURLDuplicatedLocales.get(0),
friendlyURLDuplicatedLocales.get(1),
friendlyURLDuplicatedLocales.get(2)),
String.valueOf(
friendlyURLDuplicatedLocales.size() - 3)
},
false);
}
if (friendlyURLDuplicatedLocales.size() == 1) {
return _language.format(
themeDisplay.getLocale(),
"the-content-has-been-published-but-might-cause-" +
"errors.-the-url-used-in-x-already-exists-in-" +
"other-sites-or-asset-libraries",
new String[] {
_getLocaleDisplayNames(
themeDisplay.getLocale(),
friendlyURLDuplicatedLocales.get(0))
},
false);
}
int lastElementIndex = friendlyURLDuplicatedLocales.size() - 1;
List locales = ListUtil.subList(
friendlyURLDuplicatedLocales, 0, lastElementIndex);
return _language.format(
themeDisplay.getLocale(),
"the-content-has-been-published-but-might-cause-errors.-" +
"the-url-used-in-x-and-x-already-exists-in-other-" +
"sites-or-asset-libraries",
new String[] {
_getLocaleDisplayNames(
themeDisplay.getLocale(),
locales.toArray(new Locale[0])),
_getLocaleDisplayNames(
themeDisplay.getLocale(),
friendlyURLDuplicatedLocales.get(lastElementIndex))
},
false);
}
).build();
}
private String _getLocaleDisplayNames(Locale locale, Locale... locales) {
List displayLocaleNames = new ArrayList<>();
for (Locale currentLocale : locales) {
displayLocaleNames.add(
LocaleUtil.getLocaleDisplayName(currentLocale, locale));
}
return StringUtil.merge(displayLocaleNames, StringPool.COMMA_AND_SPACE);
}
private String _getSaveAndContinueRedirect(
ActionRequest actionRequest, JournalArticle article, String redirect) {
return PortletURLBuilder.create(
PortletURLFactoryUtil.create(
actionRequest, JournalPortletKeys.JOURNAL,
PortletRequest.RENDER_PHASE)
).setMVCRenderCommandName(
"/journal/edit_article"
).setRedirect(
redirect
).setPortletResource(
ParamUtil.getString(actionRequest, "portletResource")
).setParameter(
"articleId", article.getArticleId()
).setParameter(
"folderId", article.getFolderId()
).setParameter(
"groupId", article.getGroupId()
).setParameter(
"languageId",
() -> {
String languageId = ParamUtil.getString(
actionRequest, "languageId");
if (Validator.isNull(languageId)) {
return null;
}
Locale locale = LocaleUtil.fromLanguageId(
languageId, true, false);
if (locale == null) {
return null;
}
return languageId;
}
).setParameter(
"referringPortletResource",
ParamUtil.getString(actionRequest, "referringPortletResource")
).setParameter(
"resourcePrimKey", article.getResourcePrimKey()
).setParameter(
"version", article.getVersion()
).setWindowState(
actionRequest.getWindowState()
).buildString();
}
private void _sendEditArticleRedirect(
ActionRequest actionRequest, JournalArticle article,
String oldUrlTitle)
throws Exception {
String actionName = ParamUtil.getString(
actionRequest, ActionRequest.ACTION_NAME);
String redirect = ParamUtil.getString(actionRequest, "redirect");
int workflowAction = ParamUtil.getInteger(
actionRequest, "workflowAction", WorkflowConstants.ACTION_PUBLISH);
String portletId = HttpComponentsUtil.getParameter(
redirect, "portletResource", false);
String namespace = _portal.getPortletNamespace(portletId);
if (Validator.isNotNull(oldUrlTitle) &&
Validator.isNotNull(portletId)) {
String oldRedirectParam = namespace + "redirect";
String oldRedirect = HttpComponentsUtil.getParameter(
redirect, oldRedirectParam, false);
if (Validator.isNotNull(oldRedirect)) {
String newRedirect = HttpComponentsUtil.decodeURL(oldRedirect);
newRedirect = StringUtil.replace(
newRedirect, oldUrlTitle, article.getUrlTitle());
newRedirect = StringUtil.replace(
newRedirect, oldRedirectParam, "redirect");
redirect = StringUtil.replace(
redirect, oldRedirect, newRedirect);
}
}
if ((article != null) &&
(workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
redirect = _getSaveAndContinueRedirect(
actionRequest, article, redirect);
}
else {
redirect = _portal.escapeRedirect(redirect);
if (Validator.isNotNull(redirect) &&
Validator.isNotNull(portletId) &&
actionName.equals("/journal/add_article") &&
(article != null) && Validator.isNotNull(namespace)) {
redirect = HttpComponentsUtil.addParameter(
redirect, namespace + "className",
JournalArticle.class.getName());
redirect = HttpComponentsUtil.addParameter(
redirect, namespace + "classPK",
JournalArticleAssetRenderer.getClassPK(article));
}
}
actionRequest.setAttribute(WebKeys.REDIRECT, redirect);
}
private void _updateLayoutClassedModelUsage(
long groupId, long classNameId, long classPK, String portletResource,
long plid, ServiceContext serviceContext) {
LayoutClassedModelUsage layoutClassedModelUsage =
_layoutClassedModelUsageLocalService.fetchLayoutClassedModelUsage(
groupId, classNameId, classPK, StringPool.BLANK,
portletResource, _portal.getClassNameId(Portlet.class), plid);
if (layoutClassedModelUsage != null) {
return;
}
_layoutClassedModelUsageLocalService.addLayoutClassedModelUsage(
groupId, classNameId, classPK, StringPool.BLANK, portletResource,
_portal.getClassNameId(Portlet.class), plid, serviceContext);
}
@Reference
private AssetDisplayPageEntryFormProcessor
_assetDisplayPageEntryFormProcessor;
@Reference
private AssetEntryLocalService _assetEntryLocalService;
@Reference
private DDMFormValuesFactory _ddmFormValuesFactory;
@Reference
private DDMFormValuesToFieldsConverter _ddmFormValuesToFieldsConverter;
@Reference
private DDMStructureLocalService _ddmStructureLocalService;
@Reference
private FriendlyURLNormalizer _friendlyURLNormalizer;
@Reference
private JournalArticleLocalService _journalArticleLocalService;
@Reference
private JournalArticleService _journalArticleService;
@Reference
private JournalConverter _journalConverter;
@Reference
private JournalHelper _journalHelper;
@Reference
private Language _language;
@Reference
private LayoutClassedModelUsageLocalService
_layoutClassedModelUsageLocalService;
@Reference
private LayoutLocalService _layoutLocalService;
@Reference
private Localization _localization;
@Reference
private Portal _portal;
@Reference
private PortletLocalService _portletLocalService;
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy