001
014
015 package com.liferay.portlet.messageboards.util;
016
017 import com.liferay.portal.kernel.concurrent.PortalCallable;
018 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.portlet.LiferayWindowState;
024 import com.liferay.portal.kernel.sanitizer.Sanitizer;
025 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
026 import com.liferay.portal.kernel.search.Document;
027 import com.liferay.portal.kernel.search.Field;
028 import com.liferay.portal.kernel.search.Hits;
029 import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
030 import com.liferay.portal.kernel.util.CharPool;
031 import com.liferay.portal.kernel.util.ContentTypes;
032 import com.liferay.portal.kernel.util.GetterUtil;
033 import com.liferay.portal.kernel.util.Http;
034 import com.liferay.portal.kernel.util.LocaleUtil;
035 import com.liferay.portal.kernel.util.LocalizationUtil;
036 import com.liferay.portal.kernel.util.ParamUtil;
037 import com.liferay.portal.kernel.util.PropsUtil;
038 import com.liferay.portal.kernel.util.StringBundler;
039 import com.liferay.portal.kernel.util.StringPool;
040 import com.liferay.portal.kernel.util.StringUtil;
041 import com.liferay.portal.kernel.util.Validator;
042 import com.liferay.portal.kernel.workflow.WorkflowConstants;
043 import com.liferay.portal.model.Group;
044 import com.liferay.portal.model.Organization;
045 import com.liferay.portal.model.Role;
046 import com.liferay.portal.model.Subscription;
047 import com.liferay.portal.model.UserGroup;
048 import com.liferay.portal.security.permission.ActionKeys;
049 import com.liferay.portal.security.permission.PermissionChecker;
050 import com.liferay.portal.service.GroupLocalServiceUtil;
051 import com.liferay.portal.service.OrganizationLocalServiceUtil;
052 import com.liferay.portal.service.RoleLocalServiceUtil;
053 import com.liferay.portal.service.SubscriptionLocalServiceUtil;
054 import com.liferay.portal.service.UserGroupLocalServiceUtil;
055 import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
056 import com.liferay.portal.service.UserLocalServiceUtil;
057 import com.liferay.portal.theme.ThemeDisplay;
058 import com.liferay.portal.util.PortalUtil;
059 import com.liferay.portal.util.PropsValues;
060 import com.liferay.portal.util.WebKeys;
061 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
062 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
063 import com.liferay.portlet.messageboards.model.MBBan;
064 import com.liferay.portlet.messageboards.model.MBCategory;
065 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
066 import com.liferay.portlet.messageboards.model.MBMessage;
067 import com.liferay.portlet.messageboards.model.MBMessageConstants;
068 import com.liferay.portlet.messageboards.model.MBStatsUser;
069 import com.liferay.portlet.messageboards.model.MBThread;
070 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
071 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
072 import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
073 import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
074 import com.liferay.util.ContentUtil;
075 import com.liferay.util.mail.JavaMailUtil;
076
077 import java.io.InputStream;
078
079 import java.util.ArrayList;
080 import java.util.Calendar;
081 import java.util.Collections;
082 import java.util.Date;
083 import java.util.HashMap;
084 import java.util.HashSet;
085 import java.util.List;
086 import java.util.Map;
087 import java.util.Set;
088 import java.util.concurrent.Callable;
089
090 import javax.mail.BodyPart;
091 import javax.mail.Message;
092 import javax.mail.Part;
093 import javax.mail.internet.MimeMessage;
094 import javax.mail.internet.MimeMultipart;
095
096 import javax.portlet.PortletPreferences;
097 import javax.portlet.PortletRequest;
098 import javax.portlet.PortletURL;
099 import javax.portlet.RenderResponse;
100
101 import javax.servlet.http.HttpServletRequest;
102
103
106 public class MBUtil {
107
108 public static final String BB_CODE_EDITOR_WYSIWYG_IMPL_KEY =
109 "editor.wysiwyg.portal-web.docroot.html.portlet.message_boards." +
110 "edit_message.bb_code.jsp";
111
112 public static final String MESSAGE_POP_PORTLET_PREFIX = "mb_message.";
113
114 public static void addPortletBreadcrumbEntries(
115 long categoryId, HttpServletRequest request,
116 RenderResponse renderResponse)
117 throws Exception {
118
119 if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
120 (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
121
122 return;
123 }
124
125 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
126 categoryId);
127
128 addPortletBreadcrumbEntries(category, request, renderResponse);
129 }
130
131 public static void addPortletBreadcrumbEntries(
132 MBCategory category, HttpServletRequest request,
133 RenderResponse renderResponse)
134 throws Exception {
135
136 String strutsAction = ParamUtil.getString(request, "struts_action");
137
138 PortletURL portletURL = renderResponse.createRenderURL();
139
140 if (strutsAction.equals("/message_boards/select_category") ||
141 strutsAction.equals("/message_boards_admin/select_category")) {
142
143 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
144 WebKeys.THEME_DISPLAY);
145
146 portletURL.setParameter(
147 "struts_action", "/message_boards/select_category");
148 portletURL.setWindowState(LiferayWindowState.POP_UP);
149
150 PortalUtil.addPortletBreadcrumbEntry(
151 request, themeDisplay.translate("categories"),
152 portletURL.toString());
153 }
154 else {
155 portletURL.setParameter("struts_action", "/message_boards/view");
156 }
157
158 List<MBCategory> ancestorCategories = category.getAncestors();
159
160 Collections.reverse(ancestorCategories);
161
162 for (MBCategory curCategory : ancestorCategories) {
163 portletURL.setParameter(
164 "mbCategoryId", String.valueOf(curCategory.getCategoryId()));
165
166 PortalUtil.addPortletBreadcrumbEntry(
167 request, curCategory.getName(), portletURL.toString());
168 }
169
170 portletURL.setParameter(
171 "mbCategoryId", String.valueOf(category.getCategoryId()));
172
173 PortalUtil.addPortletBreadcrumbEntry(
174 request, category.getName(), portletURL.toString());
175 }
176
177 public static void addPortletBreadcrumbEntries(
178 MBMessage message, HttpServletRequest request,
179 RenderResponse renderResponse)
180 throws Exception {
181
182 if (message.getCategoryId() ==
183 MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
184
185 return;
186 }
187
188 if (message.getCategoryId() !=
189 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
190
191 addPortletBreadcrumbEntries(
192 message.getCategory(), request, renderResponse);
193 }
194
195 PortletURL portletURL = renderResponse.createRenderURL();
196
197 portletURL.setParameter(
198 "struts_action", "/message_boards/view_message");
199 portletURL.setParameter(
200 "messageId", String.valueOf(message.getMessageId()));
201
202 PortalUtil.addPortletBreadcrumbEntry(
203 request, message.getSubject(), portletURL.toString());
204 }
205
206 public static void collectMultipartContent(
207 MimeMultipart multipart, MBMailMessage collector)
208 throws Exception {
209
210 for (int i = 0; i < multipart.getCount(); i++) {
211 BodyPart part = multipart.getBodyPart(i);
212
213 collectPartContent(part, collector);
214 }
215 }
216
217 public static void collectPartContent(
218 Part part, MBMailMessage mbMailMessage)
219 throws Exception {
220
221 Object partContent = part.getContent();
222
223 String contentType = part.getContentType().toLowerCase();
224
225 if ((part.getDisposition() != null) &&
226 part.getDisposition().equalsIgnoreCase(MimeMessage.ATTACHMENT)) {
227
228 if (_log.isDebugEnabled()) {
229 _log.debug("Processing attachment");
230 }
231
232 byte[] bytes = null;
233
234 if (partContent instanceof String) {
235 bytes = ((String)partContent).getBytes();
236 }
237 else if (partContent instanceof InputStream) {
238 bytes = JavaMailUtil.getBytes(part);
239 }
240
241 mbMailMessage.addBytes(part.getFileName(), bytes);
242 }
243 else {
244 if (partContent instanceof MimeMultipart) {
245 MimeMultipart mimeMultipart = (MimeMultipart)partContent;
246
247 collectMultipartContent(mimeMultipart, mbMailMessage);
248 }
249 else if (partContent instanceof String) {
250 Map<String, Object> options = new HashMap<String, Object>();
251
252 options.put("emailPartToMBMessageBody", Boolean.TRUE);
253
254 String messageBody = SanitizerUtil.sanitize(
255 0, 0, 0, MBMessage.class.getName(), 0, contentType,
256 Sanitizer.MODE_ALL, (String)partContent, options);
257
258 if (contentType.startsWith(ContentTypes.TEXT_HTML)) {
259 mbMailMessage.setHtmlBody(messageBody);
260 }
261 else {
262 mbMailMessage.setPlainBody(messageBody);
263 }
264 }
265 }
266 }
267
268 public static String getAbsolutePath(
269 PortletRequest portletRequest, long mbCategoryId)
270 throws PortalException, SystemException {
271
272 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
273 WebKeys.THEME_DISPLAY);
274
275 if (mbCategoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
276 return themeDisplay.translate("home");
277 }
278
279 MBCategory mbCategory = MBCategoryLocalServiceUtil.fetchMBCategory(
280 mbCategoryId);
281
282 List<MBCategory> categories = mbCategory.getAncestors();
283
284 Collections.reverse(categories);
285
286 StringBundler sb = new StringBundler((categories.size() * 3) + 5);
287
288 sb.append(themeDisplay.translate("home"));
289 sb.append(StringPool.SPACE);
290
291 for (MBCategory curCategory : categories) {
292 sb.append(StringPool.RAQUO);
293 sb.append(StringPool.SPACE);
294 sb.append(curCategory.getName());
295 }
296
297 sb.append(StringPool.RAQUO);
298 sb.append(StringPool.SPACE);
299 sb.append(mbCategory.getName());
300
301 return sb.toString();
302 }
303
304 public static long getCategoryId(
305 HttpServletRequest request, MBCategory category) {
306
307 long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
308
309 if (category != null) {
310 categoryId = category.getCategoryId();
311 }
312
313 categoryId = ParamUtil.getLong(request, "mbCategoryId", categoryId);
314
315 return categoryId;
316 }
317
318 public static long getCategoryId(
319 HttpServletRequest request, MBMessage message) {
320
321 long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
322
323 if (message != null) {
324 categoryId = message.getCategoryId();
325 }
326
327 categoryId = ParamUtil.getLong(request, "mbCategoryId", categoryId);
328
329 return categoryId;
330 }
331
332 public static Set<Long> getCategorySubscriptionClassPKs(long userId)
333 throws SystemException {
334
335 List<Subscription> subscriptions =
336 SubscriptionLocalServiceUtil.getUserSubscriptions(
337 userId, MBCategory.class.getName());
338
339 Set<Long> classPKs = new HashSet<Long>(subscriptions.size());
340
341 for (Subscription subscription : subscriptions) {
342 classPKs.add(subscription.getClassPK());
343 }
344
345 return classPKs;
346 }
347
348 public static String getEmailFromAddress(
349 PortletPreferences preferences, long companyId)
350 throws SystemException {
351
352 return PortalUtil.getEmailFromAddress(
353 preferences, companyId,
354 PropsValues.MESSAGE_BOARDS_EMAIL_FROM_ADDRESS);
355 }
356
357 public static String getEmailFromName(
358 PortletPreferences preferences, long companyId)
359 throws SystemException {
360
361 return PortalUtil.getEmailFromName(
362 preferences, companyId, PropsValues.MESSAGE_BOARDS_EMAIL_FROM_NAME);
363 }
364
365 public static boolean getEmailHtmlFormat(PortletPreferences preferences) {
366 String emailHtmlFormat = preferences.getValue(
367 "emailHtmlFormat", StringPool.BLANK);
368
369 if (Validator.isNotNull(emailHtmlFormat)) {
370 return GetterUtil.getBoolean(emailHtmlFormat);
371 }
372 else {
373 return PropsValues.MESSAGE_BOARDS_EMAIL_HTML_FORMAT;
374 }
375 }
376
377 public static String getEmailMessageAddedBody(
378 PortletPreferences preferences) {
379
380 String emailMessageAddedBody = preferences.getValue(
381 "emailMessageAddedBody", StringPool.BLANK);
382
383 if (Validator.isNotNull(emailMessageAddedBody)) {
384 return emailMessageAddedBody;
385 }
386 else {
387 return ContentUtil.get(
388 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_BODY);
389 }
390 }
391
392 public static boolean getEmailMessageAddedEnabled(
393 PortletPreferences preferences) {
394
395 String emailMessageAddedEnabled = preferences.getValue(
396 "emailMessageAddedEnabled", StringPool.BLANK);
397
398 if (Validator.isNotNull(emailMessageAddedEnabled)) {
399 return GetterUtil.getBoolean(emailMessageAddedEnabled);
400 }
401 else {
402 return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_ENABLED;
403 }
404 }
405
406 public static String getEmailMessageAddedSignature(
407 PortletPreferences preferences) {
408
409 String emailMessageAddedSignature = preferences.getValue(
410 "emailMessageAddedSignature", StringPool.BLANK);
411
412 if (Validator.isNotNull(emailMessageAddedSignature)) {
413 return emailMessageAddedSignature;
414 }
415 else {
416 return ContentUtil.get(
417 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SIGNATURE);
418 }
419 }
420
421 public static String getEmailMessageAddedSubjectPrefix(
422 PortletPreferences preferences) {
423
424 String emailMessageAddedSubjectPrefix = preferences.getValue(
425 "emailMessageAddedSubjectPrefix", StringPool.BLANK);
426
427 if (Validator.isNotNull(emailMessageAddedSubjectPrefix)) {
428 return emailMessageAddedSubjectPrefix;
429 }
430 else {
431 return ContentUtil.get(
432 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SUBJECT_PREFIX);
433 }
434 }
435
436 public static String getEmailMessageUpdatedBody(
437 PortletPreferences preferences) {
438
439 String emailMessageUpdatedBody = preferences.getValue(
440 "emailMessageUpdatedBody", StringPool.BLANK);
441
442 if (Validator.isNotNull(emailMessageUpdatedBody)) {
443 return emailMessageUpdatedBody;
444 }
445 else {
446 return ContentUtil.get(
447 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_BODY);
448 }
449 }
450
451 public static boolean getEmailMessageUpdatedEnabled(
452 PortletPreferences preferences) {
453
454 String emailMessageUpdatedEnabled = preferences.getValue(
455 "emailMessageUpdatedEnabled", StringPool.BLANK);
456
457 if (Validator.isNotNull(emailMessageUpdatedEnabled)) {
458 return GetterUtil.getBoolean(emailMessageUpdatedEnabled);
459 }
460 else {
461 return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_ENABLED;
462 }
463 }
464
465 public static String getEmailMessageUpdatedSignature(
466 PortletPreferences preferences) {
467
468 String emailMessageUpdatedSignature = preferences.getValue(
469 "emailMessageUpdatedSignature", StringPool.BLANK);
470
471 if (Validator.isNotNull(emailMessageUpdatedSignature)) {
472 return emailMessageUpdatedSignature;
473 }
474 else {
475 return ContentUtil.get(
476 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SIGNATURE);
477 }
478 }
479
480 public static String getEmailMessageUpdatedSubjectPrefix(
481 PortletPreferences preferences) {
482
483 String emailMessageUpdatedSubject = preferences.getValue(
484 "emailMessageUpdatedSubjectPrefix", StringPool.BLANK);
485
486 if (Validator.isNotNull(emailMessageUpdatedSubject)) {
487 return emailMessageUpdatedSubject;
488 }
489 else {
490 return ContentUtil.get(
491 PropsValues.
492 MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SUBJECT_PREFIX);
493 }
494 }
495
496 public static List<Object> getEntries(Hits hits) {
497 List<Object> entries = new ArrayList<Object>();
498
499 for (Document document : hits.getDocs()) {
500 long categoryId = GetterUtil.getLong(
501 document.get(Field.CATEGORY_ID));
502
503 try {
504 MBCategoryLocalServiceUtil.getCategory(categoryId);
505 }
506 catch (Exception e) {
507 if (_log.isWarnEnabled()) {
508 _log.warn(
509 "Message boards search index is stale and contains " +
510 "category " + categoryId);
511 }
512
513 continue;
514 }
515
516 long threadId = GetterUtil.getLong(document.get("threadId"));
517
518 try {
519 MBThreadLocalServiceUtil.getThread(threadId);
520 }
521 catch (Exception e) {
522 if (_log.isWarnEnabled()) {
523 _log.warn(
524 "Message boards search index is stale and contains " +
525 "thread " + threadId);
526 }
527
528 continue;
529 }
530
531 String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
532 long entryClassPK = GetterUtil.getLong(
533 document.get(Field.ENTRY_CLASS_PK));
534
535 Object obj = null;
536
537 try {
538 if (entryClassName.equals(DLFileEntry.class.getName())) {
539 long classPK = GetterUtil.getLong(
540 document.get(Field.CLASS_PK));
541
542 MBMessageLocalServiceUtil.getMessage(classPK);
543
544 obj = DLFileEntryLocalServiceUtil.getDLFileEntry(
545 entryClassPK);
546 }
547 else if (entryClassName.equals(MBMessage.class.getName())) {
548 obj = MBMessageLocalServiceUtil.getMessage(entryClassPK);
549 }
550
551 entries.add(obj);
552 }
553 catch (Exception e) {
554 if (_log.isWarnEnabled()) {
555 _log.warn(
556 "Message boards search index is stale and contains " +
557 "entry {className=" + entryClassName + ", " +
558 "classPK=" + entryClassPK + "}");
559 }
560
561 continue;
562 }
563 }
564
565 return entries;
566 }
567
568 public static String getMessageFormat(PortletPreferences preferences) {
569 String messageFormat = preferences.getValue(
570 "messageFormat", MBMessageConstants.DEFAULT_FORMAT);
571
572 String editorImpl = PropsUtil.get(BB_CODE_EDITOR_WYSIWYG_IMPL_KEY);
573
574 if (messageFormat.equals("bbcode") &&
575 !(editorImpl.equals("bbcode") ||
576 editorImpl.equals("ckeditor_bbcode"))) {
577
578 messageFormat = "html";
579 }
580
581 return messageFormat;
582 }
583
584 public static long getMessageId(String mailId) {
585 int x = mailId.indexOf(CharPool.LESS_THAN) + 1;
586 int y = mailId.indexOf(CharPool.AT);
587
588 long messageId = 0;
589
590 if ((x > 0 ) && (y != -1)) {
591 String temp = mailId.substring(x, y);
592
593 int z = temp.lastIndexOf(CharPool.PERIOD);
594
595 if (z != -1) {
596 messageId = GetterUtil.getLong(temp.substring(z + 1));
597 }
598 }
599
600 return messageId;
601 }
602
603 public static long getParentMessageId(Message message) throws Exception {
604 long parentMessageId = -1;
605
606 String parentHeader = getParentMessageIdString(message);
607
608 if (parentHeader != null) {
609 if (_log.isDebugEnabled()) {
610 _log.debug("Parent header " + parentHeader);
611 }
612
613 parentMessageId = getMessageId(parentHeader);
614
615 if (_log.isDebugEnabled()) {
616 _log.debug("Previous message id " + parentMessageId);
617 }
618 }
619
620 return parentMessageId;
621 }
622
623 public static String getParentMessageIdString(Message message)
624 throws Exception {
625
626
627
628
629
630
631 String parentHeader = null;
632
633 String[] references = message.getHeader("References");
634
635 if ((references != null) && (references.length > 0)) {
636 String reference = references[0];
637
638 int x = reference.lastIndexOf("<mb.");
639
640 if (x > -1) {
641 int y = reference.indexOf(">", x);
642
643 parentHeader = reference.substring(x, y);
644 }
645 }
646
647 if (parentHeader == null) {
648 String[] inReplyToHeaders = message.getHeader("In-Reply-To");
649
650 if ((inReplyToHeaders != null) && (inReplyToHeaders.length > 0)) {
651 parentHeader = inReplyToHeaders[0];
652 }
653 }
654
655 if (Validator.isNull(parentHeader) ||
656 !parentHeader.startsWith(MESSAGE_POP_PORTLET_PREFIX, 1)) {
657
658 parentHeader = _getParentMessageIdFromSubject(message);
659 }
660
661 return parentHeader;
662 }
663
664 public static String getReplyToAddress(
665 long categoryId, long messageId, String mx,
666 String defaultMailingListAddress) {
667
668 if (PropsValues.POP_SERVER_SUBDOMAIN.length() <= 0) {
669 return defaultMailingListAddress;
670 }
671
672 StringBundler sb = new StringBundler(8);
673
674 sb.append(MESSAGE_POP_PORTLET_PREFIX);
675 sb.append(categoryId);
676 sb.append(StringPool.PERIOD);
677 sb.append(messageId);
678 sb.append(StringPool.AT);
679 sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
680 sb.append(StringPool.PERIOD);
681 sb.append(mx);
682
683 return sb.toString();
684 }
685
686 public static String getSubjectWithoutMessageId(Message message)
687 throws Exception {
688
689 String subject = message.getSubject();
690
691 String parentMessageId = _getParentMessageIdFromSubject(message);
692
693 if (Validator.isNotNull(parentMessageId)) {
694 int pos = subject.indexOf(parentMessageId);
695
696 if (pos != -1) {
697 subject = subject.substring(0, pos);
698 }
699 }
700
701 return subject;
702 }
703
704 public static String[] getThreadPriority(
705 PortletPreferences preferences, String languageId, double value,
706 ThemeDisplay themeDisplay)
707 throws Exception {
708
709 String[] priorities = LocalizationUtil.getPreferencesValues(
710 preferences, "priorities", languageId);
711
712 String[] priorityPair = _findThreadPriority(
713 value, themeDisplay, priorities);
714
715 if (priorityPair == null) {
716 String defaultLanguageId = LocaleUtil.toLanguageId(
717 LocaleUtil.getDefault());
718
719 priorities = LocalizationUtil.getPreferencesValues(
720 preferences, "priorities", defaultLanguageId);
721
722 priorityPair = _findThreadPriority(value, themeDisplay, priorities);
723 }
724
725 return priorityPair;
726 }
727
728 public static Set<Long> getThreadSubscriptionClassPKs(long userId)
729 throws SystemException {
730
731 List<Subscription> subscriptions =
732 SubscriptionLocalServiceUtil.getUserSubscriptions(
733 userId, MBThread.class.getName());
734
735 Set<Long> classPKs = new HashSet<Long>(subscriptions.size());
736
737 for (Subscription subscription : subscriptions) {
738 classPKs.add(subscription.getClassPK());
739 }
740
741 return classPKs;
742 }
743
744 public static Date getUnbanDate(MBBan ban, int expireInterval) {
745 Date banDate = ban.getCreateDate();
746
747 Calendar cal = Calendar.getInstance();
748
749 cal.setTime(banDate);
750
751 cal.add(Calendar.DATE, expireInterval);
752
753 return cal.getTime();
754 }
755
756 public static String getUserRank(
757 PortletPreferences preferences, String languageId, int posts)
758 throws Exception {
759
760 String rank = StringPool.BLANK;
761
762 String[] ranks = LocalizationUtil.getPreferencesValues(
763 preferences, "ranks", languageId);
764
765 for (int i = 0; i < ranks.length; i++) {
766 String[] kvp = StringUtil.split(ranks[i], CharPool.EQUAL);
767
768 String kvpName = kvp[0];
769 int kvpPosts = GetterUtil.getInteger(kvp[1]);
770
771 if (posts >= kvpPosts) {
772 rank = kvpName;
773 }
774 else {
775 break;
776 }
777 }
778
779 return rank;
780 }
781
782 public static String[] getUserRank(
783 PortletPreferences preferences, String languageId,
784 MBStatsUser statsUser)
785 throws Exception {
786
787 String[] rank = {StringPool.BLANK, StringPool.BLANK};
788
789 int maxPosts = 0;
790
791 Group group = GroupLocalServiceUtil.getGroup(statsUser.getGroupId());
792
793 long companyId = group.getCompanyId();
794
795 String[] ranks = LocalizationUtil.getPreferencesValues(
796 preferences, "ranks", languageId);
797
798 for (int i = 0; i < ranks.length; i++) {
799 String[] kvp = StringUtil.split(ranks[i], CharPool.EQUAL);
800
801 String curRank = kvp[0];
802 String curRankValue = kvp[1];
803
804 String[] curRankValueKvp = StringUtil.split(
805 curRankValue, CharPool.COLON);
806
807 if (curRankValueKvp.length <= 1) {
808 int posts = GetterUtil.getInteger(curRankValue);
809
810 if ((posts <= statsUser.getMessageCount()) &&
811 (posts >= maxPosts)) {
812
813 rank[0] = curRank;
814 maxPosts = posts;
815 }
816
817 }
818 else {
819 String entityType = curRankValueKvp[0];
820 String entityValue = curRankValueKvp[1];
821
822 try {
823 if (_isEntityRank(
824 companyId, statsUser, entityType, entityValue)) {
825
826 rank[1] = curRank;
827
828 break;
829 }
830 }
831 catch (Exception e) {
832 if (_log.isWarnEnabled()) {
833 _log.warn(e);
834 }
835 }
836 }
837 }
838
839 return rank;
840 }
841
842 public static boolean hasMailIdHeader(Message message) throws Exception {
843 String[] messageIds = message.getHeader("Message-ID");
844
845 if (messageIds == null) {
846 return false;
847 }
848
849 for (String messageId : messageIds) {
850 if (Validator.isNotNull(PropsValues.POP_SERVER_SUBDOMAIN) &&
851 messageId.contains(PropsValues.POP_SERVER_SUBDOMAIN)) {
852
853 return true;
854 }
855 }
856
857 return false;
858 }
859
860 public static boolean isAllowAnonymousPosting(
861 PortletPreferences preferences) {
862
863 return GetterUtil.getBoolean(
864 preferences.getValue("allowAnonymousPosting", null),
865 PropsValues.MESSAGE_BOARDS_ANONYMOUS_POSTING_ENABLED);
866 }
867
868 public static boolean isViewableMessage(
869 ThemeDisplay themeDisplay, MBMessage message)
870 throws Exception {
871
872 return isViewableMessage(themeDisplay, message, message);
873 }
874
875 public static boolean isViewableMessage(
876 ThemeDisplay themeDisplay, MBMessage message,
877 MBMessage parentMessage)
878 throws Exception {
879
880 PermissionChecker permissionChecker =
881 themeDisplay.getPermissionChecker();
882
883 if (!MBMessagePermission.contains(
884 permissionChecker, parentMessage, ActionKeys.VIEW)) {
885
886 return false;
887 }
888
889 if ((message.getMessageId() != parentMessage.getMessageId()) &&
890 !MBMessagePermission.contains(
891 permissionChecker, message, ActionKeys.VIEW)) {
892
893 return false;
894 }
895
896 if (!message.isApproved() &&
897 !Validator.equals(message.getUserId(), themeDisplay.getUserId()) &&
898 !permissionChecker.isGroupAdmin(themeDisplay.getScopeGroupId())) {
899
900 return false;
901 }
902
903 return true;
904 }
905
906 public static String replaceMessageBodyPaths(
907 ThemeDisplay themeDisplay, String messageBody) {
908
909 return StringUtil.replace(
910 messageBody,
911 new String[] {
912 "@theme_images_path@", "href=\"/", "src=\"/"
913 },
914 new String[] {
915 themeDisplay.getPathThemeImages(),
916 "href=\"" + themeDisplay.getURLPortal() + "/",
917 "src=\"" + themeDisplay.getURLPortal() + "/"
918 });
919 }
920
921 public static void updateCategoryMessageCount(
922 long companyId, final long categoryId) {
923
924 Callable<Void> callable = new PortalCallable<Void>(companyId) {
925
926 @Override
927 protected Void doCall() throws Exception {
928 MBCategory category =
929 MBCategoryLocalServiceUtil.fetchMBCategory(categoryId);
930
931 if (category == null) {
932 return null;
933 }
934
935 int messageCount = _getMessageCount(category);
936
937 category.setMessageCount(messageCount);
938
939 MBCategoryLocalServiceUtil.updateMBCategory(category);
940
941 return null;
942 }
943
944 };
945
946 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
947 }
948
949 public static void updateCategoryStatistics(
950 long companyId, final long categoryId) {
951
952 Callable<Void> callable = new PortalCallable<Void>(companyId) {
953
954 @Override
955 protected Void doCall() throws Exception {
956 MBCategory category =
957 MBCategoryLocalServiceUtil.fetchMBCategory(categoryId);
958
959 if (category == null) {
960 return null;
961 }
962
963 int messageCount = _getMessageCount(category);
964
965 int threadCount =
966 MBThreadLocalServiceUtil.getCategoryThreadsCount(
967 category.getGroupId(), category.getCategoryId(),
968 WorkflowConstants.STATUS_APPROVED);
969
970 category.setMessageCount(messageCount);
971 category.setThreadCount(threadCount);
972
973 MBCategoryLocalServiceUtil.updateMBCategory(category);
974
975 return null;
976 }
977
978 };
979
980 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
981 }
982
983 public static void updateCategoryThreadCount(
984 long companyId, final long categoryId) {
985
986 Callable<Void> callable = new PortalCallable<Void>(companyId) {
987
988 @Override
989 protected Void doCall() throws Exception {
990 MBCategory category =
991 MBCategoryLocalServiceUtil.fetchMBCategory(categoryId);
992
993 if (category == null) {
994 return null;
995 }
996
997 int threadCount =
998 MBThreadLocalServiceUtil.getCategoryThreadsCount(
999 category.getGroupId(), category.getCategoryId(),
1000 WorkflowConstants.STATUS_APPROVED);
1001
1002 category.setThreadCount(threadCount);
1003
1004 MBCategoryLocalServiceUtil.updateMBCategory(category);
1005
1006 return null;
1007 }
1008
1009 };
1010
1011 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
1012 }
1013
1014 public static void updateThreadMessageCount(
1015 long companyId, final long threadId) {
1016
1017 Callable<Void> callable = new PortalCallable<Void>(companyId) {
1018
1019 @Override
1020 protected Void doCall() throws Exception {
1021 MBThread thread = MBThreadLocalServiceUtil.fetchThread(
1022 threadId);
1023
1024 if (thread == null) {
1025 return null;
1026 }
1027
1028 int messageCount =
1029 MBMessageLocalServiceUtil.getThreadMessagesCount(
1030 threadId, WorkflowConstants.STATUS_APPROVED);
1031
1032 thread.setMessageCount(messageCount);
1033
1034 MBThreadLocalServiceUtil.updateMBThread(thread);
1035
1036 return null;
1037 }
1038
1039 };
1040
1041 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
1042 }
1043
1044 private static String[] _findThreadPriority(
1045 double value, ThemeDisplay themeDisplay, String[] priorities) {
1046
1047 for (int i = 0; i < priorities.length; i++) {
1048 String[] priority = StringUtil.split(priorities[i]);
1049
1050 try {
1051 String priorityName = priority[0];
1052 String priorityImage = priority[1];
1053 double priorityValue = GetterUtil.getDouble(priority[2]);
1054
1055 if (value == priorityValue) {
1056 if (!priorityImage.startsWith(Http.HTTP)) {
1057 priorityImage =
1058 themeDisplay.getPathThemeImages() + priorityImage;
1059 }
1060
1061 return new String[] {priorityName, priorityImage};
1062 }
1063 }
1064 catch (Exception e) {
1065 _log.error("Unable to determine thread priority", e);
1066 }
1067 }
1068
1069 return null;
1070 }
1071
1072 private static int _getMessageCount(MBCategory category)
1073 throws SystemException {
1074
1075 int messageCount = MBMessageLocalServiceUtil.getCategoryMessagesCount(
1076 category.getGroupId(), category.getCategoryId(),
1077 WorkflowConstants.STATUS_APPROVED);
1078
1079 QueryDefinition queryDefinition = new QueryDefinition(
1080 WorkflowConstants.STATUS_IN_TRASH);
1081
1082 List<MBThread> threads = MBThreadLocalServiceUtil.getGroupThreads(
1083 category.getGroupId(), queryDefinition);
1084
1085 for (MBThread thread : threads) {
1086 messageCount = messageCount - thread.getMessageCount();
1087 }
1088
1089 return messageCount;
1090 }
1091
1092 private static String _getParentMessageIdFromSubject(Message message)
1093 throws Exception {
1094
1095 if (message.getSubject() == null) {
1096 return null;
1097 }
1098
1099 String parentMessageId = null;
1100
1101 String subject = StringUtil.reverse(message.getSubject());
1102
1103 int pos = subject.indexOf(CharPool.LESS_THAN);
1104
1105 if (pos != -1) {
1106 parentMessageId = StringUtil.reverse(subject.substring(0, pos + 1));
1107 }
1108
1109 return parentMessageId;
1110 }
1111
1112 private static boolean _isEntityRank(
1113 long companyId, MBStatsUser statsUser, String entityType,
1114 String entityValue)
1115 throws Exception {
1116
1117 long groupId = statsUser.getGroupId();
1118 long userId = statsUser.getUserId();
1119
1120 if (entityType.equals("organization-role") ||
1121 entityType.equals("site-role")) {
1122
1123 Role role = RoleLocalServiceUtil.getRole(companyId, entityValue);
1124
1125 if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1126 userId, groupId, role.getRoleId(), true)) {
1127
1128 return true;
1129 }
1130 }
1131 else if (entityType.equals("organization")) {
1132 Organization organization =
1133 OrganizationLocalServiceUtil.getOrganization(
1134 companyId, entityValue);
1135
1136 if (OrganizationLocalServiceUtil.hasUserOrganization(
1137 userId, organization.getOrganizationId(), false, false)) {
1138
1139 return true;
1140 }
1141 }
1142 else if (entityType.equals("regular-role")) {
1143 if (RoleLocalServiceUtil.hasUserRole(
1144 userId, companyId, entityValue, true)) {
1145
1146 return true;
1147 }
1148 }
1149 else if (entityType.equals("user-group")) {
1150 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1151 companyId, entityValue);
1152
1153 if (UserLocalServiceUtil.hasUserGroupUser(
1154 userGroup.getUserGroupId(), userId)) {
1155
1156 return true;
1157 }
1158 }
1159
1160 return false;
1161 }
1162
1163 private static Log _log = LogFactoryUtil.getLog(MBUtil.class);
1164
1165 }