001
014
015 package com.liferay.portlet.messageboards.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.json.JSONFactoryUtil;
021 import com.liferay.portal.kernel.json.JSONObject;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.notifications.UserNotificationDefinition;
025 import com.liferay.portal.kernel.parsers.bbcode.BBCodeTranslatorUtil;
026 import com.liferay.portal.kernel.repository.model.FileEntry;
027 import com.liferay.portal.kernel.repository.model.Folder;
028 import com.liferay.portal.kernel.sanitizer.Sanitizer;
029 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
030 import com.liferay.portal.kernel.search.Indexable;
031 import com.liferay.portal.kernel.search.IndexableType;
032 import com.liferay.portal.kernel.search.Indexer;
033 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
034 import com.liferay.portal.kernel.settings.LocalizedValuesMap;
035 import com.liferay.portal.kernel.systemevent.SystemEvent;
036 import com.liferay.portal.kernel.util.Constants;
037 import com.liferay.portal.kernel.util.ContentTypes;
038 import com.liferay.portal.kernel.util.GetterUtil;
039 import com.liferay.portal.kernel.util.ListUtil;
040 import com.liferay.portal.kernel.util.LocalizationUtil;
041 import com.liferay.portal.kernel.util.ObjectValuePair;
042 import com.liferay.portal.kernel.util.OrderByComparator;
043 import com.liferay.portal.kernel.util.ParamUtil;
044 import com.liferay.portal.kernel.util.PropsKeys;
045 import com.liferay.portal.kernel.util.StringPool;
046 import com.liferay.portal.kernel.util.StringUtil;
047 import com.liferay.portal.kernel.util.Validator;
048 import com.liferay.portal.kernel.util.WebKeys;
049 import com.liferay.portal.kernel.workflow.WorkflowConstants;
050 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
051 import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
052 import com.liferay.portal.model.Company;
053 import com.liferay.portal.model.Group;
054 import com.liferay.portal.model.ModelHintsUtil;
055 import com.liferay.portal.model.ResourceConstants;
056 import com.liferay.portal.model.SystemEventConstants;
057 import com.liferay.portal.model.User;
058 import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
059 import com.liferay.portal.security.auth.PrincipalException;
060 import com.liferay.portal.service.ServiceContext;
061 import com.liferay.portal.theme.ThemeDisplay;
062 import com.liferay.portal.util.LayoutURLUtil;
063 import com.liferay.portal.util.Portal;
064 import com.liferay.portal.util.PortalUtil;
065 import com.liferay.portal.util.PortletKeys;
066 import com.liferay.portal.util.PrefsPropsUtil;
067 import com.liferay.portal.util.PropsValues;
068 import com.liferay.portal.util.SubscriptionSender;
069 import com.liferay.portlet.PortletURLFactoryUtil;
070 import com.liferay.portlet.asset.model.AssetEntry;
071 import com.liferay.portlet.asset.model.AssetLinkConstants;
072 import com.liferay.portlet.blogs.model.BlogsEntry;
073 import com.liferay.portlet.blogs.util.LinkbackProducerUtil;
074 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
075 import com.liferay.portlet.messageboards.DiscussionMaxCommentsException;
076 import com.liferay.portlet.messageboards.MBGroupServiceSettings;
077 import com.liferay.portlet.messageboards.MessageBodyException;
078 import com.liferay.portlet.messageboards.MessageSubjectException;
079 import com.liferay.portlet.messageboards.NoSuchThreadException;
080 import com.liferay.portlet.messageboards.RequiredMessageException;
081 import com.liferay.portlet.messageboards.model.MBCategory;
082 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
083 import com.liferay.portlet.messageboards.model.MBDiscussion;
084 import com.liferay.portlet.messageboards.model.MBMessage;
085 import com.liferay.portlet.messageboards.model.MBMessageConstants;
086 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
087 import com.liferay.portlet.messageboards.model.MBThread;
088 import com.liferay.portlet.messageboards.model.MBThreadConstants;
089 import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
090 import com.liferay.portlet.messageboards.model.impl.MBMessageDisplayImpl;
091 import com.liferay.portlet.messageboards.service.base.MBMessageLocalServiceBaseImpl;
092 import com.liferay.portlet.messageboards.service.permission.MBPermission;
093 import com.liferay.portlet.messageboards.social.MBActivityKeys;
094 import com.liferay.portlet.messageboards.util.MBSubscriptionSender;
095 import com.liferay.portlet.messageboards.util.MBUtil;
096 import com.liferay.portlet.messageboards.util.MailingListThreadLocal;
097 import com.liferay.portlet.messageboards.util.comparator.MessageCreateDateComparator;
098 import com.liferay.portlet.messageboards.util.comparator.MessageThreadComparator;
099 import com.liferay.portlet.messageboards.util.comparator.ThreadLastPostDateComparator;
100 import com.liferay.portlet.social.model.SocialActivity;
101 import com.liferay.portlet.social.model.SocialActivityConstants;
102 import com.liferay.portlet.trash.util.TrashUtil;
103 import com.liferay.util.SerializableUtil;
104
105 import java.io.File;
106 import java.io.FileInputStream;
107 import java.io.FileNotFoundException;
108 import java.io.InputStream;
109 import java.io.Serializable;
110
111 import java.util.ArrayList;
112 import java.util.Collections;
113 import java.util.Comparator;
114 import java.util.Date;
115 import java.util.HashMap;
116 import java.util.List;
117 import java.util.Map;
118
119 import javax.portlet.PortletRequest;
120 import javax.portlet.PortletURL;
121
122 import javax.servlet.http.HttpServletRequest;
123
124 import net.htmlparser.jericho.Source;
125 import net.htmlparser.jericho.StartTag;
126
127
135 public class MBMessageLocalServiceImpl extends MBMessageLocalServiceBaseImpl {
136
137 @Override
138 public MBMessage addDiscussionMessage(
139 long userId, String userName, long groupId, String className,
140 long classPK, int workflowAction)
141 throws PortalException {
142
143 long threadId = 0;
144 long parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
145 String subject = String.valueOf(classPK);
146 String body = subject;
147
148 ServiceContext serviceContext = new ServiceContext();
149
150 serviceContext.setWorkflowAction(workflowAction);
151
152 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
153
154 WorkflowThreadLocal.setEnabled(false);
155
156 try {
157 return addDiscussionMessage(
158 userId, userName, groupId, className, classPK, threadId,
159 parentMessageId, subject, body, serviceContext);
160 }
161 finally {
162 WorkflowThreadLocal.setEnabled(workflowEnabled);
163 }
164 }
165
166 @Override
167 public MBMessage addDiscussionMessage(
168 long userId, String userName, long groupId, String className,
169 long classPK, long threadId, long parentMessageId, String subject,
170 String body, ServiceContext serviceContext)
171 throws PortalException {
172
173
174
175 validateDiscussionMaxComments(className, classPK);
176
177 long categoryId = MBCategoryConstants.DISCUSSION_CATEGORY_ID;
178
179 if (Validator.isNull(subject)) {
180 if (Validator.isNotNull(body)) {
181 int pos = Math.min(body.length(), 50);
182
183 subject = body.substring(0, pos) + "...";
184 }
185 else {
186 throw new MessageBodyException();
187 }
188 }
189
190 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
191 Collections.emptyList();
192 boolean anonymous = false;
193 double priority = 0.0;
194 boolean allowPingbacks = false;
195
196 serviceContext.setAddGroupPermissions(true);
197 serviceContext.setAddGuestPermissions(true);
198 serviceContext.setAttribute("className", className);
199 serviceContext.setAttribute("classPK", String.valueOf(classPK));
200
201 MBMessage message = addMessage(
202 userId, userName, groupId, categoryId, threadId, parentMessageId,
203 subject, body, PropsValues.DISCUSSION_COMMENTS_FORMAT,
204 inputStreamOVPs, anonymous, priority, allowPingbacks,
205 serviceContext);
206
207
208
209 if (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
210 long classNameId = classNameLocalService.getClassNameId(className);
211
212 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
213 classNameId, classPK);
214
215 if (discussion == null) {
216 mbDiscussionLocalService.addDiscussion(
217 userId, groupId, classNameId, classPK,
218 message.getThreadId(), serviceContext);
219 }
220 }
221
222 return message;
223 }
224
225 @Override
226 public MBMessage addMessage(
227 long userId, String userName, long groupId, long categoryId,
228 long threadId, long parentMessageId, String subject, String body,
229 String format,
230 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
231 boolean anonymous, double priority, boolean allowPingbacks,
232 ServiceContext serviceContext)
233 throws PortalException {
234
235
236
237 User user = userPersistence.findByPrimaryKey(userId);
238 userName = user.isDefaultUser() ? userName : user.getFullName();
239 subject = ModelHintsUtil.trimString(
240 MBMessage.class.getName(), "subject", subject);
241
242 MBGroupServiceSettings mbGroupServiceSettings =
243 MBGroupServiceSettings.getInstance(groupId);
244
245 if (mbGroupServiceSettings != null) {
246 if (!mbGroupServiceSettings.isAllowAnonymousPosting()) {
247 if (anonymous || user.isDefaultUser()) {
248 throw new PrincipalException();
249 }
250 }
251 }
252
253 if (user.isDefaultUser()) {
254 anonymous = true;
255 }
256
257 Date now = new Date();
258
259 long messageId = counterLocalService.increment();
260
261 Map<String, Object> options = new HashMap<>();
262
263 boolean discussion = false;
264
265 if (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
266 discussion = true;
267 }
268
269 options.put("discussion", discussion);
270
271 body = SanitizerUtil.sanitize(
272 user.getCompanyId(), groupId, userId, MBMessage.class.getName(),
273 messageId, "text/" + format, Sanitizer.MODE_ALL, body, options);
274
275 validate(subject, body);
276
277 subject = getSubject(subject, body);
278 body = getBody(subject, body);
279
280 MBMessage message = mbMessagePersistence.create(messageId);
281
282 message.setUuid(serviceContext.getUuid());
283 message.setGroupId(groupId);
284 message.setCompanyId(user.getCompanyId());
285 message.setUserId(user.getUserId());
286 message.setUserName(userName);
287 message.setCreateDate(serviceContext.getCreateDate(now));
288 message.setModifiedDate(serviceContext.getModifiedDate(now));
289
290 if (threadId > 0) {
291 message.setThreadId(threadId);
292 }
293
294 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
295 message.setPriority(priority);
296 }
297
298 message.setAllowPingbacks(allowPingbacks);
299 message.setStatus(WorkflowConstants.STATUS_DRAFT);
300 message.setStatusByUserId(user.getUserId());
301 message.setStatusByUserName(userName);
302 message.setStatusDate(serviceContext.getModifiedDate(now));
303
304
305
306 if (parentMessageId != MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
307 MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
308 parentMessageId);
309
310 if (parentMessage == null) {
311 parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
312 }
313 }
314
315 MBThread thread = null;
316
317 if (threadId > 0) {
318 thread = mbThreadPersistence.fetchByPrimaryKey(threadId);
319 }
320
321 if (thread == null) {
322 if (parentMessageId ==
323 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
324
325 thread = mbThreadLocalService.addThread(
326 categoryId, message, serviceContext);
327 }
328 else {
329 throw new NoSuchThreadException("{threadId=" + threadId + "}");
330 }
331 }
332
333 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
334 (thread.getPriority() != priority)) {
335
336 thread.setPriority(priority);
337
338 mbThreadPersistence.update(thread);
339
340 updatePriorities(thread.getThreadId(), priority);
341 }
342
343
344
345 message.setCategoryId(categoryId);
346 message.setThreadId(thread.getThreadId());
347 message.setRootMessageId(thread.getRootMessageId());
348 message.setParentMessageId(parentMessageId);
349 message.setSubject(subject);
350 message.setBody(body);
351 message.setFormat(format);
352 message.setAnonymous(anonymous);
353
354 if (message.isDiscussion()) {
355 long classNameId = classNameLocalService.getClassNameId(
356 (String)serviceContext.getAttribute("className"));
357 long classPK = ParamUtil.getLong(serviceContext, "classPK");
358
359 message.setClassNameId(classNameId);
360 message.setClassPK(classPK);
361 }
362
363 message.setExpandoBridgeAttributes(serviceContext);
364
365 mbMessagePersistence.update(message);
366
367
368
369 if (ListUtil.isNotEmpty(inputStreamOVPs)) {
370 Folder folder = message.addAttachmentsFolder();
371
372 PortletFileRepositoryUtil.addPortletFileEntries(
373 message.getGroupId(), userId, MBMessage.class.getName(),
374 message.getMessageId(), PortletKeys.MESSAGE_BOARDS,
375 folder.getFolderId(), inputStreamOVPs);
376 }
377
378
379
380 if ((parentMessageId !=
381 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) &&
382 GetterUtil.getBoolean(
383 serviceContext.getAttribute("propagatePermissions"))) {
384
385 MBUtil.propagatePermissions(
386 message.getCompanyId(), groupId, parentMessageId,
387 serviceContext);
388 }
389
390 if (!message.isDiscussion()) {
391 if (user.isDefaultUser()) {
392 addMessageResources(message, true, true);
393 }
394 else if (serviceContext.isAddGroupPermissions() ||
395 serviceContext.isAddGuestPermissions()) {
396
397 addMessageResources(
398 message, serviceContext.isAddGroupPermissions(),
399 serviceContext.isAddGuestPermissions());
400 }
401 else {
402 addMessageResources(
403 message, serviceContext.getGroupPermissions(),
404 serviceContext.getGuestPermissions());
405 }
406 }
407
408
409
410 updateAsset(
411 userId, message, serviceContext.getAssetCategoryIds(),
412 serviceContext.getAssetTagNames(),
413 serviceContext.getAssetLinkEntryIds(),
414 serviceContext.isAssetEntryVisible());
415
416
417
418 startWorkflowInstance(userId, message, serviceContext);
419
420 return message;
421 }
422
423 @Override
424 public MBMessage addMessage(
425 long userId, String userName, long groupId, long categoryId,
426 String subject, String body, ServiceContext serviceContext)
427 throws PortalException {
428
429 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
430 Collections.emptyList();
431
432 return addMessage(
433 userId, userName, groupId, categoryId, 0, 0, subject, body,
434 MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false, 0.0,
435 false, serviceContext);
436 }
437
438 @Override
439 public MBMessage addMessage(
440 long userId, String userName, long groupId, long categoryId,
441 String subject, String body, String format,
442 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
443 boolean anonymous, double priority, boolean allowPingbacks,
444 ServiceContext serviceContext)
445 throws PortalException {
446
447 long threadId = 0;
448 long parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
449
450 return addMessage(
451 userId, userName, groupId, categoryId, threadId, parentMessageId,
452 subject, body, format, inputStreamOVPs, anonymous, priority,
453 allowPingbacks, serviceContext);
454 }
455
456 @Override
457 public MBMessage addMessage(
458 long userId, String userName, long groupId, long categoryId,
459 String subject, String body, String format, String fileName,
460 File file, boolean anonymous, double priority,
461 boolean allowPingbacks, ServiceContext serviceContext)
462 throws FileNotFoundException, PortalException {
463
464 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
465 new ArrayList<>(1);
466
467 InputStream inputStream = new FileInputStream(file);
468
469 ObjectValuePair<String, InputStream> inputStreamOVP =
470 new ObjectValuePair<>(fileName, inputStream);
471
472 inputStreamOVPs.add(inputStreamOVP);
473
474 return addMessage(
475 userId, userName, groupId, categoryId, 0, 0, subject, body, format,
476 inputStreamOVPs, anonymous, priority, allowPingbacks,
477 serviceContext);
478 }
479
480
484 @Deprecated
485 @Override
486 public MBMessage addMessage(
487 long userId, String userName, long categoryId, String subject,
488 String body, ServiceContext serviceContext)
489 throws PortalException {
490
491 long groupId = serviceContext.getScopeGroupId();
492
493 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
494 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
495 categoryId);
496
497 groupId = category.getGroupId();
498 }
499
500 return addMessage(
501 userId, userName, groupId, categoryId, subject, body,
502 serviceContext);
503 }
504
505 @Override
506 public void addMessageAttachment(
507 long userId, long messageId, String fileName, File file,
508 String mimeType)
509 throws PortalException {
510
511 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
512
513 Folder folder = message.addAttachmentsFolder();
514
515 PortletFileRepositoryUtil.addPortletFileEntry(
516 message.getGroupId(), userId, MBMessage.class.getName(),
517 message.getMessageId(), PortletKeys.MESSAGE_BOARDS,
518 folder.getFolderId(), file, fileName, mimeType, true);
519 }
520
521 @Override
522 public void addMessageResources(
523 long messageId, boolean addGroupPermissions,
524 boolean addGuestPermissions)
525 throws PortalException {
526
527 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
528
529 addMessageResources(message, addGroupPermissions, addGuestPermissions);
530 }
531
532 @Override
533 public void addMessageResources(
534 long messageId, String[] groupPermissions,
535 String[] guestPermissions)
536 throws PortalException {
537
538 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
539
540 addMessageResources(message, groupPermissions, guestPermissions);
541 }
542
543 @Override
544 public void addMessageResources(
545 MBMessage message, boolean addGroupPermissions,
546 boolean addGuestPermissions)
547 throws PortalException {
548
549 resourceLocalService.addResources(
550 message.getCompanyId(), message.getGroupId(), message.getUserId(),
551 MBMessage.class.getName(), message.getMessageId(), false,
552 addGroupPermissions, addGuestPermissions);
553 }
554
555 @Override
556 public void addMessageResources(
557 MBMessage message, String[] groupPermissions,
558 String[] guestPermissions)
559 throws PortalException {
560
561 resourceLocalService.addModelResources(
562 message.getCompanyId(), message.getGroupId(), message.getUserId(),
563 MBMessage.class.getName(), message.getMessageId(), groupPermissions,
564 guestPermissions);
565 }
566
567 @Indexable(type = IndexableType.DELETE)
568 @Override
569 public MBMessage deleteDiscussionMessage(long messageId)
570 throws PortalException {
571
572 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
573
574 deleteDiscussionSocialActivities(BlogsEntry.class.getName(), message);
575
576 return mbMessageLocalService.deleteMessage(message);
577 }
578
579 @Override
580 public void deleteDiscussionMessages(String className, long classPK)
581 throws PortalException {
582
583 long classNameId = classNameLocalService.getClassNameId(className);
584
585 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
586 classNameId, classPK);
587
588 if (discussion == null) {
589 if (_log.isInfoEnabled()) {
590 _log.info(
591 "Unable to delete discussion message for class name " +
592 className + " and class PK " + classPK +
593 " because it does not exist");
594 }
595
596 return;
597 }
598
599 List<MBMessage> messages = mbMessagePersistence.findByT_P(
600 discussion.getThreadId(),
601 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, 0, 1);
602
603 if (!messages.isEmpty()) {
604 MBMessage message = messages.get(0);
605
606 deleteDiscussionSocialActivities(
607 BlogsEntry.class.getName(), message);
608
609 mbThreadLocalService.deleteThread(message.getThreadId());
610 }
611
612 mbDiscussionPersistence.remove(discussion);
613 }
614
615 @Indexable(type = IndexableType.DELETE)
616 @Override
617 public MBMessage deleteMessage(long messageId) throws PortalException {
618 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
619
620 return mbMessageLocalService.deleteMessage(message);
621 }
622
623 @Indexable(type = IndexableType.DELETE)
624 @Override
625 @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
626 public MBMessage deleteMessage(MBMessage message) throws PortalException {
627
628
629
630 long folderId = message.getAttachmentsFolderId();
631
632 if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
633 PortletFileRepositoryUtil.deletePortletFolder(folderId);
634 }
635
636
637
638 int count = mbMessagePersistence.countByThreadId(message.getThreadId());
639
640 if (count == 1) {
641
642
643
644 long threadAttachmentsFolderId =
645 message.getThreadAttachmentsFolderId();
646
647 if (threadAttachmentsFolderId !=
648 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
649
650 PortletFileRepositoryUtil.deletePortletFolder(
651 threadAttachmentsFolderId);
652 }
653
654
655
656 subscriptionLocalService.deleteSubscriptions(
657 message.getCompanyId(), MBThread.class.getName(),
658 message.getThreadId());
659
660
661
662 MBThread thread = mbThreadPersistence.findByPrimaryKey(
663 message.getThreadId());
664
665 mbThreadPersistence.remove(thread);
666
667
668
669 if ((message.getCategoryId() !=
670 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
671 (message.getCategoryId() !=
672 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
673
674 MBUtil.updateCategoryStatistics(
675 message.getCompanyId(), message.getCategoryId());
676 }
677
678
679
680 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
681 MBThread.class);
682
683 indexer.delete(thread);
684 }
685 else {
686 MBThread thread = mbThreadPersistence.findByPrimaryKey(
687 message.getThreadId());
688
689
690
691 if (thread.getRootMessageId() == message.getMessageId()) {
692 List<MBMessage> childrenMessages =
693 mbMessagePersistence.findByT_P(
694 message.getThreadId(), message.getMessageId());
695
696 if (childrenMessages.size() > 1) {
697 throw new RequiredMessageException(
698 String.valueOf(message.getMessageId()));
699 }
700 else if (childrenMessages.size() == 1) {
701 MBMessage childMessage = childrenMessages.get(0);
702
703 childMessage.setRootMessageId(childMessage.getMessageId());
704 childMessage.setParentMessageId(
705 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
706
707 mbMessagePersistence.update(childMessage);
708
709 List<MBMessage> repliesMessages =
710 mbMessagePersistence.findByThreadReplies(
711 message.getThreadId());
712
713 for (MBMessage repliesMessage : repliesMessages) {
714 repliesMessage.setRootMessageId(
715 childMessage.getMessageId());
716
717 mbMessagePersistence.update(repliesMessage);
718 }
719
720 thread.setRootMessageId(childMessage.getMessageId());
721 thread.setRootMessageUserId(childMessage.getUserId());
722
723 mbThreadPersistence.update(thread);
724 }
725 }
726
727
728
729 else {
730 List<MBMessage> childrenMessages =
731 mbMessagePersistence.findByT_P(
732 message.getThreadId(), message.getMessageId());
733
734
735
736 if (!childrenMessages.isEmpty()) {
737 for (MBMessage childMessage : childrenMessages) {
738 childMessage.setParentMessageId(
739 message.getParentMessageId());
740
741 mbMessagePersistence.update(childMessage);
742 }
743 }
744 else if (message.getStatus() ==
745 WorkflowConstants.STATUS_APPROVED) {
746
747 MessageCreateDateComparator comparator =
748 new MessageCreateDateComparator(true);
749
750 MBMessage[] prevAndNextMessages =
751 mbMessagePersistence.findByT_S_PrevAndNext(
752 message.getMessageId(), thread.getThreadId(),
753 WorkflowConstants.STATUS_APPROVED, comparator);
754
755 if (prevAndNextMessages[2] == null) {
756 thread.setLastPostByUserId(
757 prevAndNextMessages[0].getUserId());
758 thread.setLastPostDate(
759 prevAndNextMessages[0].getModifiedDate());
760
761 mbThreadPersistence.update(thread);
762 }
763 }
764 }
765
766
767
768 if (message.isApproved()) {
769 MBUtil.updateThreadMessageCount(
770 thread.getCompanyId(), thread.getThreadId());
771 }
772
773
774
775 if ((message.getCategoryId() !=
776 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
777 (message.getCategoryId() !=
778 MBCategoryConstants.DISCUSSION_CATEGORY_ID) &&
779 !message.isDraft()) {
780
781 MBUtil.updateCategoryMessageCount(
782 message.getCompanyId(), message.getCategoryId());
783 }
784
785
786
787 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
788 MBThread.class);
789
790 indexer.reindex(thread);
791 }
792
793
794
795 assetEntryLocalService.deleteEntry(
796 message.getWorkflowClassName(), message.getMessageId());
797
798
799
800 expandoRowLocalService.deleteRows(message.getMessageId());
801
802
803
804 ratingsStatsLocalService.deleteStats(
805 message.getWorkflowClassName(), message.getMessageId());
806
807
808
809 if (!message.isDiscussion()) {
810 resourceLocalService.deleteResource(
811 message.getCompanyId(), message.getWorkflowClassName(),
812 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
813 }
814
815
816
817 mbMessagePersistence.remove(message);
818
819
820
821 if (!message.isDiscussion()) {
822 mbStatsUserLocalService.updateStatsUser(
823 message.getGroupId(), message.getUserId());
824 }
825
826
827
828 workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
829 message.getCompanyId(), message.getGroupId(),
830 message.getWorkflowClassName(), message.getMessageId());
831
832 return message;
833 }
834
835 @Override
836 public void deleteMessageAttachment(long messageId, String fileName)
837 throws PortalException {
838
839 MBMessage message = getMessage(messageId);
840
841 long folderId = message.getAttachmentsFolderId();
842
843 if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
844 return;
845 }
846
847 PortletFileRepositoryUtil.deletePortletFileEntry(
848 message.getGroupId(), folderId, fileName);
849 }
850
851 @Override
852 public void deleteMessageAttachments(long messageId)
853 throws PortalException {
854
855 MBMessage message = getMessage(messageId);
856
857 long folderId = message.getAttachmentsFolderId();
858
859 if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
860 return;
861 }
862
863 PortletFileRepositoryUtil.deletePortletFileEntries(
864 message.getGroupId(), folderId);
865 }
866
867 @Override
868 public void emptyMessageAttachments(long messageId) throws PortalException {
869 MBMessage message = getMessage(messageId);
870
871 long folderId = message.getAttachmentsFolderId();
872
873 if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
874 return;
875 }
876
877 PortletFileRepositoryUtil.deletePortletFileEntries(
878 message.getGroupId(), folderId, WorkflowConstants.STATUS_IN_TRASH);
879 }
880
881 @Override
882 public List<MBMessage> getCategoryMessages(
883 long groupId, long categoryId, int status, int start, int end) {
884
885 if (status == WorkflowConstants.STATUS_ANY) {
886 return mbMessagePersistence.findByG_C(
887 groupId, categoryId, start, end);
888 }
889 else {
890 return mbMessagePersistence.findByG_C_S(
891 groupId, categoryId, status, start, end);
892 }
893 }
894
895 @Override
896 public List<MBMessage> getCategoryMessages(
897 long groupId, long categoryId, int status, int start, int end,
898 OrderByComparator<MBMessage> obc) {
899
900 if (status == WorkflowConstants.STATUS_ANY) {
901 return mbMessagePersistence.findByG_C(
902 groupId, categoryId, start, end, obc);
903 }
904 else {
905 return mbMessagePersistence.findByG_C_S(
906 groupId, categoryId, status, start, end, obc);
907 }
908 }
909
910 @Override
911 public int getCategoryMessagesCount(
912 long groupId, long categoryId, int status) {
913
914 if (status == WorkflowConstants.STATUS_ANY) {
915 return mbMessagePersistence.countByG_C(groupId, categoryId);
916 }
917 else {
918 return mbMessagePersistence.countByG_C_S(
919 groupId, categoryId, status);
920 }
921 }
922
923 @Override
924 public List<MBMessage> getCompanyMessages(
925 long companyId, int status, int start, int end) {
926
927 if (status == WorkflowConstants.STATUS_ANY) {
928 return mbMessagePersistence.findByCompanyId(companyId, start, end);
929 }
930 else {
931 return mbMessagePersistence.findByC_S(
932 companyId, status, start, end);
933 }
934 }
935
936 @Override
937 public List<MBMessage> getCompanyMessages(
938 long companyId, int status, int start, int end,
939 OrderByComparator<MBMessage> obc) {
940
941 if (status == WorkflowConstants.STATUS_ANY) {
942 return mbMessagePersistence.findByCompanyId(
943 companyId, start, end, obc);
944 }
945 else {
946 return mbMessagePersistence.findByC_S(
947 companyId, status, start, end, obc);
948 }
949 }
950
951 @Override
952 public int getCompanyMessagesCount(long companyId, int status) {
953 if (status == WorkflowConstants.STATUS_ANY) {
954 return mbMessagePersistence.countByCompanyId(companyId);
955 }
956 else {
957 return mbMessagePersistence.countByC_S(companyId, status);
958 }
959 }
960
961 @Override
962 public MBMessageDisplay getDiscussionMessageDisplay(
963 long userId, long groupId, String className, long classPK,
964 int status)
965 throws PortalException {
966
967 return getDiscussionMessageDisplay(
968 userId, groupId, className, classPK, status,
969 new MessageThreadComparator());
970 }
971
972 @Override
973 public MBMessageDisplay getDiscussionMessageDisplay(
974 long userId, long groupId, String className, long classPK,
975 int status, Comparator<MBMessage> comparator)
976 throws PortalException {
977
978 long classNameId = classNameLocalService.getClassNameId(className);
979
980 MBMessage message = null;
981
982 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
983 classNameId, classPK);
984
985 if (discussion != null) {
986 message = mbMessagePersistence.findByT_P_First(
987 discussion.getThreadId(),
988 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, null);
989 }
990 else {
991 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
992
993 WorkflowThreadLocal.setEnabled(false);
994
995 try {
996 String subject = String.valueOf(classPK);
997
998
999 message = addDiscussionMessage(
1000 userId, null, groupId, className, classPK, 0,
1001 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, subject,
1002 subject, new ServiceContext());
1003 }
1004 catch (SystemException se) {
1005 if (_log.isWarnEnabled()) {
1006 _log.warn(
1007 "Add failed, fetch {threadId=0, parentMessageId=" +
1008 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID + "}");
1009 }
1010
1011 message = mbMessagePersistence.fetchByT_P_First(
1012 0, MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, null);
1013
1014 if (message == null) {
1015 throw se;
1016 }
1017 }
1018 finally {
1019 WorkflowThreadLocal.setEnabled(workflowEnabled);
1020 }
1021 }
1022
1023 return getMessageDisplay(
1024 userId, message, status, MBThreadConstants.THREAD_VIEW_COMBINATION,
1025 false, comparator);
1026 }
1027
1028
1032 @Deprecated
1033 @Override
1034 public MBMessageDisplay getDiscussionMessageDisplay(
1035 long userId, long groupId, String className, long classPK,
1036 int status, String threadView)
1037 throws PortalException {
1038
1039 return getDiscussionMessageDisplay(
1040 userId, groupId, className, classPK, status);
1041 }
1042
1043 @Override
1044 public int getDiscussionMessagesCount(
1045 long classNameId, long classPK, int status) {
1046
1047 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
1048 classNameId, classPK);
1049
1050 if (discussion == null) {
1051 return 0;
1052 }
1053
1054 int count = 0;
1055
1056 if (status == WorkflowConstants.STATUS_ANY) {
1057 count = mbMessagePersistence.countByThreadId(
1058 discussion.getThreadId());
1059 }
1060 else {
1061 count = mbMessagePersistence.countByT_S(
1062 discussion.getThreadId(), status);
1063 }
1064
1065 if (count >= 1) {
1066 return count - 1;
1067 }
1068 else {
1069 return 0;
1070 }
1071 }
1072
1073 @Override
1074 public int getDiscussionMessagesCount(
1075 String className, long classPK, int status) {
1076
1077 long classNameId = classNameLocalService.getClassNameId(className);
1078
1079 return getDiscussionMessagesCount(classNameId, classPK, status);
1080 }
1081
1082 @Override
1083 public List<MBDiscussion> getDiscussions(String className) {
1084 long classNameId = classNameLocalService.getClassNameId(className);
1085
1086 return mbDiscussionPersistence.findByClassNameId(classNameId);
1087 }
1088
1089 @Override
1090 public List<MBMessage> getGroupMessages(
1091 long groupId, int status, int start, int end) {
1092
1093 if (status == WorkflowConstants.STATUS_ANY) {
1094 return mbMessagePersistence.findByGroupId(groupId, start, end);
1095 }
1096 else {
1097 return mbMessagePersistence.findByG_S(groupId, status, start, end);
1098 }
1099 }
1100
1101 @Override
1102 public List<MBMessage> getGroupMessages(
1103 long groupId, int status, int start, int end,
1104 OrderByComparator<MBMessage> obc) {
1105
1106 if (status == WorkflowConstants.STATUS_ANY) {
1107 return mbMessagePersistence.findByGroupId(groupId, start, end, obc);
1108 }
1109 else {
1110 return mbMessagePersistence.findByG_S(
1111 groupId, status, start, end, obc);
1112 }
1113 }
1114
1115 @Override
1116 public List<MBMessage> getGroupMessages(
1117 long groupId, long userId, int status, int start, int end) {
1118
1119 if (status == WorkflowConstants.STATUS_ANY) {
1120 return mbMessagePersistence.findByG_U(groupId, userId, start, end);
1121 }
1122 else {
1123 return mbMessagePersistence.findByG_U_S(
1124 groupId, userId, status, start, end);
1125 }
1126 }
1127
1128 @Override
1129 public List<MBMessage> getGroupMessages(
1130 long groupId, long userId, int status, int start, int end,
1131 OrderByComparator<MBMessage> obc) {
1132
1133 if (status == WorkflowConstants.STATUS_ANY) {
1134 return mbMessagePersistence.findByG_U(
1135 groupId, userId, start, end, obc);
1136 }
1137 else {
1138 return mbMessagePersistence.findByG_U_S(
1139 groupId, userId, status, start, end, obc);
1140 }
1141 }
1142
1143 @Override
1144 public int getGroupMessagesCount(long groupId, int status) {
1145 if (status == WorkflowConstants.STATUS_ANY) {
1146 return mbMessagePersistence.countByGroupId(groupId);
1147 }
1148 else {
1149 return mbMessagePersistence.countByG_S(groupId, status);
1150 }
1151 }
1152
1153 @Override
1154 public int getGroupMessagesCount(long groupId, long userId, int status) {
1155 if (status == WorkflowConstants.STATUS_ANY) {
1156 return mbMessagePersistence.countByG_U(groupId, userId);
1157 }
1158 else {
1159 return mbMessagePersistence.countByG_U_S(groupId, userId, status);
1160 }
1161 }
1162
1163 @Override
1164 public MBMessage getMessage(long messageId) throws PortalException {
1165 return mbMessagePersistence.findByPrimaryKey(messageId);
1166 }
1167
1168 @Override
1169 public MBMessageDisplay getMessageDisplay(
1170 long userId, long messageId, int status, String threadView,
1171 boolean includePrevAndNext)
1172 throws PortalException {
1173
1174 MBMessage message = getMessage(messageId);
1175
1176 return getMessageDisplay(
1177 userId, message, status, threadView, includePrevAndNext);
1178 }
1179
1180 @Override
1181 public MBMessageDisplay getMessageDisplay(
1182 long userId, MBMessage message, int status, String threadView,
1183 boolean includePrevAndNext)
1184 throws PortalException {
1185
1186 return getMessageDisplay(
1187 userId, message, status, threadView, includePrevAndNext,
1188 new MessageThreadComparator());
1189 }
1190
1191 @Override
1192 public MBMessageDisplay getMessageDisplay(
1193 long userId, MBMessage message, int status, String threadView,
1194 boolean includePrevAndNext, Comparator<MBMessage> comparator)
1195 throws PortalException {
1196
1197 MBCategory category = null;
1198
1199 if ((message.getCategoryId() !=
1200 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1201 (message.getCategoryId() !=
1202 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1203
1204 category = mbCategoryPersistence.findByPrimaryKey(
1205 message.getCategoryId());
1206 }
1207 else {
1208 category = new MBCategoryImpl();
1209
1210 category.setCategoryId(message.getCategoryId());
1211 category.setDisplayStyle(MBCategoryConstants.DEFAULT_DISPLAY_STYLE);
1212 }
1213
1214 MBMessage parentMessage = null;
1215
1216 if (message.isReply()) {
1217 parentMessage = mbMessagePersistence.findByPrimaryKey(
1218 message.getParentMessageId());
1219 }
1220
1221 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1222 message.getThreadId());
1223
1224 if (message.isApproved() && !message.isDiscussion()) {
1225 mbThreadLocalService.incrementViewCounter(thread.getThreadId(), 1);
1226
1227 if (thread.getRootMessageUserId() != userId) {
1228 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
1229 thread.getRootMessageId());
1230
1231 socialActivityLocalService.addActivity(
1232 userId, rootMessage.getGroupId(), MBMessage.class.getName(),
1233 rootMessage.getMessageId(),
1234 SocialActivityConstants.TYPE_VIEW, StringPool.BLANK, 0);
1235 }
1236 }
1237
1238 MBThread previousThread = null;
1239 MBThread nextThread = null;
1240
1241 if (message.isApproved() && includePrevAndNext) {
1242 ThreadLastPostDateComparator threadLastPostDateComparator =
1243 new ThreadLastPostDateComparator(false);
1244
1245 MBThread[] prevAndNextThreads = null;
1246
1247 if (status == WorkflowConstants.STATUS_ANY) {
1248 prevAndNextThreads =
1249 mbThreadPersistence.filterFindByG_C_NotS_PrevAndNext(
1250 message.getThreadId(), message.getGroupId(),
1251 message.getCategoryId(),
1252 WorkflowConstants.STATUS_IN_TRASH,
1253 threadLastPostDateComparator);
1254 }
1255 else {
1256 prevAndNextThreads =
1257 mbThreadPersistence.filterFindByG_C_S_PrevAndNext(
1258 message.getThreadId(), message.getGroupId(),
1259 message.getCategoryId(), status,
1260 threadLastPostDateComparator);
1261 }
1262
1263 previousThread = prevAndNextThreads[0];
1264 nextThread = prevAndNextThreads[2];
1265 }
1266
1267 return new MBMessageDisplayImpl(
1268 message, parentMessage, category, thread, previousThread,
1269 nextThread, status, threadView, this, comparator);
1270 }
1271
1272 @Override
1273 public List<MBMessage> getMessages(
1274 String className, long classPK, int status) {
1275
1276 long classNameId = classNameLocalService.getClassNameId(className);
1277
1278 if (status == WorkflowConstants.STATUS_ANY) {
1279 return mbMessagePersistence.findByC_C(classNameId, classPK);
1280 }
1281 else {
1282 return mbMessagePersistence.findByC_C_S(
1283 classNameId, classPK, status);
1284 }
1285 }
1286
1287 @Override
1288 public List<MBMessage> getNoAssetMessages() {
1289 return mbMessageFinder.findByNoAssets();
1290 }
1291
1292 @Override
1293 public int getPositionInThread(long messageId) throws PortalException {
1294 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1295
1296 return mbMessageFinder.countByC_T(
1297 message.getCreateDate(), message.getThreadId());
1298 }
1299
1300 @Override
1301 public List<MBMessage> getThreadMessages(long threadId, int status) {
1302 return getThreadMessages(
1303 threadId, status, new MessageThreadComparator());
1304 }
1305
1306 @Override
1307 public List<MBMessage> getThreadMessages(
1308 long threadId, int status, Comparator<MBMessage> comparator) {
1309
1310 List<MBMessage> messages = null;
1311
1312 if (status == WorkflowConstants.STATUS_ANY) {
1313 messages = mbMessagePersistence.findByThreadId(threadId);
1314 }
1315 else {
1316 messages = mbMessagePersistence.findByT_S(threadId, status);
1317 }
1318
1319 return ListUtil.sort(messages, comparator);
1320 }
1321
1322 @Override
1323 public List<MBMessage> getThreadMessages(
1324 long threadId, int status, int start, int end) {
1325
1326 if (status == WorkflowConstants.STATUS_ANY) {
1327 return mbMessagePersistence.findByThreadId(threadId, start, end);
1328 }
1329 else {
1330 return mbMessagePersistence.findByT_S(threadId, status, start, end);
1331 }
1332 }
1333
1334 @Override
1335 public int getThreadMessagesCount(long threadId, int status) {
1336 if (status == WorkflowConstants.STATUS_ANY) {
1337 return mbMessagePersistence.countByThreadId(threadId);
1338 }
1339 else {
1340 return mbMessagePersistence.countByT_S(threadId, status);
1341 }
1342 }
1343
1344 @Override
1345 public List<MBMessage> getThreadRepliesMessages(
1346 long threadId, int status, int start, int end) {
1347
1348 if (status == WorkflowConstants.STATUS_ANY) {
1349 return mbMessagePersistence.findByThreadReplies(
1350 threadId, start, end);
1351 }
1352 else {
1353 return mbMessagePersistence.findByTR_S(
1354 threadId, status, start, end);
1355 }
1356 }
1357
1358 @Override
1359 public List<MBMessage> getUserDiscussionMessages(
1360 long userId, long classNameId, long classPK, int status, int start,
1361 int end, OrderByComparator<MBMessage> obc) {
1362
1363 if (status == WorkflowConstants.STATUS_ANY) {
1364 return mbMessagePersistence.findByU_C_C(
1365 userId, classNameId, classPK, start, end, obc);
1366 }
1367 else {
1368 return mbMessagePersistence.findByU_C_C_S(
1369 userId, classNameId, classPK, status, start, end, obc);
1370 }
1371 }
1372
1373 @Override
1374 public List<MBMessage> getUserDiscussionMessages(
1375 long userId, long[] classNameIds, int status, int start, int end,
1376 OrderByComparator<MBMessage> obc) {
1377
1378 if (status == WorkflowConstants.STATUS_ANY) {
1379 return mbMessagePersistence.findByU_C(
1380 userId, classNameIds, start, end, obc);
1381 }
1382 else {
1383 return mbMessagePersistence.findByU_C_S(
1384 userId, classNameIds, status, start, end, obc);
1385 }
1386 }
1387
1388 @Override
1389 public List<MBMessage> getUserDiscussionMessages(
1390 long userId, String className, long classPK, int status, int start,
1391 int end, OrderByComparator<MBMessage> obc) {
1392
1393 long classNameId = classNameLocalService.getClassNameId(className);
1394
1395 return getUserDiscussionMessages(
1396 userId, classNameId, classPK, status, start, end, obc);
1397 }
1398
1399 @Override
1400 public int getUserDiscussionMessagesCount(
1401 long userId, long classNameId, long classPK, int status) {
1402
1403 if (status == WorkflowConstants.STATUS_ANY) {
1404 return mbMessagePersistence.countByU_C_C(
1405 userId, classNameId, classPK);
1406 }
1407 else {
1408 return mbMessagePersistence.countByU_C_C_S(
1409 userId, classNameId, classPK, status);
1410 }
1411 }
1412
1413 @Override
1414 public int getUserDiscussionMessagesCount(
1415 long userId, long[] classNameIds, int status) {
1416
1417 if (status == WorkflowConstants.STATUS_ANY) {
1418 return mbMessagePersistence.countByU_C(userId, classNameIds);
1419 }
1420 else {
1421 return mbMessagePersistence.countByU_C_S(
1422 userId, classNameIds, status);
1423 }
1424 }
1425
1426 @Override
1427 public int getUserDiscussionMessagesCount(
1428 long userId, String className, long classPK, int status) {
1429
1430 long classNameId = classNameLocalService.getClassNameId(className);
1431
1432 return getUserDiscussionMessagesCount(
1433 userId, classNameId, classPK, status);
1434 }
1435
1436 @Override
1437 public long moveMessageAttachmentToTrash(
1438 long userId, long messageId, String fileName)
1439 throws PortalException {
1440
1441 MBMessage message = getMessage(messageId);
1442
1443 long folderId = message.getAttachmentsFolderId();
1444
1445 FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
1446 message.getGroupId(), folderId, fileName);
1447
1448 PortletFileRepositoryUtil.movePortletFileEntryToTrash(
1449 userId, fileEntry.getFileEntryId());
1450
1451 return fileEntry.getFileEntryId();
1452 }
1453
1454 @Override
1455 public void restoreMessageAttachmentFromTrash(
1456 long userId, long messageId, String deletedFileName)
1457 throws PortalException {
1458
1459 MBMessage message = getMessage(messageId);
1460
1461 Folder folder = message.addAttachmentsFolder();
1462
1463 PortletFileRepositoryUtil.restorePortletFileEntryFromTrash(
1464 message.getGroupId(), userId, folder.getFolderId(),
1465 deletedFileName);
1466 }
1467
1468 @Override
1469 public void subscribeMessage(long userId, long messageId)
1470 throws PortalException {
1471
1472 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1473
1474 subscriptionLocalService.addSubscription(
1475 userId, message.getGroupId(), MBThread.class.getName(),
1476 message.getThreadId());
1477 }
1478
1479 @Override
1480 public void unsubscribeMessage(long userId, long messageId)
1481 throws PortalException {
1482
1483 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1484
1485 subscriptionLocalService.deleteSubscription(
1486 userId, MBThread.class.getName(), message.getThreadId());
1487 }
1488
1489 @Override
1490 public void updateAnswer(long messageId, boolean answer, boolean cascade)
1491 throws PortalException {
1492
1493 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1494
1495 updateAnswer(message, answer, cascade);
1496 }
1497
1498 @Override
1499 public void updateAnswer(MBMessage message, boolean answer, boolean cascade)
1500 throws PortalException {
1501
1502 if (message.isAnswer() != answer) {
1503 message.setAnswer(answer);
1504
1505 mbMessagePersistence.update(message);
1506 }
1507
1508 if (cascade) {
1509 List<MBMessage> messages = mbMessagePersistence.findByT_P(
1510 message.getThreadId(), message.getMessageId());
1511
1512 for (MBMessage curMessage : messages) {
1513 updateAnswer(curMessage, answer, cascade);
1514 }
1515 }
1516 }
1517
1518 @Override
1519 public void updateAsset(
1520 long userId, MBMessage message, long[] assetCategoryIds,
1521 String[] assetTagNames, long[] assetLinkEntryIds)
1522 throws PortalException {
1523
1524 updateAsset(
1525 userId, message, assetCategoryIds, assetTagNames, assetLinkEntryIds,
1526 true);
1527 }
1528
1529 @Override
1530 public MBMessage updateDiscussionMessage(
1531 long userId, long messageId, String className, long classPK,
1532 String subject, String body, ServiceContext serviceContext)
1533 throws PortalException {
1534
1535 if (Validator.isNull(subject)) {
1536 if (Validator.isNotNull(body)) {
1537 int pos = Math.min(body.length(), 50);
1538
1539 subject = body.substring(0, pos) + "...";
1540 }
1541 else {
1542 throw new MessageBodyException();
1543 }
1544 }
1545
1546 List<ObjectValuePair<String, InputStream>> inputStreamOVPs = null;
1547 List<String> existingFiles = null;
1548 double priority = 0.0;
1549 boolean allowPingbacks = false;
1550
1551 serviceContext.setAttribute("className", className);
1552 serviceContext.setAttribute("classPK", String.valueOf(classPK));
1553
1554 return updateMessage(
1555 userId, messageId, subject, body, inputStreamOVPs, existingFiles,
1556 priority, allowPingbacks, serviceContext);
1557 }
1558
1559 @Override
1560 public MBMessage updateMessage(
1561 long userId, long messageId, String body,
1562 ServiceContext serviceContext)
1563 throws PortalException {
1564
1565 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1566
1567 return updateMessage(
1568 userId, messageId, message.getSubject(), body, null, null,
1569 message.getPriority(), message.isAllowPingbacks(), serviceContext);
1570 }
1571
1572 @Override
1573 public MBMessage updateMessage(
1574 long userId, long messageId, String subject, String body,
1575 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
1576 List<String> existingFiles, double priority, boolean allowPingbacks,
1577 ServiceContext serviceContext)
1578 throws PortalException {
1579
1580
1581
1582 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1583
1584 int oldStatus = message.getStatus();
1585
1586 Date modifiedDate = serviceContext.getModifiedDate(null);
1587 subject = ModelHintsUtil.trimString(
1588 MBMessage.class.getName(), "subject", subject);
1589
1590 Map<String, Object> options = new HashMap<>();
1591
1592 options.put("discussion", message.isDiscussion());
1593
1594 body = SanitizerUtil.sanitize(
1595 message.getCompanyId(), message.getGroupId(), userId,
1596 MBMessage.class.getName(), messageId, "text/" + message.getFormat(),
1597 Sanitizer.MODE_ALL, body, options);
1598
1599 validate(subject, body);
1600
1601 subject = getSubject(subject, body);
1602 body = getBody(subject, body);
1603
1604 message.setModifiedDate(modifiedDate);
1605 message.setSubject(subject);
1606 message.setBody(body);
1607 message.setAllowPingbacks(allowPingbacks);
1608
1609 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
1610 message.setPriority(priority);
1611 }
1612
1613 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1614 message.getThreadId());
1615
1616 if (serviceContext.getWorkflowAction() ==
1617 WorkflowConstants.ACTION_SAVE_DRAFT) {
1618
1619 if (!message.isDraft() && !message.isPending()) {
1620 message.setStatus(WorkflowConstants.STATUS_DRAFT);
1621
1622
1623
1624 User user = userPersistence.findByPrimaryKey(userId);
1625
1626 updateThreadStatus(
1627 thread, message, user, oldStatus, modifiedDate);
1628
1629
1630
1631 assetEntryLocalService.updateVisible(
1632 message.getWorkflowClassName(), message.getMessageId(),
1633 false);
1634
1635 if (!message.isDiscussion()) {
1636
1637
1638
1639 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1640 MBMessage.class);
1641
1642 indexer.delete(message);
1643 }
1644 }
1645 }
1646
1647
1648
1649 if ((inputStreamOVPs != null) || (existingFiles != null)) {
1650 if (ListUtil.isNotEmpty(inputStreamOVPs) ||
1651 ListUtil.isNotEmpty(existingFiles)) {
1652
1653 List<FileEntry> fileEntries =
1654 message.getAttachmentsFileEntries();
1655
1656 for (FileEntry fileEntry : fileEntries) {
1657 String fileEntryId = String.valueOf(
1658 fileEntry.getFileEntryId());
1659
1660 if (!existingFiles.contains(fileEntryId)) {
1661 if (!TrashUtil.isTrashEnabled(message.getGroupId())) {
1662 deleteMessageAttachment(
1663 messageId, fileEntry.getTitle());
1664 }
1665 else {
1666 moveMessageAttachmentToTrash(
1667 userId, messageId, fileEntry.getTitle());
1668 }
1669 }
1670 }
1671
1672 Folder folder = message.addAttachmentsFolder();
1673
1674 PortletFileRepositoryUtil.addPortletFileEntries(
1675 message.getGroupId(), userId, MBMessage.class.getName(),
1676 message.getMessageId(), PortletKeys.MESSAGE_BOARDS,
1677 folder.getFolderId(), inputStreamOVPs);
1678 }
1679 else {
1680 if (TrashUtil.isTrashEnabled(message.getGroupId())) {
1681 List<FileEntry> fileEntries =
1682 message.getAttachmentsFileEntries();
1683
1684 for (FileEntry fileEntry : fileEntries) {
1685 moveMessageAttachmentToTrash(
1686 userId, messageId, fileEntry.getTitle());
1687 }
1688 }
1689 else {
1690 deleteMessageAttachments(message.getMessageId());
1691 }
1692 }
1693 }
1694
1695 message.setExpandoBridgeAttributes(serviceContext);
1696
1697 mbMessagePersistence.update(message);
1698
1699
1700
1701 if ((serviceContext.getWorkflowAction() ==
1702 WorkflowConstants.ACTION_SAVE_DRAFT) &&
1703 !message.isDiscussion()) {
1704
1705 mbStatsUserLocalService.updateStatsUser(
1706 message.getGroupId(), userId, message.getModifiedDate());
1707 }
1708
1709
1710
1711 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
1712 (thread.getPriority() != priority)) {
1713
1714 thread.setPriority(priority);
1715
1716 mbThreadPersistence.update(thread);
1717
1718 updatePriorities(thread.getThreadId(), priority);
1719 }
1720
1721
1722
1723 updateAsset(
1724 userId, message, serviceContext.getAssetCategoryIds(),
1725 serviceContext.getAssetTagNames(),
1726 serviceContext.getAssetLinkEntryIds());
1727
1728
1729
1730 startWorkflowInstance(userId, message, serviceContext);
1731
1732 return message;
1733 }
1734
1735
1738 @Deprecated
1739 @Override
1740 public MBMessage updateMessage(long messageId, String body)
1741 throws PortalException {
1742
1743 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1744
1745 message.setBody(body);
1746
1747 mbMessagePersistence.update(message);
1748
1749 return message;
1750 }
1751
1752
1756 @Deprecated
1757 @Override
1758 public MBMessage updateStatus(
1759 long userId, long messageId, int status,
1760 ServiceContext serviceContext)
1761 throws PortalException {
1762
1763 return updateStatus(
1764 userId, messageId, status, serviceContext,
1765 new HashMap<String, Serializable>());
1766 }
1767
1768 @Override
1769 public MBMessage updateStatus(
1770 long userId, long messageId, int status,
1771 ServiceContext serviceContext,
1772 Map<String, Serializable> workflowContext)
1773 throws PortalException {
1774
1775
1776
1777 MBMessage message = getMessage(messageId);
1778
1779 int oldStatus = message.getStatus();
1780
1781 User user = userPersistence.findByPrimaryKey(userId);
1782 Date now = new Date();
1783
1784 Date modifiedDate = serviceContext.getModifiedDate(now);
1785
1786 message.setStatus(status);
1787 message.setStatusByUserId(userId);
1788 message.setStatusByUserName(user.getFullName());
1789 message.setStatusDate(modifiedDate);
1790
1791 mbMessagePersistence.update(message);
1792
1793
1794
1795 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1796 message.getThreadId());
1797
1798 updateThreadStatus(thread, message, user, oldStatus, modifiedDate);
1799
1800 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1801 MBMessage.class);
1802
1803 if (status == WorkflowConstants.STATUS_APPROVED) {
1804 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
1805
1806
1807
1808 if (serviceContext.isAssetEntryVisible() &&
1809 ((message.getClassNameId() == 0) ||
1810 (message.getParentMessageId() != 0))) {
1811
1812 Date publishDate = null;
1813
1814 AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
1815 message.getWorkflowClassName(), message.getMessageId());
1816
1817 if ((assetEntry != null) &&
1818 (assetEntry.getPublishDate() != null)) {
1819
1820 publishDate = assetEntry.getPublishDate();
1821 }
1822 else {
1823 publishDate = now;
1824
1825 serviceContext.setCommand(Constants.ADD);
1826 }
1827
1828 assetEntryLocalService.updateEntry(
1829 message.getWorkflowClassName(), message.getMessageId(),
1830 publishDate, true);
1831 }
1832
1833 if (serviceContext.isCommandAdd()) {
1834
1835
1836
1837 JSONObject extraDataJSONObject =
1838 JSONFactoryUtil.createJSONObject();
1839
1840 extraDataJSONObject.put("title", message.getSubject());
1841
1842 if (!message.isDiscussion() ) {
1843 if (!message.isAnonymous() && !user.isDefaultUser()) {
1844 long receiverUserId = 0;
1845
1846 MBMessage parentMessage =
1847 mbMessagePersistence.fetchByPrimaryKey(
1848 message.getParentMessageId());
1849
1850 if (parentMessage != null) {
1851 receiverUserId = parentMessage.getUserId();
1852 }
1853
1854 socialActivityLocalService.addActivity(
1855 message.getUserId(), message.getGroupId(),
1856 MBMessage.class.getName(),
1857 message.getMessageId(),
1858 MBActivityKeys.ADD_MESSAGE,
1859 extraDataJSONObject.toString(), receiverUserId);
1860
1861 if ((parentMessage != null) &&
1862 (receiverUserId != message.getUserId())) {
1863
1864 socialActivityLocalService.addActivity(
1865 message.getUserId(),
1866 parentMessage.getGroupId(),
1867 MBMessage.class.getName(),
1868 parentMessage.getMessageId(),
1869 MBActivityKeys.REPLY_MESSAGE,
1870 extraDataJSONObject.toString(), 0);
1871 }
1872 }
1873 }
1874 else {
1875 String className = (String)serviceContext.getAttribute(
1876 "className");
1877 long classPK = ParamUtil.getLong(
1878 serviceContext, "classPK");
1879 long parentMessageId = message.getParentMessageId();
1880
1881 if (parentMessageId !=
1882 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
1883
1884 AssetEntry assetEntry =
1885 assetEntryLocalService.fetchEntry(
1886 className, classPK);
1887
1888 if (assetEntry != null) {
1889 extraDataJSONObject.put(
1890 "messageId", message.getMessageId());
1891
1892 socialActivityLocalService.addActivity(
1893 message.getUserId(),
1894 assetEntry.getGroupId(), className, classPK,
1895 SocialActivityConstants.TYPE_ADD_COMMENT,
1896 extraDataJSONObject.toString(),
1897 assetEntry.getUserId());
1898 }
1899 }
1900 }
1901 }
1902 }
1903
1904
1905
1906 notifySubscribers(
1907 userId, (MBMessage)message.clone(),
1908 (String)workflowContext.get(WorkflowConstants.CONTEXT_URL),
1909 serviceContext);
1910
1911
1912
1913 indexer.reindex(message);
1914
1915
1916
1917 pingPingback(message, serviceContext);
1918 }
1919 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
1920
1921
1922
1923 assetEntryLocalService.updateVisible(
1924 message.getWorkflowClassName(), message.getMessageId(), false);
1925
1926
1927
1928 indexer.delete(message);
1929 }
1930
1931
1932
1933 if (!message.isDiscussion()) {
1934 mbStatsUserLocalService.updateStatsUser(
1935 message.getGroupId(), userId,
1936 serviceContext.getModifiedDate(now));
1937 }
1938
1939 return message;
1940 }
1941
1942 @Override
1943 public void updateUserName(long userId, String userName) {
1944 List<MBMessage> messages = mbMessagePersistence.findByUserId(userId);
1945
1946 for (MBMessage message : messages) {
1947 message.setUserName(userName);
1948
1949 mbMessagePersistence.update(message);
1950 }
1951 }
1952
1953 protected void deleteDiscussionSocialActivities(
1954 String className, MBMessage message)
1955 throws PortalException {
1956
1957 MBDiscussion discussion = mbDiscussionPersistence.findByThreadId(
1958 message.getThreadId());
1959
1960 long classNameId = classNameLocalService.getClassNameId(className);
1961 long classPK = discussion.getClassPK();
1962
1963 if (discussion.getClassNameId() != classNameId) {
1964 return;
1965 }
1966
1967 List<SocialActivity> socialActivities =
1968 socialActivityLocalService.getActivities(
1969 0, className, classPK, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1970
1971 for (SocialActivity socialActivity : socialActivities) {
1972 if (Validator.isNull(socialActivity.getExtraData())) {
1973 continue;
1974 }
1975
1976 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
1977 socialActivity.getExtraData());
1978
1979 long extraDataMessageId = extraDataJSONObject.getLong("messageId");
1980
1981 if (message.getMessageId() == extraDataMessageId) {
1982 socialActivityLocalService.deleteActivity(
1983 socialActivity.getActivityId());
1984 }
1985 }
1986 }
1987
1988 protected String getBody(String subject, String body) {
1989 if (Validator.isNull(body)) {
1990 return subject;
1991 }
1992
1993 return body;
1994 }
1995
1996 protected String getMessageURL(
1997 MBMessage message, ServiceContext serviceContext)
1998 throws PortalException {
1999
2000 String entryURL = GetterUtil.getString(
2001 serviceContext.getAttribute("entryURL"));
2002
2003 if (Validator.isNotNull(entryURL)) {
2004 return entryURL;
2005 }
2006
2007 HttpServletRequest request = serviceContext.getRequest();
2008
2009 if (request == null) {
2010 if (Validator.isNull(serviceContext.getLayoutFullURL())) {
2011 return StringPool.BLANK;
2012 }
2013
2014 return serviceContext.getLayoutFullURL() +
2015 Portal.FRIENDLY_URL_SEPARATOR + "message_boards/view_message/" +
2016 message.getMessageId();
2017 }
2018
2019 String layoutURL = LayoutURLUtil.getLayoutURL(
2020 message.getGroupId(), PortletKeys.MESSAGE_BOARDS, serviceContext);
2021
2022 if (Validator.isNotNull(layoutURL)) {
2023 return layoutURL + Portal.FRIENDLY_URL_SEPARATOR +
2024 "message_boards/view_message/" + message.getMessageId();
2025 }
2026 else {
2027 long controlPanelPlid = PortalUtil.getControlPanelPlid(
2028 serviceContext.getCompanyId());
2029
2030 PortletURL portletURL = PortletURLFactoryUtil.create(
2031 request, PortletKeys.MESSAGE_BOARDS_ADMIN, controlPanelPlid,
2032 PortletRequest.RENDER_PHASE);
2033
2034 portletURL.setParameter(
2035 "struts_action", "/message_boards_admin/view_message");
2036 portletURL.setParameter(
2037 "messageId", String.valueOf(message.getMessageId()));
2038
2039 return portletURL.toString();
2040 }
2041 }
2042
2043 protected String getSubject(String subject, String body) {
2044 if (Validator.isNull(subject)) {
2045 return StringUtil.shorten(body);
2046 }
2047
2048 return subject;
2049 }
2050
2051 protected void notifyDiscussionSubscribers(
2052 long userId, MBMessage message, ServiceContext serviceContext)
2053 throws PortalException {
2054
2055 if (!PrefsPropsUtil.getBoolean(
2056 message.getCompanyId(),
2057 PropsKeys.DISCUSSION_EMAIL_COMMENTS_ADDED_ENABLED)) {
2058
2059 return;
2060 }
2061
2062 MBDiscussion mbDiscussion =
2063 mbDiscussionLocalService.getThreadDiscussion(message.getThreadId());
2064
2065 String contentURL = (String)serviceContext.getAttribute("contentURL");
2066
2067 String userAddress = StringPool.BLANK;
2068 String userName = (String)serviceContext.getAttribute(
2069 "pingbackUserName");
2070
2071 if (Validator.isNull(userName)) {
2072 userAddress = PortalUtil.getUserEmailAddress(message.getUserId());
2073 userName = PortalUtil.getUserName(
2074 message.getUserId(), StringPool.BLANK);
2075 }
2076
2077 String fromName = PrefsPropsUtil.getString(
2078 message.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
2079 String fromAddress = PrefsPropsUtil.getString(
2080 message.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
2081
2082 String subject = PrefsPropsUtil.getContent(
2083 message.getCompanyId(), PropsKeys.DISCUSSION_EMAIL_SUBJECT);
2084 String body = PrefsPropsUtil.getContent(
2085 message.getCompanyId(), PropsKeys.DISCUSSION_EMAIL_BODY);
2086
2087 SubscriptionSender subscriptionSender = new SubscriptionSender();
2088
2089 subscriptionSender.setBody(body);
2090 subscriptionSender.setCompanyId(message.getCompanyId());
2091 subscriptionSender.setClassName(MBDiscussion.class.getName());
2092 subscriptionSender.setClassPK(mbDiscussion.getDiscussionId());
2093 subscriptionSender.setContextAttribute(
2094 "[$COMMENTS_BODY$]", message.getBody(true), false);
2095 subscriptionSender.setContextAttributes(
2096 "[$COMMENTS_USER_ADDRESS$]", userAddress, "[$COMMENTS_USER_NAME$]",
2097 userName, "[$CONTENT_URL$]", contentURL);
2098 subscriptionSender.setCurrentUserId(userId);
2099 subscriptionSender.setEntryTitle(message.getBody());
2100 subscriptionSender.setEntryURL(contentURL);
2101 subscriptionSender.setFrom(fromAddress, fromName);
2102 subscriptionSender.setHtmlFormat(true);
2103
2104 Date modifiedDate = message.getModifiedDate();
2105
2106 subscriptionSender.setMailId(
2107 "mb_discussion", message.getCategoryId(), message.getMessageId(),
2108 modifiedDate.getTime());
2109
2110 int notificationType =
2111 UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
2112
2113 if (serviceContext.isCommandUpdate()) {
2114 notificationType =
2115 UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
2116 }
2117
2118 subscriptionSender.setNotificationType(notificationType);
2119
2120 subscriptionSender.setPortletId(PortletKeys.COMMENTS);
2121 subscriptionSender.setScopeGroupId(message.getGroupId());
2122 subscriptionSender.setServiceContext(serviceContext);
2123 subscriptionSender.setSubject(subject);
2124 subscriptionSender.setUniqueMailId(false);
2125
2126 String className = (String)serviceContext.getAttribute("className");
2127 long classPK = ParamUtil.getLong(serviceContext, "classPK");
2128
2129 subscriptionSender.addPersistedSubscribers(className, classPK);
2130
2131 subscriptionSender.flushNotificationsAsync();
2132 }
2133
2134 protected void notifySubscribers(
2135 long userId, MBMessage message, String messageURL,
2136 ServiceContext serviceContext)
2137 throws PortalException {
2138
2139 if (!message.isApproved() || Validator.isNull(messageURL)) {
2140 return;
2141 }
2142
2143 if (message.isDiscussion()) {
2144 try {
2145 notifyDiscussionSubscribers(userId, message, serviceContext);
2146 }
2147 catch (Exception e) {
2148 _log.error(e, e);
2149 }
2150
2151 return;
2152 }
2153
2154 MBGroupServiceSettings mbGroupServiceSettings =
2155 MBGroupServiceSettings.getInstance(message.getGroupId());
2156
2157 if (serviceContext.isCommandAdd() &&
2158 mbGroupServiceSettings.isEmailMessageAddedEnabled()) {
2159 }
2160 else if (serviceContext.isCommandUpdate() &&
2161 mbGroupServiceSettings.isEmailMessageUpdatedEnabled()) {
2162 }
2163 else {
2164 return;
2165 }
2166
2167 Company company = companyPersistence.findByPrimaryKey(
2168 message.getCompanyId());
2169
2170 Group group = groupPersistence.findByPrimaryKey(message.getGroupId());
2171
2172 String emailAddress = PortalUtil.getUserEmailAddress(
2173 message.getUserId());
2174 String fullName = PortalUtil.getUserName(
2175 message.getUserId(), message.getUserName());
2176
2177 if (message.isAnonymous()) {
2178 emailAddress = StringPool.BLANK;
2179 fullName = serviceContext.translate("anonymous");
2180 }
2181
2182 MBCategory category = message.getCategory();
2183
2184 String categoryName = category.getName();
2185
2186 if (category.getCategoryId() ==
2187 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2188
2189 categoryName = serviceContext.translate("message-boards-home");
2190
2191 categoryName += " - " + group.getDescriptiveName();
2192 }
2193
2194 List<Long> categoryIds = new ArrayList<>();
2195
2196 categoryIds.add(message.getCategoryId());
2197
2198 if (message.getCategoryId() !=
2199 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2200
2201 categoryIds.addAll(category.getAncestorCategoryIds());
2202 }
2203
2204 String entryTitle = message.getSubject();
2205
2206 String fromName = mbGroupServiceSettings.getEmailFromName();
2207 String fromAddress = mbGroupServiceSettings.getEmailFromAddress();
2208
2209 String replyToAddress = StringPool.BLANK;
2210
2211 if (PropsValues.POP_SERVER_NOTIFICATIONS_ENABLED) {
2212 replyToAddress = MBUtil.getReplyToAddress(
2213 message.getCategoryId(), message.getMessageId(),
2214 company.getMx(), fromAddress);
2215 }
2216
2217 LocalizedValuesMap subjectLocalizedValuesMap = null;
2218 LocalizedValuesMap bodyLocalizedValuesMap = null;
2219
2220 if (serviceContext.isCommandUpdate()) {
2221 subjectLocalizedValuesMap =
2222 mbGroupServiceSettings.getEmailMessageUpdatedSubject();
2223 bodyLocalizedValuesMap =
2224 mbGroupServiceSettings.getEmailMessageUpdatedBody();
2225 }
2226 else {
2227 subjectLocalizedValuesMap =
2228 mbGroupServiceSettings.getEmailMessageAddedSubject();
2229 bodyLocalizedValuesMap =
2230 mbGroupServiceSettings.getEmailMessageAddedBody();
2231 }
2232
2233 boolean htmlFormat = mbGroupServiceSettings.isEmailHtmlFormat();
2234
2235 String messageBody = message.getBody();
2236
2237 if (htmlFormat && message.isFormatBBCode()) {
2238 try {
2239 messageBody = BBCodeTranslatorUtil.getHTML(messageBody);
2240
2241 HttpServletRequest request = serviceContext.getRequest();
2242
2243 if (request != null) {
2244 ThemeDisplay themeDisplay =
2245 (ThemeDisplay)request.getAttribute(
2246 WebKeys.THEME_DISPLAY);
2247
2248 messageBody = MBUtil.replaceMessageBodyPaths(
2249 themeDisplay, messageBody);
2250 }
2251 }
2252 catch (Exception e) {
2253 _log.error(
2254 "Could not parse message " + message.getMessageId() +
2255 " " + e.getMessage());
2256 }
2257 }
2258
2259 String inReplyTo = null;
2260
2261 if (message.getParentMessageId() !=
2262 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
2263
2264 MBMessage parentMessage = mbMessageLocalService.getMessage(
2265 message.getParentMessageId());
2266
2267 Date modifiedDate = parentMessage.getModifiedDate();
2268
2269 inReplyTo = PortalUtil.getMailId(
2270 company.getMx(), MBUtil.MESSAGE_POP_PORTLET_PREFIX,
2271 message.getCategoryId(), parentMessage.getMessageId(),
2272 modifiedDate.getTime());
2273 }
2274
2275 SubscriptionSender subscriptionSenderPrototype =
2276 new MBSubscriptionSender(MBPermission.RESOURCE_NAME);
2277
2278 subscriptionSenderPrototype.setBulk(
2279 PropsValues.MESSAGE_BOARDS_EMAIL_BULK);
2280 subscriptionSenderPrototype.setClassName(message.getModelClassName());
2281 subscriptionSenderPrototype.setClassPK(message.getMessageId());
2282 subscriptionSenderPrototype.setCompanyId(message.getCompanyId());
2283 subscriptionSenderPrototype.setContextAttribute(
2284 "[$MESSAGE_BODY$]", messageBody, false);
2285 subscriptionSenderPrototype.setContextAttributes(
2286 "[$CATEGORY_NAME$]", categoryName, "[$MAILING_LIST_ADDRESS$]",
2287 replyToAddress, "[$MESSAGE_ID$]", message.getMessageId(),
2288 "[$MESSAGE_SUBJECT$]", entryTitle, "[$MESSAGE_URL$]", messageURL,
2289 "[$MESSAGE_USER_ADDRESS$]", emailAddress, "[$MESSAGE_USER_NAME$]",
2290 fullName);
2291 subscriptionSenderPrototype.setCurrentUserId(userId);
2292 subscriptionSenderPrototype.setEntryTitle(entryTitle);
2293 subscriptionSenderPrototype.setEntryURL(messageURL);
2294 subscriptionSenderPrototype.setFrom(fromAddress, fromName);
2295 subscriptionSenderPrototype.setHtmlFormat(htmlFormat);
2296 subscriptionSenderPrototype.setInReplyTo(inReplyTo);
2297
2298 if (bodyLocalizedValuesMap != null) {
2299 subscriptionSenderPrototype.setLocalizedBodyMap(
2300 LocalizationUtil.getMap(bodyLocalizedValuesMap));
2301 }
2302
2303 if (subjectLocalizedValuesMap != null) {
2304 subscriptionSenderPrototype.setLocalizedSubjectMap(
2305 LocalizationUtil.getMap(subjectLocalizedValuesMap));
2306 }
2307
2308 Date modifiedDate = message.getModifiedDate();
2309
2310 subscriptionSenderPrototype.setMailId(
2311 MBUtil.MESSAGE_POP_PORTLET_PREFIX, message.getCategoryId(),
2312 message.getMessageId(), modifiedDate.getTime());
2313
2314 int notificationType =
2315 UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
2316
2317 if (serviceContext.isCommandUpdate()) {
2318 notificationType =
2319 UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
2320 }
2321
2322 subscriptionSenderPrototype.setNotificationType(notificationType);
2323
2324 subscriptionSenderPrototype.setPortletId(PortletKeys.MESSAGE_BOARDS);
2325 subscriptionSenderPrototype.setReplyToAddress(replyToAddress);
2326 subscriptionSenderPrototype.setScopeGroupId(message.getGroupId());
2327 subscriptionSenderPrototype.setServiceContext(serviceContext);
2328 subscriptionSenderPrototype.setUniqueMailId(false);
2329
2330 SubscriptionSender subscriptionSender =
2331 (SubscriptionSender)SerializableUtil.clone(
2332 subscriptionSenderPrototype);
2333
2334 subscriptionSender.addPersistedSubscribers(
2335 MBCategory.class.getName(), message.getGroupId());
2336
2337 for (long categoryId : categoryIds) {
2338 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2339 subscriptionSender.addPersistedSubscribers(
2340 MBCategory.class.getName(), categoryId);
2341 }
2342 }
2343
2344 subscriptionSender.addPersistedSubscribers(
2345 MBThread.class.getName(), message.getThreadId());
2346
2347 subscriptionSender.flushNotificationsAsync();
2348
2349 if (!MailingListThreadLocal.isSourceMailingList()) {
2350 for (long categoryId : categoryIds) {
2351 MBSubscriptionSender sourceMailingListSubscriptionSender =
2352 (MBSubscriptionSender)SerializableUtil.clone(
2353 subscriptionSenderPrototype);
2354
2355 sourceMailingListSubscriptionSender.setBulk(false);
2356
2357 sourceMailingListSubscriptionSender.addMailingListSubscriber(
2358 message.getGroupId(), categoryId);
2359
2360 sourceMailingListSubscriptionSender.flushNotificationsAsync();
2361 }
2362 }
2363 }
2364
2365 protected void pingPingback(
2366 MBMessage message, ServiceContext serviceContext) {
2367
2368 if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
2369 !message.isAllowPingbacks() || !message.isApproved()) {
2370
2371 return;
2372 }
2373
2374 String layoutFullURL = serviceContext.getLayoutFullURL();
2375
2376 if (Validator.isNull(layoutFullURL)) {
2377 return;
2378 }
2379
2380 String sourceUri =
2381 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
2382 "message_boards/view_message/" + message.getMessageId();
2383
2384 Source source = new Source(message.getBody(true));
2385
2386 List<StartTag> startTags = source.getAllStartTags("a");
2387
2388 for (StartTag startTag : startTags) {
2389 String targetUri = startTag.getAttributeValue("href");
2390
2391 if (Validator.isNotNull(targetUri)) {
2392 try {
2393 LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
2394 }
2395 catch (Exception e) {
2396 _log.error("Error while sending pingback " + targetUri, e);
2397 }
2398 }
2399 }
2400 }
2401
2402 protected void startWorkflowInstance(
2403 long userId, MBMessage message, ServiceContext serviceContext)
2404 throws PortalException {
2405
2406 Map<String, Serializable> workflowContext = new HashMap<>();
2407
2408 workflowContext.put(
2409 WorkflowConstants.CONTEXT_URL,
2410 getMessageURL(message, serviceContext));
2411
2412 WorkflowHandlerRegistryUtil.startWorkflowInstance(
2413 message.getCompanyId(), message.getGroupId(), userId,
2414 message.getWorkflowClassName(), message.getMessageId(), message,
2415 serviceContext, workflowContext);
2416 }
2417
2418 protected void updateAsset(
2419 long userId, MBMessage message, long[] assetCategoryIds,
2420 String[] assetTagNames, long[] assetLinkEntryIds,
2421 boolean assetEntryVisible)
2422 throws PortalException {
2423
2424 boolean visible = false;
2425
2426 if (assetEntryVisible && message.isApproved() &&
2427 ((message.getClassNameId() == 0) ||
2428 (message.getParentMessageId() != 0))) {
2429
2430 visible = true;
2431 }
2432
2433 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
2434 userId, message.getGroupId(), message.getCreateDate(),
2435 message.getModifiedDate(), message.getWorkflowClassName(),
2436 message.getMessageId(), message.getUuid(), 0, assetCategoryIds,
2437 assetTagNames, visible, null, null, null, ContentTypes.TEXT_HTML,
2438 message.getSubject(), null, null, null, null, 0, 0, null);
2439
2440 assetLinkLocalService.updateLinks(
2441 userId, assetEntry.getEntryId(), assetLinkEntryIds,
2442 AssetLinkConstants.TYPE_RELATED);
2443 }
2444
2445 protected void updatePriorities(long threadId, double priority) {
2446 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
2447 threadId);
2448
2449 for (MBMessage message : messages) {
2450 if (message.getPriority() != priority) {
2451 message.setPriority(priority);
2452
2453 mbMessagePersistence.update(message);
2454 }
2455 }
2456 }
2457
2458 protected void updateThreadStatus(
2459 MBThread thread, MBMessage message, User user, int oldStatus,
2460 Date modifiedDate)
2461 throws PortalException {
2462
2463 MBCategory category = null;
2464
2465 int status = message.getStatus();
2466
2467 if ((thread.getCategoryId() !=
2468 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
2469 (thread.getCategoryId() !=
2470 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
2471
2472 category = mbCategoryPersistence.findByPrimaryKey(
2473 thread.getCategoryId());
2474 }
2475
2476 if ((thread.getRootMessageId() == message.getMessageId()) &&
2477 (oldStatus != status)) {
2478
2479 thread.setModifiedDate(modifiedDate);
2480 thread.setStatus(status);
2481 thread.setStatusByUserId(user.getUserId());
2482 thread.setStatusByUserName(user.getFullName());
2483 thread.setStatusDate(modifiedDate);
2484 }
2485
2486 if (status == oldStatus) {
2487 return;
2488 }
2489
2490 if (status == WorkflowConstants.STATUS_APPROVED) {
2491 if (message.isAnonymous()) {
2492 thread.setLastPostByUserId(0);
2493 }
2494 else {
2495 thread.setLastPostByUserId(message.getUserId());
2496 }
2497
2498 thread.setLastPostDate(modifiedDate);
2499
2500 if (category != null) {
2501 category.setLastPostDate(modifiedDate);
2502
2503 category = mbCategoryPersistence.update(category);
2504 }
2505 }
2506
2507 if ((oldStatus == WorkflowConstants.STATUS_APPROVED) ||
2508 (status == WorkflowConstants.STATUS_APPROVED)) {
2509
2510
2511
2512 MBUtil.updateThreadMessageCount(
2513 thread.getCompanyId(), thread.getThreadId());
2514
2515
2516
2517 if ((category != null) &&
2518 (thread.getRootMessageId() == message.getMessageId())) {
2519
2520 MBUtil.updateCategoryStatistics(
2521 category.getCompanyId(), category.getCategoryId());
2522 }
2523
2524 if ((category != null) &&
2525 !(thread.getRootMessageId() == message.getMessageId())) {
2526
2527 MBUtil.updateCategoryMessageCount(
2528 category.getCompanyId(), category.getCategoryId());
2529 }
2530 }
2531
2532
2533
2534 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
2535 MBThread.class);
2536
2537 indexer.reindex(thread);
2538
2539 mbThreadPersistence.update(thread);
2540 }
2541
2542 protected void validate(String subject, String body)
2543 throws PortalException {
2544
2545 if (Validator.isNull(subject) && Validator.isNull(body)) {
2546 throw new MessageSubjectException();
2547 }
2548 }
2549
2550 protected void validateDiscussionMaxComments(String className, long classPK)
2551 throws PortalException {
2552
2553 if (PropsValues.DISCUSSION_MAX_COMMENTS <= 0) {
2554 return;
2555 }
2556
2557 int count = getDiscussionMessagesCount(
2558 className, classPK, WorkflowConstants.STATUS_APPROVED);
2559
2560 if (count >= PropsValues.DISCUSSION_MAX_COMMENTS) {
2561 throw new DiscussionMaxCommentsException();
2562 }
2563 }
2564
2565 private static final Log _log = LogFactoryUtil.getLog(
2566 MBMessageLocalServiceImpl.class);
2567
2568 }