/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* 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.
*/
package com.liferay.blogs.web.internal.portlet.action;
import com.liferay.asset.kernel.exception.AssetCategoryException;
import com.liferay.asset.kernel.exception.AssetTagException;
import com.liferay.blogs.exception.EntryContentException;
import com.liferay.blogs.exception.EntryCoverImageCropException;
import com.liferay.blogs.exception.EntryDescriptionException;
import com.liferay.blogs.exception.EntryDisplayDateException;
import com.liferay.blogs.exception.EntrySmallImageNameException;
import com.liferay.blogs.exception.EntrySmallImageScaleException;
import com.liferay.blogs.exception.EntryTitleException;
import com.liferay.blogs.exception.EntryUrlTitleException;
import com.liferay.blogs.exception.NoSuchEntryException;
import com.liferay.blogs.model.BlogsEntry;
import com.liferay.blogs.service.BlogsEntryLocalService;
import com.liferay.blogs.service.BlogsEntryService;
import com.liferay.blogs.util.BlogsEntryAttachmentContentUpdater;
import com.liferay.blogs.util.BlogsEntryAttachmentFileEntryUtil;
import com.liferay.blogs.util.BlogsEntryImageSelectorHelper;
import com.liferay.blogs.web.constants.BlogsPortletKeys;
import com.liferay.document.library.kernel.exception.FileSizeException;
import com.liferay.friendly.url.exception.DuplicateFriendlyURLEntryException;
import com.liferay.portal.kernel.editor.EditorConstants;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.TrashedModel;
import com.liferay.portal.kernel.portlet.JSONPortletResponseUtil;
import com.liferay.portal.kernel.portlet.LiferayPortletURL;
import com.liferay.portal.kernel.portlet.LiferayWindowState;
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.portletfilerepository.PortletFileRepositoryUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.Folder;
import com.liferay.portal.kernel.sanitizer.SanitizerException;
import com.liferay.portal.kernel.security.auth.PrincipalException;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.ServiceContextFactory;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.taglib.ui.ImageSelector;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.transaction.Propagation;
import com.liferay.portal.kernel.transaction.TransactionConfig;
import com.liferay.portal.kernel.transaction.TransactionInvokerUtil;
import com.liferay.portal.kernel.upload.LiferayFileItemException;
import com.liferay.portal.kernel.upload.UploadException;
import com.liferay.portal.kernel.upload.UploadRequestSizeException;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.Http;
import com.liferay.portal.kernel.util.JavaConstants;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.StringPool;
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 com.liferay.portlet.blogs.BlogsEntryAttachmentFileEntryReference;
import com.liferay.trash.kernel.service.TrashEntryService;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletRequest;
import javax.portlet.WindowState;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* @author Brian Wing Shun Chan
* @author Wilson S. Man
* @author Thiago Moreira
* @author Juan Fernández
* @author Zsolt Berentey
* @author Levente Hudák
*/
@Component(
immediate = true,
property = {
"javax.portlet.name=" + BlogsPortletKeys.BLOGS,
"javax.portlet.name=" + BlogsPortletKeys.BLOGS_ADMIN,
"javax.portlet.name=" + BlogsPortletKeys.BLOGS_AGGREGATOR,
"mvc.command.name=/blogs/edit_entry"
},
service = MVCActionCommand.class
)
public class EditEntryMVCActionCommand extends BaseMVCActionCommand {
protected void deleteEntries(
ActionRequest actionRequest, boolean moveToTrash)
throws Exception {
long[] deleteEntryIds = null;
long entryId = ParamUtil.getLong(actionRequest, "entryId");
if (entryId > 0) {
deleteEntryIds = new long[] {entryId};
}
else {
deleteEntryIds = StringUtil.split(
ParamUtil.getString(actionRequest, "deleteEntryIds"), 0L);
}
List<TrashedModel> trashedModels = new ArrayList<>();
for (long deleteEntryId : deleteEntryIds) {
if (moveToTrash) {
BlogsEntry entry = _blogsEntryService.moveEntryToTrash(
deleteEntryId);
trashedModels.add(entry);
}
else {
_blogsEntryService.deleteEntry(deleteEntryId);
}
}
if (moveToTrash && !trashedModels.isEmpty()) {
Map<String, Object> data = new HashMap<>();
data.put("trashedModels", trashedModels);
addDeleteSuccessData(actionRequest, data);
}
}
@Override
protected void doProcessAction(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
try {
BlogsEntry entry = null;
UploadException uploadException =
(UploadException)actionRequest.getAttribute(
WebKeys.UPLOAD_EXCEPTION);
if (uploadException != null) {
Throwable cause = uploadException.getCause();
if (uploadException.isExceededFileSizeLimit()) {
throw new FileSizeException(cause);
}
if (uploadException.isExceededLiferayFileItemSizeLimit()) {
throw new LiferayFileItemException(cause);
}
if (uploadException.isExceededUploadRequestSizeLimit()) {
throw new UploadRequestSizeException(cause);
}
throw new PortalException(cause);
}
else if (cmd.equals(Constants.ADD) ||
cmd.equals(Constants.UPDATE)) {
Callable<BlogsEntry> updateEntryCallable =
new UpdateEntryCallable(actionRequest);
entry = TransactionInvokerUtil.invoke(
_transactionConfig, updateEntryCallable);
}
else if (cmd.equals(Constants.DELETE)) {
deleteEntries(actionRequest, false);
}
else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
deleteEntries(actionRequest, true);
}
else if (cmd.equals(Constants.RESTORE)) {
restoreTrashEntries(actionRequest);
}
else if (cmd.equals(Constants.SUBSCRIBE)) {
subscribe(actionRequest);
}
else if (cmd.equals(Constants.UNSUBSCRIBE)) {
unsubscribe(actionRequest);
}
String redirect = ParamUtil.getString(actionRequest, "redirect");
String portletId = _http.getParameter(redirect, "p_p_id", false);
int workflowAction = ParamUtil.getInteger(
actionRequest, "workflowAction",
WorkflowConstants.ACTION_SAVE_DRAFT);
boolean ajax = ParamUtil.getBoolean(actionRequest, "ajax");
if (ajax) {
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
jsonObject.put(
"attributeDataImageId",
EditorConstants.ATTRIBUTE_DATA_IMAGE_ID);
jsonObject.put("content", entry.getContent());
jsonObject.put(
"coverImageFileEntryId", entry.getCoverImageFileEntryId());
jsonObject.put("entryId", entry.getEntryId());
jsonObject.put("redirect", redirect);
JSONPortletResponseUtil.writeJSON(
actionRequest, actionResponse, jsonObject);
return;
}
if ((entry != null) &&
(workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
redirect = getSaveAndContinueRedirect(
actionRequest, entry, redirect);
sendRedirect(actionRequest, actionResponse, redirect);
}
else {
WindowState windowState = actionRequest.getWindowState();
if (!windowState.equals(LiferayWindowState.POP_UP)) {
sendRedirect(actionRequest, actionResponse, redirect);
}
else {
redirect = _portal.escapeRedirect(redirect);
if (Validator.isNotNull(redirect)) {
if (cmd.equals(Constants.ADD) && (entry != null)) {
String namespace = _portal.getPortletNamespace(
portletId);
redirect = _http.addParameter(
redirect, namespace + "className",
BlogsEntry.class.getName());
redirect = _http.addParameter(
redirect, namespace + "classPK",
entry.getEntryId());
}
actionRequest.setAttribute(WebKeys.REDIRECT, redirect);
}
}
}
}
catch (AssetCategoryException | AssetTagException e) {
SessionErrors.add(actionRequest, e.getClass(), e);
actionResponse.setRenderParameter(
"mvcRenderCommandName", "/blogs/edit_entry");
hideDefaultSuccessMessage(actionRequest);
}
catch (DuplicateFriendlyURLEntryException | EntryContentException |
EntryCoverImageCropException | EntryDescriptionException |
EntryDisplayDateException | EntrySmallImageNameException |
EntrySmallImageScaleException | EntryTitleException |
EntryUrlTitleException | FileSizeException |
LiferayFileItemException | SanitizerException |
UploadRequestSizeException e) {
SessionErrors.add(actionRequest, e.getClass());
actionResponse.setRenderParameter(
"mvcRenderCommandName", "/blogs/edit_entry");
hideDefaultSuccessMessage(actionRequest);
}
catch (NoSuchEntryException | PrincipalException e) {
SessionErrors.add(actionRequest, e.getClass());
actionResponse.setRenderParameter("mvcPath", "/blogs/error.jsp");
hideDefaultSuccessMessage(actionRequest);
}
catch (Throwable t) {
_log.error(t, t);
actionResponse.setRenderParameter("mvcPath", "/blogs/error.jsp");
hideDefaultSuccessMessage(actionRequest);
}
}
protected String getSaveAndContinueRedirect(
ActionRequest actionRequest, BlogsEntry entry, String redirect)
throws Exception {
PortletConfig portletConfig = (PortletConfig)actionRequest.getAttribute(
JavaConstants.JAVAX_PORTLET_CONFIG);
LiferayPortletURL portletURL = PortletURLFactoryUtil.create(
actionRequest, portletConfig.getPortletName(),
PortletRequest.RENDER_PHASE);
portletURL.setParameter("mvcRenderCommandName", "/blogs/edit_entry");
portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
portletURL.setParameter("redirect", redirect, false);
portletURL.setParameter(
"groupId", String.valueOf(entry.getGroupId()), false);
portletURL.setParameter(
"entryId", String.valueOf(entry.getEntryId()), false);
portletURL.setWindowState(actionRequest.getWindowState());
return portletURL.toString();
}
protected void restoreTrashEntries(ActionRequest actionRequest)
throws Exception {
long[] restoreTrashEntryIds = StringUtil.split(
ParamUtil.getString(actionRequest, "restoreTrashEntryIds"), 0L);
for (long restoreTrashEntryId : restoreTrashEntryIds) {
_trashEntryService.restoreEntry(restoreTrashEntryId);
}
}
@Reference(policyOption = ReferencePolicyOption.GREEDY, unbind = "-")
protected void setBlogsEntryAttachmentContentUpdater(
BlogsEntryAttachmentContentUpdater blogsEntryAttachmentContentUpdater) {
_blogsEntryAttachmentContentUpdater =
blogsEntryAttachmentContentUpdater;
}
@Reference(unbind = "-")
protected void setBlogsEntryLocalService(
BlogsEntryLocalService blogsEntryLocalService) {
_blogsEntryLocalService = blogsEntryLocalService;
}
@Reference(unbind = "-")
protected void setBlogsEntryService(BlogsEntryService blogsEntryService) {
_blogsEntryService = blogsEntryService;
}
@Reference(unbind = "-")
protected void setTrashEntryService(TrashEntryService trashEntryService) {
_trashEntryService = trashEntryService;
}
protected void subscribe(ActionRequest actionRequest) throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
_blogsEntryService.subscribe(themeDisplay.getScopeGroupId());
}
protected void unsubscribe(ActionRequest actionRequest) throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
_blogsEntryService.unsubscribe(themeDisplay.getScopeGroupId());
}
protected BlogsEntry updateEntry(ActionRequest actionRequest)
throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
long entryId = ParamUtil.getLong(actionRequest, "entryId");
String title = ParamUtil.getString(actionRequest, "title");
String subtitle = ParamUtil.getString(actionRequest, "subtitle");
String urlTitle = ParamUtil.getString(actionRequest, "urlTitle");
String description = StringPool.BLANK;
boolean customAbstract = ParamUtil.getBoolean(
actionRequest, "customAbstract");
if (customAbstract) {
description = ParamUtil.getString(actionRequest, "description");
if (Validator.isNull(description)) {
throw new EntryDescriptionException();
}
}
String content = ParamUtil.getString(actionRequest, "content");
int displayDateMonth = ParamUtil.getInteger(
actionRequest, "displayDateMonth");
int displayDateDay = ParamUtil.getInteger(
actionRequest, "displayDateDay");
int displayDateYear = ParamUtil.getInteger(
actionRequest, "displayDateYear");
int displayDateHour = ParamUtil.getInteger(
actionRequest, "displayDateHour");
int displayDateMinute = ParamUtil.getInteger(
actionRequest, "displayDateMinute");
int displayDateAmPm = ParamUtil.getInteger(
actionRequest, "displayDateAmPm");
if (displayDateAmPm == Calendar.PM) {
displayDateHour += 12;
}
boolean allowPingbacks = ParamUtil.getBoolean(
actionRequest, "allowPingbacks");
boolean allowTrackbacks = ParamUtil.getBoolean(
actionRequest, "allowTrackbacks");
String[] trackbacks = StringUtil.split(
ParamUtil.getString(actionRequest, "trackbacks"));
long coverImageFileEntryId = ParamUtil.getLong(
actionRequest, "coverImageFileEntryId");
String coverImageURL = ParamUtil.getString(
actionRequest, "coverImageURL");
String coverImageFileEntryCropRegion = ParamUtil.getString(
actionRequest, "coverImageFileEntryCropRegion");
String coverImageCaption = ParamUtil.getString(
actionRequest, "coverImageCaption");
long oldCoverImageId = 0;
String oldCoverImageURL = StringPool.BLANK;
long oldSmallImageId = 0;
String oldSmallImageURL = StringPool.BLANK;
if (entryId != 0) {
BlogsEntry entry = _blogsEntryLocalService.getEntry(entryId);
oldCoverImageId = entry.getCoverImageFileEntryId();
oldCoverImageURL = entry.getCoverImageURL();
oldSmallImageId = entry.getSmallImageId();
oldSmallImageURL = entry.getSmallImageURL();
}
BlogsEntryImageSelectorHelper blogsEntryCoverImageSelectorHelper =
new BlogsEntryImageSelectorHelper(
coverImageFileEntryId, oldCoverImageId,
coverImageFileEntryCropRegion, coverImageURL, oldCoverImageURL);
ImageSelector coverImageImageSelector =
blogsEntryCoverImageSelectorHelper.getImageSelector();
long smallImageFileEntryId = ParamUtil.getLong(
actionRequest, "smallImageFileEntryId");
String smallImageURL = ParamUtil.getString(
actionRequest, "smallImageURL");
BlogsEntryImageSelectorHelper blogsEntrySmallImageSelectorHelper =
new BlogsEntryImageSelectorHelper(
smallImageFileEntryId, oldSmallImageId, StringPool.BLANK,
smallImageURL, oldSmallImageURL);
ImageSelector smallImageImageSelector =
blogsEntrySmallImageSelectorHelper.getImageSelector();
ServiceContext serviceContext = ServiceContextFactory.getInstance(
BlogsEntry.class.getName(), actionRequest);
BlogsEntry entry = null;
List<BlogsEntryAttachmentFileEntryReference>
blogsEntryAttachmentFileEntryReferences = null;
if (entryId <= 0) {
// Add entry
entry = _blogsEntryService.addEntry(
title, subtitle, urlTitle, description, content,
displayDateMonth, displayDateDay, displayDateYear,
displayDateHour, displayDateMinute, allowPingbacks,
allowTrackbacks, trackbacks, coverImageCaption,
coverImageImageSelector, smallImageImageSelector,
serviceContext);
List<FileEntry> tempBlogsEntryAttachments =
BlogsEntryAttachmentFileEntryUtil.
getTempBlogsEntryAttachmentFileEntries(content);
if (!tempBlogsEntryAttachments.isEmpty()) {
Folder folder = _blogsEntryLocalService.addAttachmentsFolder(
themeDisplay.getUserId(), entry.getGroupId());
blogsEntryAttachmentFileEntryReferences =
BlogsEntryAttachmentFileEntryUtil.
addBlogsEntryAttachmentFileEntries(
entry.getGroupId(), themeDisplay.getUserId(),
entry.getEntryId(), folder.getFolderId(),
tempBlogsEntryAttachments);
content = _blogsEntryAttachmentContentUpdater.updateContent(
content, blogsEntryAttachmentFileEntryReferences);
entry.setContent(content);
_blogsEntryLocalService.updateBlogsEntry(entry);
}
for (FileEntry tempBlogsEntryAttachment :
tempBlogsEntryAttachments) {
PortletFileRepositoryUtil.deletePortletFileEntry(
tempBlogsEntryAttachment.getFileEntryId());
}
}
else {
// Update entry
boolean sendEmailEntryUpdated = ParamUtil.getBoolean(
actionRequest, "sendEmailEntryUpdated");
serviceContext.setAttribute(
"sendEmailEntryUpdated", sendEmailEntryUpdated);
String emailEntryUpdatedComment = ParamUtil.getString(
actionRequest, "emailEntryUpdatedComment");
serviceContext.setAttribute(
"emailEntryUpdatedComment", emailEntryUpdatedComment);
entry = _blogsEntryLocalService.getEntry(entryId);
List<FileEntry> tempBlogsEntryAttachmentFileEntries =
BlogsEntryAttachmentFileEntryUtil.
getTempBlogsEntryAttachmentFileEntries(content);
if (!tempBlogsEntryAttachmentFileEntries.isEmpty()) {
Folder folder = _blogsEntryLocalService.addAttachmentsFolder(
themeDisplay.getUserId(), entry.getGroupId());
blogsEntryAttachmentFileEntryReferences =
BlogsEntryAttachmentFileEntryUtil.
addBlogsEntryAttachmentFileEntries(
entry.getGroupId(), themeDisplay.getUserId(),
entry.getEntryId(), folder.getFolderId(),
tempBlogsEntryAttachmentFileEntries);
content = _blogsEntryAttachmentContentUpdater.updateContent(
content, blogsEntryAttachmentFileEntryReferences);
}
entry = _blogsEntryService.updateEntry(
entryId, title, subtitle, urlTitle, description, content,
displayDateMonth, displayDateDay, displayDateYear,
displayDateHour, displayDateMinute, allowPingbacks,
allowTrackbacks, trackbacks, coverImageCaption,
coverImageImageSelector, smallImageImageSelector,
serviceContext);
for (FileEntry tempBlogsEntryAttachmentFileEntry :
tempBlogsEntryAttachmentFileEntries) {
PortletFileRepositoryUtil.deletePortletFileEntry(
tempBlogsEntryAttachmentFileEntry.getFileEntryId());
}
}
if (blogsEntryCoverImageSelectorHelper.isFileEntryTempFile()) {
_blogsEntryLocalService.addOriginalImageFileEntry(
themeDisplay.getUserId(), entry.getGroupId(),
entry.getEntryId(), coverImageImageSelector);
PortletFileRepositoryUtil.deletePortletFileEntry(
coverImageFileEntryId);
}
if (blogsEntrySmallImageSelectorHelper.isFileEntryTempFile()) {
_blogsEntryLocalService.addOriginalImageFileEntry(
themeDisplay.getUserId(), entry.getGroupId(),
entry.getEntryId(), smallImageImageSelector);
PortletFileRepositoryUtil.deletePortletFileEntry(
smallImageFileEntryId);
}
return entry;
}
private static final Log _log = LogFactoryUtil.getLog(
EditEntryMVCActionCommand.class);
private static final TransactionConfig _transactionConfig =
TransactionConfig.Factory.create(
Propagation.REQUIRED, new Class<?>[] {Exception.class});
private BlogsEntryAttachmentContentUpdater
_blogsEntryAttachmentContentUpdater;
private BlogsEntryLocalService _blogsEntryLocalService;
private BlogsEntryService _blogsEntryService;
@Reference
private Http _http;
@Reference
private Portal _portal;
private TrashEntryService _trashEntryService;
private class UpdateEntryCallable implements Callable<BlogsEntry> {
@Override
public BlogsEntry call() throws Exception {
return updateEntry(_actionRequest);
}
private UpdateEntryCallable(ActionRequest actionRequest) {
_actionRequest = actionRequest;
}
private final ActionRequest _actionRequest;
}
}