001
014
015 package com.liferay.portlet.messageboards.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.increment.BufferedIncrement;
020 import com.liferay.portal.kernel.increment.NumberIncrement;
021 import com.liferay.portal.kernel.json.JSONFactoryUtil;
022 import com.liferay.portal.kernel.json.JSONObject;
023 import com.liferay.portal.kernel.search.Field;
024 import com.liferay.portal.kernel.search.Hits;
025 import com.liferay.portal.kernel.search.Indexer;
026 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
027 import com.liferay.portal.kernel.search.SearchContext;
028 import com.liferay.portal.kernel.search.Sort;
029 import com.liferay.portal.kernel.systemevent.SystemEvent;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.kernel.workflow.WorkflowConstants;
033 import com.liferay.portal.model.Group;
034 import com.liferay.portal.model.ResourceConstants;
035 import com.liferay.portal.model.SystemEventConstants;
036 import com.liferay.portal.model.User;
037 import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
038 import com.liferay.portal.service.ServiceContext;
039 import com.liferay.portal.util.PortletKeys;
040 import com.liferay.portlet.asset.model.AssetEntry;
041 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
042 import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
043 import com.liferay.portlet.messageboards.NoSuchCategoryException;
044 import com.liferay.portlet.messageboards.SplitThreadException;
045 import com.liferay.portlet.messageboards.model.MBCategory;
046 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
047 import com.liferay.portlet.messageboards.model.MBMessage;
048 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
049 import com.liferay.portlet.messageboards.model.MBThread;
050 import com.liferay.portlet.messageboards.model.MBThreadConstants;
051 import com.liferay.portlet.messageboards.model.MBTreeWalker;
052 import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
053 import com.liferay.portlet.messageboards.util.MBUtil;
054 import com.liferay.portlet.social.model.SocialActivityConstants;
055 import com.liferay.portlet.trash.model.TrashEntry;
056 import com.liferay.portlet.trash.model.TrashVersion;
057
058 import java.util.ArrayList;
059 import java.util.Date;
060 import java.util.HashSet;
061 import java.util.List;
062 import java.util.Set;
063
064
068 public class MBThreadLocalServiceImpl extends MBThreadLocalServiceBaseImpl {
069
070 @Override
071 public MBThread addThread(
072 long categoryId, MBMessage message, ServiceContext serviceContext)
073 throws PortalException {
074
075
076
077 long threadId = message.getThreadId();
078
079 if (!message.isRoot() || (threadId <= 0)) {
080 threadId = counterLocalService.increment();
081 }
082
083 MBThread thread = mbThreadPersistence.create(threadId);
084
085 thread.setUuid(serviceContext.getUuid());
086 thread.setGroupId(message.getGroupId());
087 thread.setCompanyId(message.getCompanyId());
088 thread.setUserId(message.getUserId());
089 thread.setUserName(message.getUserName());
090 thread.setCategoryId(categoryId);
091 thread.setRootMessageId(message.getMessageId());
092 thread.setRootMessageUserId(message.getUserId());
093
094 if (message.isAnonymous()) {
095 thread.setLastPostByUserId(0);
096 }
097 else {
098 thread.setLastPostByUserId(message.getUserId());
099 }
100
101 thread.setLastPostDate(message.getModifiedDate());
102
103 if (message.getPriority() != MBThreadConstants.PRIORITY_NOT_GIVEN) {
104 thread.setPriority(message.getPriority());
105 }
106
107 thread.setStatus(message.getStatus());
108 thread.setStatusByUserId(message.getStatusByUserId());
109 thread.setStatusByUserName(message.getStatusByUserName());
110 thread.setStatusDate(message.getStatusDate());
111
112 mbThreadPersistence.update(thread);
113
114
115
116 if (categoryId >= 0) {
117 assetEntryLocalService.updateEntry(
118 message.getUserId(), message.getGroupId(),
119 thread.getStatusDate(), thread.getLastPostDate(),
120 MBThread.class.getName(), thread.getThreadId(),
121 thread.getUuid(), 0, new long[0], new String[0], false, null,
122 null, null, null, String.valueOf(thread.getRootMessageId()),
123 null, null, null, null, 0, 0, null);
124 }
125
126 return thread;
127 }
128
129 @Override
130 public void deleteThread(long threadId) throws PortalException {
131 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
132
133 mbThreadLocalService.deleteThread(thread);
134 }
135
136 @Override
137 @SystemEvent(
138 action = SystemEventConstants.ACTION_SKIP,
139 type = SystemEventConstants.TYPE_DELETE
140 )
141 public void deleteThread(MBThread thread) throws PortalException {
142 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
143 thread.getRootMessageId());
144
145
146
147 Indexer messageIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
148 MBMessage.class);
149
150
151
152 long folderId = thread.getAttachmentsFolderId();
153
154 if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
155 PortletFileRepositoryUtil.deletePortletFolder(folderId);
156 }
157
158
159
160 subscriptionLocalService.deleteSubscriptions(
161 thread.getCompanyId(), MBThread.class.getName(),
162 thread.getThreadId());
163
164
165
166 mbThreadFlagLocalService.deleteThreadFlagsByThreadId(
167 thread.getThreadId());
168
169
170
171 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
172 thread.getThreadId());
173
174 for (MBMessage message : messages) {
175
176
177
178 ratingsStatsLocalService.deleteStats(
179 message.getWorkflowClassName(), message.getMessageId());
180
181
182
183 assetEntryLocalService.deleteEntry(
184 message.getWorkflowClassName(), message.getMessageId());
185
186
187
188 if (!message.isDiscussion()) {
189 resourceLocalService.deleteResource(
190 message.getCompanyId(), message.getWorkflowClassName(),
191 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
192 }
193
194
195
196 mbMessagePersistence.remove(message);
197
198
199
200 messageIndexer.delete(message);
201
202
203
204 if (!message.isDiscussion()) {
205 mbStatsUserLocalService.updateStatsUser(
206 message.getGroupId(), message.getUserId());
207 }
208
209
210
211 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
212 message.getCompanyId(), message.getGroupId(),
213 message.getWorkflowClassName(), message.getMessageId());
214 }
215
216
217
218 if ((rootMessage.getCategoryId() !=
219 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
220 (rootMessage.getCategoryId() !=
221 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
222
223 try {
224 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
225 thread.getCategoryId());
226
227 MBUtil.updateCategoryStatistics(
228 category.getCompanyId(), category.getCategoryId());
229 }
230 catch (NoSuchCategoryException nsce) {
231 if (!thread.isInTrash()) {
232 throw nsce;
233 }
234 }
235 }
236
237
238
239 AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
240 MBThread.class.getName(), thread.getThreadId());
241
242 if (assetEntry != null) {
243 assetEntry.setTitle(rootMessage.getSubject());
244
245 assetEntryLocalService.updateAssetEntry(assetEntry);
246 }
247
248 assetEntryLocalService.deleteEntry(
249 MBThread.class.getName(), thread.getThreadId());
250
251
252
253 if (thread.isInTrashExplicitly()) {
254 trashEntryLocalService.deleteEntry(
255 MBThread.class.getName(), thread.getThreadId());
256 }
257 else {
258 trashVersionLocalService.deleteTrashVersion(
259 MBThread.class.getName(), thread.getThreadId());
260 }
261
262
263
264 Indexer threadIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
265 MBThread.class);
266
267 threadIndexer.delete(thread);
268
269
270
271 mbThreadPersistence.remove(thread);
272 }
273
274 @Override
275 public void deleteThreads(long groupId, long categoryId)
276 throws PortalException {
277
278 deleteThreads(groupId, categoryId, true);
279 }
280
281 @Override
282 public void deleteThreads(
283 long groupId, long categoryId, boolean includeTrashedEntries)
284 throws PortalException {
285
286 List<MBThread> threads = mbThreadPersistence.findByG_C(
287 groupId, categoryId);
288
289 for (MBThread thread : threads) {
290 if (includeTrashedEntries || !thread.isInTrashExplicitly()) {
291 mbThreadLocalService.deleteThread(thread);
292 }
293 }
294
295 if (mbThreadPersistence.countByGroupId(groupId) == 0) {
296 PortletFileRepositoryUtil.deletePortletRepository(
297 groupId, PortletKeys.MESSAGE_BOARDS);
298 }
299 }
300
301 @Override
302 public MBThread fetchThread(long threadId) {
303 return mbThreadPersistence.fetchByPrimaryKey(threadId);
304 }
305
306 @Override
307 public int getCategoryThreadsCount(
308 long groupId, long categoryId, int status) {
309
310 if (status == WorkflowConstants.STATUS_ANY) {
311 return mbThreadPersistence.countByG_C(groupId, categoryId);
312 }
313 else {
314 return mbThreadPersistence.countByG_C_S(
315 groupId, categoryId, status);
316 }
317 }
318
319
323 @Deprecated
324 @Override
325 public List<MBThread> getGroupThreads(
326 long groupId, int status, int start, int end) {
327
328 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
329 status, start, end, null);
330
331 return getGroupThreads(groupId, queryDefinition);
332 }
333
334 @Override
335 public List<MBThread> getGroupThreads(
336 long groupId, long userId, boolean subscribed, boolean includeAnonymous,
337 QueryDefinition<MBThread> queryDefinition) {
338
339 if (userId <= 0) {
340 return getGroupThreads(groupId, queryDefinition);
341 }
342
343 if (subscribed) {
344 return mbThreadFinder.findByS_G_U_C(
345 groupId, userId, null, queryDefinition);
346 }
347 else {
348 if (includeAnonymous) {
349 return mbThreadFinder.findByG_U_C(
350 groupId, userId, null, queryDefinition);
351 }
352 else {
353 return mbThreadFinder.findByG_U_C_A(
354 groupId, userId, null, false, queryDefinition);
355 }
356 }
357 }
358
359 @Override
360 public List<MBThread> getGroupThreads(
361 long groupId, long userId, boolean subscribed,
362 QueryDefinition<MBThread> queryDefinition) {
363
364 return getGroupThreads(
365 groupId, userId, subscribed, true, queryDefinition);
366 }
367
368
372 @Deprecated
373 @Override
374 public List<MBThread> getGroupThreads(
375 long groupId, long userId, int status, boolean subscribed,
376 boolean includeAnonymous, int start, int end) {
377
378 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
379 status, start, end, null);
380
381 return getGroupThreads(
382 groupId, userId, subscribed, includeAnonymous, queryDefinition);
383 }
384
385
389 @Deprecated
390 @Override
391 public List<MBThread> getGroupThreads(
392 long groupId, long userId, int status, boolean subscribed, int start,
393 int end) {
394
395 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
396 status, start, end, null);
397
398 return getGroupThreads(groupId, userId, subscribed, queryDefinition);
399 }
400
401
405 @Deprecated
406 @Override
407 public List<MBThread> getGroupThreads(
408 long groupId, long userId, int status, int start, int end) {
409
410 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
411 status, start, end, null);
412
413 return getGroupThreads(groupId, userId, false, queryDefinition);
414 }
415
416 @Override
417 public List<MBThread> getGroupThreads(
418 long groupId, long userId, QueryDefinition<MBThread> queryDefinition) {
419
420 return getGroupThreads(groupId, userId, false, queryDefinition);
421 }
422
423 @Override
424 public List<MBThread> getGroupThreads(
425 long groupId, QueryDefinition<MBThread> queryDefinition) {
426
427 if (queryDefinition.isExcludeStatus()) {
428 return mbThreadPersistence.findByG_NotC_NotS(
429 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
430 queryDefinition.getStatus(), queryDefinition.getStart(),
431 queryDefinition.getEnd());
432 }
433 else {
434 return mbThreadPersistence.findByG_NotC_S(
435 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
436 queryDefinition.getStatus(), queryDefinition.getStart(),
437 queryDefinition.getEnd());
438 }
439 }
440
441
445 @Deprecated
446 @Override
447 public int getGroupThreadsCount(long groupId, int status) {
448 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
449 status);
450
451 return getGroupThreadsCount(groupId, queryDefinition);
452 }
453
454 @Override
455 public int getGroupThreadsCount(
456 long groupId, long userId, boolean subscribed, boolean includeAnonymous,
457 QueryDefinition<MBThread> queryDefinition) {
458
459 if (userId <= 0) {
460 return getGroupThreadsCount(groupId, queryDefinition);
461 }
462
463 if (subscribed) {
464 return mbThreadFinder.countByS_G_U_C(
465 groupId, userId, null, queryDefinition);
466 }
467 else {
468 if (includeAnonymous) {
469 return mbThreadFinder.countByG_U_C(
470 groupId, userId, null, queryDefinition);
471 }
472 else {
473 return mbThreadFinder.countByG_U_C_A(
474 groupId, userId, null, false, queryDefinition);
475 }
476 }
477 }
478
479 @Override
480 public int getGroupThreadsCount(
481 long groupId, long userId, boolean subscribed,
482 QueryDefinition<MBThread> queryDefinition) {
483
484 return getGroupThreadsCount(
485 groupId, userId, subscribed, true, queryDefinition);
486 }
487
488
492 @Deprecated
493 @Override
494 public int getGroupThreadsCount(long groupId, long userId, int status) {
495 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
496 status);
497
498 return getGroupThreadsCount(groupId, userId, false, queryDefinition);
499 }
500
501
505 @Deprecated
506 @Override
507 public int getGroupThreadsCount(
508 long groupId, long userId, int status, boolean subscribed) {
509
510 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
511 status);
512
513 return getGroupThreadsCount(
514 groupId, userId, subscribed, true, queryDefinition);
515 }
516
517
521 @Deprecated
522 @Override
523 public int getGroupThreadsCount(
524 long groupId, long userId, int status, boolean subscribed,
525 boolean includeAnonymous) {
526
527 QueryDefinition<MBThread> queryDefinition = new QueryDefinition<>(
528 status);
529
530 return getGroupThreadsCount(
531 groupId, userId, subscribed, includeAnonymous, queryDefinition);
532 }
533
534 @Override
535 public int getGroupThreadsCount(
536 long groupId, long userId, QueryDefinition<MBThread> queryDefinition) {
537
538 return getGroupThreadsCount(groupId, userId, false, queryDefinition);
539 }
540
541 @Override
542 public int getGroupThreadsCount(
543 long groupId, QueryDefinition<MBThread> queryDefinition) {
544
545 if (queryDefinition.isExcludeStatus()) {
546 return mbThreadPersistence.countByG_NotC_NotS(
547 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
548 queryDefinition.getStatus());
549 }
550 else {
551 return mbThreadPersistence.countByG_NotC_S(
552 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
553 queryDefinition.getStatus());
554 }
555 }
556
557 @Override
558 public List<MBThread> getNoAssetThreads() {
559 return mbThreadFinder.findByNoAssets();
560 }
561
562 @Override
563 public List<MBThread> getPriorityThreads(long categoryId, double priority)
564 throws PortalException {
565
566 return getPriorityThreads(categoryId, priority, false);
567 }
568
569 @Override
570 public List<MBThread> getPriorityThreads(
571 long categoryId, double priority, boolean inherit)
572 throws PortalException {
573
574 if (!inherit) {
575 return mbThreadPersistence.findByC_P(categoryId, priority);
576 }
577
578 List<MBThread> threads = new ArrayList<>();
579
580 while ((categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
581 (categoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
582
583 threads.addAll(
584 0, mbThreadPersistence.findByC_P(categoryId, priority));
585
586 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
587 categoryId);
588
589 categoryId = category.getParentCategoryId();
590 }
591
592 return threads;
593 }
594
595 @Override
596 public MBThread getThread(long threadId) throws PortalException {
597 return mbThreadPersistence.findByPrimaryKey(threadId);
598 }
599
600 @Override
601 public List<MBThread> getThreads(
602 long groupId, long categoryId, int status, int start, int end) {
603
604 if (status == WorkflowConstants.STATUS_ANY) {
605 return mbThreadPersistence.findByG_C(
606 groupId, categoryId, start, end);
607 }
608 else {
609 return mbThreadPersistence.findByG_C_S(
610 groupId, categoryId, status, start, end);
611 }
612 }
613
614 @Override
615 public int getThreadsCount(long groupId, long categoryId, int status) {
616 if (status == WorkflowConstants.STATUS_ANY) {
617 return mbThreadPersistence.countByG_C(groupId, categoryId);
618 }
619 else {
620 return mbThreadPersistence.countByG_C_S(
621 groupId, categoryId, status);
622 }
623 }
624
625 @Override
626 public boolean hasAnswerMessage(long threadId) {
627 int count = mbMessagePersistence.countByT_A(threadId, true);
628
629 if (count > 0) {
630 return true;
631 }
632 else {
633 return false;
634 }
635 }
636
637 @BufferedIncrement(
638 configuration = "MBThread", incrementClass = NumberIncrement.class
639 )
640 @Override
641 public void incrementViewCounter(long threadId, int increment)
642 throws PortalException {
643
644 if (ExportImportThreadLocal.isImportInProcess()) {
645 return;
646 }
647
648 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
649
650 thread.setViewCount(thread.getViewCount() + increment);
651
652 mbThreadPersistence.update(thread);
653 }
654
655 @Override
656 public void moveDependentsToTrash(
657 long groupId, long threadId, long trashEntryId)
658 throws PortalException {
659
660 Set<Long> userIds = new HashSet<>();
661
662 List<MBMessage> messages = mbMessageLocalService.getThreadMessages(
663 threadId, WorkflowConstants.STATUS_ANY);
664
665 for (MBMessage message : messages) {
666
667
668
669 if (message.isDiscussion()) {
670 continue;
671 }
672
673 int oldStatus = message.getStatus();
674
675 message.setStatus(WorkflowConstants.STATUS_IN_TRASH);
676
677 mbMessagePersistence.update(message);
678
679 userIds.add(message.getUserId());
680
681
682
683 int status = oldStatus;
684
685 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
686 status = WorkflowConstants.STATUS_DRAFT;
687 }
688
689 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
690 trashVersionLocalService.addTrashVersion(
691 trashEntryId, MBMessage.class.getName(),
692 message.getMessageId(), status, null);
693 }
694
695
696
697 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
698 assetEntryLocalService.updateVisible(
699 MBMessage.class.getName(), message.getMessageId(), false);
700 }
701
702
703
704 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
705 MBMessage.class);
706
707 indexer.reindex(message);
708
709
710
711 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
712 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
713 message.getCompanyId(), message.getGroupId(),
714 MBMessage.class.getName(), message.getMessageId());
715 }
716 }
717
718
719
720 for (long userId : userIds) {
721 mbStatsUserLocalService.updateStatsUser(groupId, userId);
722 }
723 }
724
725 @Override
726 public MBThread moveThread(long groupId, long categoryId, long threadId)
727 throws PortalException {
728
729 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
730
731 long oldCategoryId = thread.getCategoryId();
732
733 MBCategory oldCategory = null;
734
735 if (oldCategoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
736 oldCategory = mbCategoryPersistence.fetchByPrimaryKey(
737 oldCategoryId);
738 }
739
740 MBCategory category = null;
741
742 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
743 category = mbCategoryPersistence.fetchByPrimaryKey(categoryId);
744 }
745
746
747
748 thread.setCategoryId(categoryId);
749
750 mbThreadPersistence.update(thread);
751
752
753
754 List<MBMessage> messages = mbMessagePersistence.findByG_C_T(
755 groupId, oldCategoryId, thread.getThreadId());
756
757 for (MBMessage message : messages) {
758 message.setCategoryId(categoryId);
759
760 mbMessagePersistence.update(message);
761
762
763
764 if (!message.isDiscussion()) {
765 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
766 MBMessage.class);
767
768 indexer.reindex(message);
769 }
770 }
771
772
773
774 if ((oldCategory != null) && (categoryId != oldCategoryId)) {
775 MBUtil.updateCategoryStatistics(
776 oldCategory.getCompanyId(), oldCategory.getCategoryId());
777 }
778
779 if ((category != null) && (categoryId != oldCategoryId)) {
780 MBUtil.updateCategoryStatistics(
781 category.getCompanyId(), category.getCategoryId());
782 }
783
784
785
786 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
787 MBThread.class);
788
789 indexer.reindex(thread);
790
791 return thread;
792 }
793
794 @Override
795 public MBThread moveThreadFromTrash(
796 long userId, long categoryId, long threadId)
797 throws PortalException {
798
799 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
800
801 if (thread.isInTrashExplicitly()) {
802 restoreThreadFromTrash(userId, threadId);
803 }
804 else {
805
806
807
808 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
809 MBThread.class.getName(), thread.getThreadId());
810
811 int status = WorkflowConstants.STATUS_APPROVED;
812
813 if (trashVersion != null) {
814 status = trashVersion.getStatus();
815 }
816
817 updateStatus(userId, threadId, status);
818
819
820
821 if (trashVersion != null) {
822 trashVersionLocalService.deleteTrashVersion(trashVersion);
823 }
824
825
826
827 restoreDependentsFromTrash(thread.getGroupId(), threadId);
828 }
829
830 return moveThread(thread.getGroupId(), categoryId, threadId);
831 }
832
833 @Override
834 public void moveThreadsToTrash(long groupId, long userId)
835 throws PortalException {
836
837 List<MBThread> threads = mbThreadPersistence.findByGroupId(groupId);
838
839 for (MBThread thread : threads) {
840 moveThreadToTrash(userId, thread);
841 }
842 }
843
844 @Override
845 public MBThread moveThreadToTrash(long userId, long threadId)
846 throws PortalException {
847
848 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
849
850 return moveThreadToTrash(userId, thread);
851 }
852
853 @Override
854 public MBThread moveThreadToTrash(long userId, MBThread thread)
855 throws PortalException {
856
857
858
859 if (thread.getCategoryId() ==
860 MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
861
862 return thread;
863 }
864
865 int oldStatus = thread.getStatus();
866
867 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
868 thread.setStatus(WorkflowConstants.STATUS_DRAFT);
869
870 mbThreadPersistence.update(thread);
871 }
872
873 thread = updateStatus(
874 userId, thread.getThreadId(), WorkflowConstants.STATUS_IN_TRASH);
875
876
877
878 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
879 userId, thread.getGroupId(), MBThread.class.getName(),
880 thread.getThreadId(), thread.getUuid(), null, oldStatus, null,
881 null);
882
883
884
885 moveDependentsToTrash(
886 thread.getGroupId(), thread.getThreadId(), trashEntry.getEntryId());
887
888
889
890 MBMessage message = mbMessageLocalService.getMBMessage(
891 thread.getRootMessageId());
892
893 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
894
895 extraDataJSONObject.put("rootMessageId", thread.getRootMessageId());
896 extraDataJSONObject.put("title", message.getSubject());
897
898 socialActivityLocalService.addActivity(
899 userId, thread.getGroupId(), MBThread.class.getName(),
900 thread.getThreadId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
901 extraDataJSONObject.toString(), 0);
902
903 return thread;
904 }
905
906 @Override
907 public void restoreDependentsFromTrash(long groupId, long threadId)
908 throws PortalException {
909
910 Set<Long> userIds = new HashSet<>();
911
912 List<MBMessage> messages = mbMessageLocalService.getThreadMessages(
913 threadId, WorkflowConstants.STATUS_ANY);
914
915 for (MBMessage message : messages) {
916
917
918
919 if (message.isDiscussion()) {
920 continue;
921 }
922
923 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
924 MBMessage.class.getName(), message.getMessageId());
925
926 int oldStatus = WorkflowConstants.STATUS_APPROVED;
927
928 if (trashVersion != null) {
929 oldStatus = trashVersion.getStatus();
930 }
931
932 message.setStatus(oldStatus);
933
934 mbMessagePersistence.update(message);
935
936 userIds.add(message.getUserId());
937
938
939
940 if (trashVersion != null) {
941 trashVersionLocalService.deleteTrashVersion(trashVersion);
942 }
943
944
945
946 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
947 assetEntryLocalService.updateVisible(
948 MBMessage.class.getName(), message.getMessageId(), true);
949 }
950
951
952
953 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
954 MBMessage.class);
955
956 indexer.reindex(message);
957 }
958
959
960
961 for (long userId : userIds) {
962 mbStatsUserLocalService.updateStatsUser(groupId, userId);
963 }
964 }
965
966
970 @Deprecated
971 @Override
972 public void restoreDependentsFromTrash(
973 long groupId, long threadId, long trashEntryId)
974 throws PortalException {
975
976 restoreDependentsFromTrash(groupId, threadId);
977 }
978
979 @Override
980 public void restoreThreadFromTrash(long userId, long threadId)
981 throws PortalException {
982
983
984
985 MBThread thread = getThread(threadId);
986
987 if (thread.getCategoryId() ==
988 MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
989
990 return;
991 }
992
993 TrashEntry trashEntry = trashEntryLocalService.getEntry(
994 MBThread.class.getName(), threadId);
995
996 updateStatus(userId, threadId, trashEntry.getStatus());
997
998
999
1000 restoreDependentsFromTrash(thread.getGroupId(), threadId);
1001
1002
1003
1004 trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
1005
1006
1007
1008 MBMessage message = mbMessageLocalService.getMBMessage(
1009 thread.getRootMessageId());
1010
1011 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1012
1013 extraDataJSONObject.put("rootMessageId", thread.getRootMessageId());
1014 extraDataJSONObject.put("title", message.getSubject());
1015
1016 socialActivityLocalService.addActivity(
1017 userId, thread.getGroupId(), MBThread.class.getName(),
1018 thread.getThreadId(),
1019 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1020 extraDataJSONObject.toString(), 0);
1021 }
1022
1023 @Override
1024 public Hits search(
1025 long groupId, long userId, long creatorUserId, int status,
1026 int start, int end)
1027 throws PortalException {
1028
1029 return search(groupId, userId, creatorUserId, 0, 0, status, start, end);
1030 }
1031
1032 @Override
1033 public Hits search(
1034 long groupId, long userId, long creatorUserId, long startDate,
1035 long endDate, int status, int start, int end)
1036 throws PortalException {
1037
1038 Indexer indexer = IndexerRegistryUtil.getIndexer(
1039 MBThread.class.getName());
1040
1041 SearchContext searchContext = new SearchContext();
1042
1043 searchContext.setAttribute(Field.STATUS, status);
1044
1045 if (endDate > 0) {
1046 searchContext.setAttribute("endDate", endDate);
1047 }
1048
1049 searchContext.setAttribute("paginationType", "none");
1050
1051 if (creatorUserId > 0) {
1052 searchContext.setAttribute(
1053 "participantUserId", String.valueOf(creatorUserId));
1054 }
1055
1056 if (startDate > 0) {
1057 searchContext.setAttribute("startDate", startDate);
1058 }
1059
1060 Group group = groupLocalService.getGroup(groupId);
1061
1062 searchContext.setCompanyId(group.getCompanyId());
1063
1064 searchContext.setEnd(end);
1065 searchContext.setGroupIds(new long[] {groupId});
1066 searchContext.setSorts(new Sort("lastPostDate", true));
1067 searchContext.setStart(start);
1068 searchContext.setUserId(userId);
1069
1070 return indexer.search(searchContext);
1071 }
1072
1073 @Override
1074 public MBThread splitThread(
1075 long messageId, String subject, ServiceContext serviceContext)
1076 throws PortalException {
1077
1078 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1079
1080 if (message.isRoot()) {
1081 throw new SplitThreadException();
1082 }
1083
1084 MBCategory category = message.getCategory();
1085 MBThread oldThread = message.getThread();
1086 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
1087 oldThread.getRootMessageId());
1088
1089
1090
1091 mbMessageLocalService.updateAnswer(message, false, true);
1092
1093
1094
1095 MBThread thread = addThread(
1096 message.getCategoryId(), message, serviceContext);
1097
1098 mbThreadPersistence.update(oldThread);
1099
1100
1101
1102 if (Validator.isNotNull(subject)) {
1103 MBMessageDisplay messageDisplay =
1104 mbMessageService.getMessageDisplay(
1105 messageId, WorkflowConstants.STATUS_ANY,
1106 MBThreadConstants.THREAD_VIEW_TREE, false);
1107
1108 MBTreeWalker treeWalker = messageDisplay.getTreeWalker();
1109
1110 List<MBMessage> messages = treeWalker.getMessages();
1111
1112 int[] range = treeWalker.getChildrenRange(message);
1113
1114 for (int i = range[0]; i < range[1]; i++) {
1115 MBMessage curMessage = messages.get(i);
1116
1117 String oldSubject = message.getSubject();
1118 String curSubject = curMessage.getSubject();
1119
1120 if (oldSubject.startsWith("RE: ")) {
1121 curSubject = StringUtil.replace(
1122 curSubject, rootMessage.getSubject(), subject);
1123 }
1124 else {
1125 curSubject = StringUtil.replace(
1126 curSubject, oldSubject, subject);
1127 }
1128
1129 curMessage.setSubject(curSubject);
1130
1131 mbMessagePersistence.update(curMessage);
1132 }
1133
1134 message.setSubject(subject);
1135 }
1136
1137 message.setThreadId(thread.getThreadId());
1138 message.setRootMessageId(thread.getRootMessageId());
1139 message.setParentMessageId(0);
1140
1141 mbMessagePersistence.update(message);
1142
1143
1144
1145 if (!message.isDiscussion()) {
1146 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1147 MBMessage.class);
1148
1149 indexer.reindex(message);
1150 }
1151
1152
1153
1154 moveChildrenMessages(message, category, oldThread.getThreadId());
1155
1156
1157
1158 MBUtil.updateThreadMessageCount(
1159 thread.getCompanyId(), thread.getThreadId());
1160
1161
1162
1163 MBUtil.updateThreadMessageCount(
1164 oldThread.getCompanyId(), oldThread.getThreadId());
1165
1166
1167
1168 if ((message.getCategoryId() !=
1169 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1170 (message.getCategoryId() !=
1171 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1172
1173 MBUtil.updateCategoryThreadCount(
1174 category.getCompanyId(), category.getCategoryId());
1175 }
1176
1177
1178
1179 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1180 MBThread.class);
1181
1182 indexer.reindex(oldThread);
1183 indexer.reindex(message.getThread());
1184
1185 return thread;
1186 }
1187
1188 @Override
1189 public void updateQuestion(long threadId, boolean question)
1190 throws PortalException {
1191
1192 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1193
1194 if (thread.isQuestion() == question) {
1195 return;
1196 }
1197
1198 thread.setQuestion(question);
1199
1200 mbThreadPersistence.update(thread);
1201
1202 if (!question) {
1203 MBMessage message = mbMessagePersistence.findByPrimaryKey(
1204 thread.getRootMessageId());
1205
1206 mbMessageLocalService.updateAnswer(message, false, true);
1207 }
1208 }
1209
1210 @Override
1211 public MBThread updateStatus(long userId, long threadId, int status)
1212 throws PortalException {
1213
1214 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1215
1216
1217
1218 User user = userPersistence.findByPrimaryKey(userId);
1219
1220 thread.setStatus(status);
1221 thread.setStatusByUserId(user.getUserId());
1222 thread.setStatusByUserName(user.getFullName());
1223 thread.setStatusDate(new Date());
1224
1225 mbThreadPersistence.update(thread);
1226
1227
1228
1229 if (thread.getCategoryId() !=
1230 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
1231
1232
1233
1234 MBCategory category = mbCategoryPersistence.fetchByPrimaryKey(
1235 thread.getCategoryId());
1236
1237 if (category != null) {
1238 MBUtil.updateCategoryStatistics(
1239 category.getCompanyId(), category.getCategoryId());
1240 }
1241 }
1242
1243
1244
1245 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1246 MBThread.class);
1247
1248 indexer.reindex(thread);
1249
1250 return thread;
1251 }
1252
1253
1257 @Deprecated
1258 @Override
1259 public MBThread updateThread(long threadId, int viewCount)
1260 throws PortalException {
1261
1262 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1263
1264 thread.setViewCount(viewCount);
1265
1266 mbThreadPersistence.update(thread);
1267
1268 return thread;
1269 }
1270
1271 protected void moveChildrenMessages(
1272 MBMessage parentMessage, MBCategory category, long oldThreadId)
1273 throws PortalException {
1274
1275 List<MBMessage> messages = mbMessagePersistence.findByT_P(
1276 oldThreadId, parentMessage.getMessageId());
1277
1278 for (MBMessage message : messages) {
1279 message.setCategoryId(parentMessage.getCategoryId());
1280 message.setThreadId(parentMessage.getThreadId());
1281 message.setRootMessageId(parentMessage.getRootMessageId());
1282
1283 mbMessagePersistence.update(message);
1284
1285 if (!message.isDiscussion()) {
1286 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1287 MBMessage.class);
1288
1289 indexer.reindex(message);
1290 }
1291
1292 moveChildrenMessages(message, category, oldThreadId);
1293 }
1294 }
1295
1296 }