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