001
014
015 package com.liferay.portlet.blogs.action;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.json.JSONFactoryUtil;
020 import com.liferay.portal.kernel.json.JSONObject;
021 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
022 import com.liferay.portal.kernel.portlet.LiferayWindowState;
023 import com.liferay.portal.kernel.sanitizer.SanitizerException;
024 import com.liferay.portal.kernel.servlet.SessionErrors;
025 import com.liferay.portal.kernel.servlet.SessionMessages;
026 import com.liferay.portal.kernel.upload.LiferayFileItemException;
027 import com.liferay.portal.kernel.upload.UploadException;
028 import com.liferay.portal.kernel.upload.UploadPortletRequest;
029 import com.liferay.portal.kernel.util.ArrayUtil;
030 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
031 import com.liferay.portal.kernel.util.Constants;
032 import com.liferay.portal.kernel.util.HttpUtil;
033 import com.liferay.portal.kernel.util.ParamUtil;
034 import com.liferay.portal.kernel.util.StreamUtil;
035 import com.liferay.portal.kernel.util.StringPool;
036 import com.liferay.portal.kernel.util.StringUtil;
037 import com.liferay.portal.kernel.util.Validator;
038 import com.liferay.portal.kernel.workflow.WorkflowConstants;
039 import com.liferay.portal.security.auth.PrincipalException;
040 import com.liferay.portal.service.ServiceContext;
041 import com.liferay.portal.service.ServiceContextFactory;
042 import com.liferay.portal.struts.PortletAction;
043 import com.liferay.portal.theme.ThemeDisplay;
044 import com.liferay.portal.util.PortalUtil;
045 import com.liferay.portal.util.PortletKeys;
046 import com.liferay.portal.util.PropsValues;
047 import com.liferay.portal.util.WebKeys;
048 import com.liferay.portlet.PortletURLFactoryUtil;
049 import com.liferay.portlet.asset.AssetCategoryException;
050 import com.liferay.portlet.asset.AssetTagException;
051 import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
052 import com.liferay.portlet.blogs.EntryContentException;
053 import com.liferay.portlet.blogs.EntryDisplayDateException;
054 import com.liferay.portlet.blogs.EntrySmallImageNameException;
055 import com.liferay.portlet.blogs.EntrySmallImageSizeException;
056 import com.liferay.portlet.blogs.EntryTitleException;
057 import com.liferay.portlet.blogs.NoSuchEntryException;
058 import com.liferay.portlet.blogs.model.BlogsEntry;
059 import com.liferay.portlet.blogs.service.BlogsEntryLocalServiceUtil;
060 import com.liferay.portlet.blogs.service.BlogsEntryServiceUtil;
061 import com.liferay.portlet.documentlibrary.FileSizeException;
062
063 import java.io.InputStream;
064
065 import java.util.Calendar;
066 import java.util.HashMap;
067 import java.util.Map;
068
069 import javax.portlet.ActionRequest;
070 import javax.portlet.ActionResponse;
071 import javax.portlet.PortletConfig;
072 import javax.portlet.PortletRequest;
073 import javax.portlet.RenderRequest;
074 import javax.portlet.RenderResponse;
075 import javax.portlet.WindowState;
076
077 import javax.servlet.http.HttpServletResponse;
078
079 import org.apache.struts.action.ActionForm;
080 import org.apache.struts.action.ActionForward;
081 import org.apache.struts.action.ActionMapping;
082
083
091 public class EditEntryAction extends PortletAction {
092
093 @Override
094 public void processAction(
095 ActionMapping actionMapping, ActionForm actionForm,
096 PortletConfig portletConfig, ActionRequest actionRequest,
097 ActionResponse actionResponse)
098 throws Exception {
099
100 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
101
102 try {
103 BlogsEntry entry = null;
104 String oldUrlTitle = StringPool.BLANK;
105
106 UploadException uploadException =
107 (UploadException)actionRequest.getAttribute(
108 WebKeys.UPLOAD_EXCEPTION);
109
110 if (uploadException != null) {
111 if (uploadException.isExceededLiferayFileItemSizeLimit()) {
112 throw new LiferayFileItemException();
113 }
114 else if (uploadException.isExceededSizeLimit()) {
115 throw new FileSizeException(uploadException.getCause());
116 }
117
118 throw new PortalException(uploadException.getCause());
119 }
120 else if (cmd.equals(Constants.ADD) ||
121 cmd.equals(Constants.UPDATE)) {
122
123 Object[] returnValue = updateEntry(actionRequest);
124
125 entry = (BlogsEntry)returnValue[0];
126 oldUrlTitle = ((String)returnValue[1]);
127 }
128 else if (cmd.equals(Constants.DELETE)) {
129 deleteEntries(actionRequest, false);
130 }
131 else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
132 deleteEntries(actionRequest, true);
133 }
134 else if (cmd.equals(Constants.SUBSCRIBE)) {
135 subscribe(actionRequest);
136 }
137 else if (cmd.equals(Constants.RESTORE)) {
138 restoreEntries(actionRequest);
139 }
140 else if (cmd.equals(Constants.UNSUBSCRIBE)) {
141 unsubscribe(actionRequest);
142 }
143 else if (cmd.equals(Constants.UPDATE_CONTENT)) {
144 updateContent(actionRequest, actionResponse);
145
146 return;
147 }
148
149 String redirect = ParamUtil.getString(actionRequest, "redirect");
150 boolean updateRedirect = false;
151
152 String portletId = HttpUtil.getParameter(redirect, "p_p_id", false);
153
154 if (Validator.isNotNull(oldUrlTitle)) {
155 String oldRedirectParam =
156 PortalUtil.getPortletNamespace(portletId) + "redirect";
157
158 String oldRedirect = HttpUtil.getParameter(
159 redirect, oldRedirectParam, false);
160
161 if (Validator.isNotNull(oldRedirect)) {
162 String newRedirect = HttpUtil.decodeURL(oldRedirect);
163
164 newRedirect = StringUtil.replace(
165 newRedirect, oldUrlTitle, entry.getUrlTitle());
166 newRedirect = StringUtil.replace(
167 newRedirect, oldRedirectParam, "redirect");
168
169 redirect = StringUtil.replace(
170 redirect, oldRedirect, newRedirect);
171 }
172 else if (redirect.endsWith("/blogs/" + oldUrlTitle) ||
173 redirect.contains("/blogs/" + oldUrlTitle + "?") ||
174 redirect.contains("/blog/" + oldUrlTitle + "?")) {
175
176 redirect = StringUtil.replace(
177 redirect, oldUrlTitle, entry.getUrlTitle());
178 }
179
180 updateRedirect = true;
181 }
182
183 int workflowAction = ParamUtil.getInteger(
184 actionRequest, "workflowAction",
185 WorkflowConstants.ACTION_SAVE_DRAFT);
186
187 boolean ajax = ParamUtil.getBoolean(actionRequest, "ajax");
188
189 if (ajax) {
190 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
191
192 jsonObject.put("entryId", entry.getEntryId());
193 jsonObject.put("redirect", redirect);
194 jsonObject.put("updateRedirect", updateRedirect);
195
196 writeJSON(actionRequest, actionResponse, jsonObject);
197
198 return;
199 }
200
201 if ((entry != null) &&
202 (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
203
204 redirect = getSaveAndContinueRedirect(
205 portletConfig, actionRequest, entry, redirect);
206
207 sendRedirect(actionRequest, actionResponse, redirect);
208 }
209 else {
210 WindowState windowState = actionRequest.getWindowState();
211
212 if (!windowState.equals(LiferayWindowState.POP_UP)) {
213 sendRedirect(actionRequest, actionResponse, redirect);
214 }
215 else {
216 redirect = PortalUtil.escapeRedirect(redirect);
217
218 if (Validator.isNotNull(redirect)) {
219 if (cmd.equals(Constants.ADD) && (entry != null)) {
220 String namespace = PortalUtil.getPortletNamespace(
221 portletId);
222
223 redirect = HttpUtil.addParameter(
224 redirect, namespace + "className",
225 BlogsEntry.class.getName());
226 redirect = HttpUtil.addParameter(
227 redirect, namespace + "classPK",
228 entry.getEntryId());
229 }
230
231 actionResponse.sendRedirect(redirect);
232 }
233 }
234 }
235 }
236 catch (Exception e) {
237 if (e instanceof NoSuchEntryException ||
238 e instanceof PrincipalException) {
239
240 SessionErrors.add(actionRequest, e.getClass());
241
242 setForward(actionRequest, "portlet.blogs.error");
243 }
244 else if (e instanceof EntryContentException ||
245 e instanceof EntryDisplayDateException ||
246 e instanceof EntrySmallImageNameException ||
247 e instanceof EntrySmallImageSizeException ||
248 e instanceof EntryTitleException ||
249 e instanceof LiferayFileItemException ||
250 e instanceof FileSizeException ||
251 e instanceof SanitizerException) {
252
253 SessionErrors.add(actionRequest, e.getClass());
254 }
255 else if (e instanceof AssetCategoryException ||
256 e instanceof AssetTagException) {
257
258 SessionErrors.add(actionRequest, e.getClass(), e);
259 }
260 else {
261 Throwable cause = e.getCause();
262
263 if (cause instanceof SanitizerException) {
264 SessionErrors.add(actionRequest, SanitizerException.class);
265 }
266 else {
267 throw e;
268 }
269 }
270 }
271 }
272
273 @Override
274 public ActionForward render(
275 ActionMapping actionMapping, ActionForm actionForm,
276 PortletConfig portletConfig, RenderRequest renderRequest,
277 RenderResponse renderResponse)
278 throws Exception {
279
280 try {
281 ActionUtil.getEntry(renderRequest);
282
283 if (PropsValues.BLOGS_PINGBACK_ENABLED) {
284 BlogsEntry entry = (BlogsEntry)renderRequest.getAttribute(
285 WebKeys.BLOGS_ENTRY);
286
287 if ((entry != null) && entry.isAllowPingbacks()) {
288 HttpServletResponse response =
289 PortalUtil.getHttpServletResponse(renderResponse);
290
291 response.addHeader(
292 "X-Pingback",
293 PortalUtil.getPortalURL(renderRequest) +
294 "/xmlrpc/pingback");
295 }
296 }
297 }
298 catch (Exception e) {
299 if (e instanceof NoSuchEntryException ||
300 e instanceof PrincipalException) {
301
302 SessionErrors.add(renderRequest, e.getClass());
303
304 return actionMapping.findForward("portlet.blogs.error");
305 }
306 else {
307 throw e;
308 }
309 }
310
311 return actionMapping.findForward(
312 getForward(renderRequest, "portlet.blogs.edit_entry"));
313 }
314
315 protected void deleteEntries(
316 ActionRequest actionRequest, boolean moveToTrash)
317 throws Exception {
318
319 long[] deleteEntryIds = null;
320
321 long entryId = ParamUtil.getLong(actionRequest, "entryId");
322
323 if (entryId > 0) {
324 deleteEntryIds = new long[] {entryId};
325 }
326 else {
327 deleteEntryIds = StringUtil.split(
328 ParamUtil.getString(actionRequest, "deleteEntryIds"), 0L);
329 }
330
331 String deleteEntryTitle = null;
332
333 for (int i = 0; i < deleteEntryIds.length; i++) {
334 long deleteEntryId = deleteEntryIds[i];
335
336 if (moveToTrash) {
337 BlogsEntry entry = BlogsEntryServiceUtil.moveEntryToTrash(
338 deleteEntryId);
339
340 if (i == 0) {
341 deleteEntryTitle = entry.getTitle();
342 }
343 }
344 else {
345 BlogsEntryServiceUtil.deleteEntry(deleteEntryId);
346 }
347 }
348
349 if (moveToTrash && (deleteEntryIds.length > 0)) {
350 Map<String, String[]> data = new HashMap<String, String[]>();
351
352 data.put(
353 "deleteEntryClassName",
354 new String[] {BlogsEntry.class.getName()});
355
356 if (Validator.isNotNull(deleteEntryTitle)) {
357 data.put("deleteEntryTitle", new String[] {deleteEntryTitle});
358 }
359
360 data.put(
361 "restoreEntryIds", ArrayUtil.toStringArray(deleteEntryIds));
362
363 SessionMessages.add(
364 actionRequest,
365 PortalUtil.getPortletId(actionRequest) +
366 SessionMessages.KEY_SUFFIX_DELETE_SUCCESS_DATA, data);
367
368 hideDefaultSuccessMessage(actionRequest);
369 }
370 }
371
372 protected String getSaveAndContinueRedirect(
373 PortletConfig portletConfig, ActionRequest actionRequest,
374 BlogsEntry entry, String redirect)
375 throws Exception {
376
377 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
378 WebKeys.THEME_DISPLAY);
379
380 String backURL = ParamUtil.getString(actionRequest, "backURL");
381
382 boolean preview = ParamUtil.getBoolean(actionRequest, "preview");
383
384 LiferayPortletURL portletURL = PortletURLFactoryUtil.create(
385 actionRequest, portletConfig.getPortletName(),
386 themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
387
388 String portletName = portletConfig.getPortletName();
389
390 if (portletName.equals(PortletKeys.BLOGS_ADMIN)) {
391 portletURL.setParameter("struts_action", "/blogs_admin/edit_entry");
392 }
393 else {
394 portletURL.setParameter("struts_action", "/blogs/edit_entry");
395 }
396
397 portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
398 portletURL.setParameter("redirect", redirect, false);
399 portletURL.setParameter("backURL", backURL, false);
400 portletURL.setParameter(
401 "groupId", String.valueOf(entry.getGroupId()), false);
402 portletURL.setParameter(
403 "entryId", String.valueOf(entry.getEntryId()), false);
404 portletURL.setParameter("preview", String.valueOf(preview), false);
405 portletURL.setWindowState(actionRequest.getWindowState());
406
407 return portletURL.toString();
408 }
409
410 protected void restoreEntries(ActionRequest actionRequest)
411 throws PortalException, SystemException {
412
413 long[] restoreEntryIds = StringUtil.split(
414 ParamUtil.getString(actionRequest, "restoreEntryIds"), 0L);
415
416 for (long restoreEntryId : restoreEntryIds) {
417 BlogsEntryServiceUtil.restoreEntryFromTrash(restoreEntryId);
418 }
419 }
420
421 protected void subscribe(ActionRequest actionRequest) throws Exception {
422 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
423 WebKeys.THEME_DISPLAY);
424
425 BlogsEntryServiceUtil.subscribe(themeDisplay.getScopeGroupId());
426 }
427
428 protected void unsubscribe(ActionRequest actionRequest) throws Exception {
429 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
430 WebKeys.THEME_DISPLAY);
431
432 BlogsEntryServiceUtil.unsubscribe(themeDisplay.getScopeGroupId());
433 }
434
435 protected void updateContent(
436 ActionRequest actionRequest, ActionResponse actionResponse)
437 throws Exception {
438
439 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
440 WebKeys.THEME_DISPLAY);
441
442 long entryId = ParamUtil.getLong(actionRequest, "entryId");
443
444 BlogsEntry entry = BlogsEntryLocalServiceUtil.getEntry(entryId);
445
446 String content = ParamUtil.getString(actionRequest, "content");
447
448 Calendar displayDateCal = CalendarFactoryUtil.getCalendar(
449 themeDisplay.getTimeZone());
450
451 displayDateCal.setTime(entry.getDisplayDate());
452
453 int displayDateMonth = displayDateCal.get(Calendar.MONTH);
454 int displayDateDay = displayDateCal.get(Calendar.DATE);
455 int displayDateYear = displayDateCal.get(Calendar.YEAR);
456 int displayDateHour = displayDateCal.get(Calendar.HOUR);
457 int displayDateMinute = displayDateCal.get(Calendar.MINUTE);
458
459 if (displayDateCal.get(Calendar.AM_PM) == Calendar.PM) {
460 displayDateHour += 12;
461 }
462
463 ServiceContext serviceContext = ServiceContextFactory.getInstance(
464 actionRequest);
465
466 serviceContext.setCommand(Constants.UPDATE);
467
468 try {
469 BlogsEntryServiceUtil.updateEntry(
470 entryId, entry.getTitle(), entry.getDescription(), content,
471 displayDateMonth, displayDateDay, displayDateYear,
472 displayDateHour, displayDateMinute, entry.getAllowPingbacks(),
473 entry.getAllowTrackbacks(), null, entry.getSmallImage(),
474 entry.getSmallImageURL(), null, null, serviceContext);
475
476 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
477
478 jsonObject.put("success", Boolean.TRUE);
479
480 writeJSON(actionRequest, actionResponse, jsonObject);
481 }
482 catch (Exception e) {
483 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
484
485 jsonObject.put("success", Boolean.FALSE);
486
487 jsonObject.putException(e);
488
489 writeJSON(actionRequest, actionResponse, jsonObject);
490 }
491 }
492
493 protected Object[] updateEntry(ActionRequest actionRequest)
494 throws Exception {
495
496 long entryId = ParamUtil.getLong(actionRequest, "entryId");
497
498 String title = ParamUtil.getString(actionRequest, "title");
499 String description = ParamUtil.getString(actionRequest, "description");
500 String content = ParamUtil.getString(actionRequest, "content");
501
502 int displayDateMonth = ParamUtil.getInteger(
503 actionRequest, "displayDateMonth");
504 int displayDateDay = ParamUtil.getInteger(
505 actionRequest, "displayDateDay");
506 int displayDateYear = ParamUtil.getInteger(
507 actionRequest, "displayDateYear");
508 int displayDateHour = ParamUtil.getInteger(
509 actionRequest, "displayDateHour");
510 int displayDateMinute = ParamUtil.getInteger(
511 actionRequest, "displayDateMinute");
512 int displayDateAmPm = ParamUtil.getInteger(
513 actionRequest, "displayDateAmPm");
514
515 if (displayDateAmPm == Calendar.PM) {
516 displayDateHour += 12;
517 }
518
519 boolean allowPingbacks = ParamUtil.getBoolean(
520 actionRequest, "allowPingbacks");
521 boolean allowTrackbacks = ParamUtil.getBoolean(
522 actionRequest, "allowTrackbacks");
523 String[] trackbacks = StringUtil.split(
524 ParamUtil.getString(actionRequest, "trackbacks"));
525
526 boolean smallImage = false;
527 String smallImageURL = null;
528 String smallImageFileName = null;
529 InputStream smallImageInputStream = null;
530
531 BlogsEntry entry = null;
532 String oldUrlTitle = null;
533
534 try {
535 boolean ajax = ParamUtil.getBoolean(actionRequest, "ajax");
536
537 if (!ajax) {
538 smallImage = ParamUtil.getBoolean(actionRequest, "smallImage");
539 smallImageURL = ParamUtil.getString(
540 actionRequest, "smallImageURL");
541
542 if (smallImage && Validator.isNull(smallImageURL)) {
543 UploadPortletRequest uploadPortletRequest =
544 PortalUtil.getUploadPortletRequest(actionRequest);
545
546 smallImageFileName = uploadPortletRequest.getFileName(
547 "smallFile");
548 smallImageInputStream =
549 uploadPortletRequest.getFileAsStream("smallFile");
550 }
551 }
552
553 ServiceContext serviceContext = ServiceContextFactory.getInstance(
554 BlogsEntry.class.getName(), actionRequest);
555
556 entry = null;
557 oldUrlTitle = StringPool.BLANK;
558
559 if (entryId <= 0) {
560
561
562
563 entry = BlogsEntryServiceUtil.addEntry(
564 title, description, content, displayDateMonth,
565 displayDateDay, displayDateYear, displayDateHour,
566 displayDateMinute, allowPingbacks, allowTrackbacks,
567 trackbacks, smallImage, smallImageURL, smallImageFileName,
568 smallImageInputStream, serviceContext);
569
570 AssetPublisherUtil.addAndStoreSelection(
571 actionRequest, BlogsEntry.class.getName(),
572 entry.getEntryId(), -1);
573 }
574 else {
575
576
577
578 entry = BlogsEntryLocalServiceUtil.getEntry(entryId);
579
580 String tempOldUrlTitle = entry.getUrlTitle();
581
582 entry = BlogsEntryServiceUtil.updateEntry(
583 entryId, title, description, content, displayDateMonth,
584 displayDateDay, displayDateYear, displayDateHour,
585 displayDateMinute, allowPingbacks, allowTrackbacks,
586 trackbacks, smallImage, smallImageURL, smallImageFileName,
587 smallImageInputStream, serviceContext);
588
589 if (!tempOldUrlTitle.equals(entry.getUrlTitle())) {
590 oldUrlTitle = tempOldUrlTitle;
591 }
592
593 AssetPublisherUtil.addAndStoreSelection(
594 actionRequest, BlogsEntry.class.getName(),
595 entry.getEntryId(), -1);
596 }
597 }
598 finally {
599 StreamUtil.cleanUp(smallImageInputStream);
600 }
601
602 return new Object[] {entry, oldUrlTitle};
603 }
604
605 }