001
014
015 package com.liferay.portlet.blogs.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.json.JSONFactoryUtil;
020 import com.liferay.portal.kernel.json.JSONObject;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.search.Indexer;
024 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
025 import com.liferay.portal.kernel.util.Constants;
026 import com.liferay.portal.kernel.util.ContentTypes;
027 import com.liferay.portal.kernel.util.FileUtil;
028 import com.liferay.portal.kernel.util.GetterUtil;
029 import com.liferay.portal.kernel.util.HtmlUtil;
030 import com.liferay.portal.kernel.util.HttpUtil;
031 import com.liferay.portal.kernel.util.OrderByComparator;
032 import com.liferay.portal.kernel.util.PropsKeys;
033 import com.liferay.portal.kernel.util.SetUtil;
034 import com.liferay.portal.kernel.util.StringBundler;
035 import com.liferay.portal.kernel.util.StringPool;
036 import com.liferay.portal.kernel.util.StringUtil;
037 import com.liferay.portal.kernel.util.Validator;
038 import com.liferay.portal.kernel.util.WebKeys;
039 import com.liferay.portal.kernel.workflow.WorkflowConstants;
040 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
041 import com.liferay.portal.model.Group;
042 import com.liferay.portal.model.ResourceConstants;
043 import com.liferay.portal.model.User;
044 import com.liferay.portal.service.ServiceContext;
045 import com.liferay.portal.service.ServiceContextUtil;
046 import com.liferay.portal.theme.ThemeDisplay;
047 import com.liferay.portal.util.Portal;
048 import com.liferay.portal.util.PortalUtil;
049 import com.liferay.portal.util.PortletKeys;
050 import com.liferay.portal.util.PrefsPropsUtil;
051 import com.liferay.portal.util.PropsValues;
052 import com.liferay.portal.util.SubscriptionSender;
053 import com.liferay.portlet.asset.model.AssetEntry;
054 import com.liferay.portlet.asset.model.AssetLinkConstants;
055 import com.liferay.portlet.blogs.EntryContentException;
056 import com.liferay.portlet.blogs.EntryDisplayDateException;
057 import com.liferay.portlet.blogs.EntrySmallImageNameException;
058 import com.liferay.portlet.blogs.EntrySmallImageSizeException;
059 import com.liferay.portlet.blogs.EntryTitleException;
060 import com.liferay.portlet.blogs.model.BlogsEntry;
061 import com.liferay.portlet.blogs.service.base.BlogsEntryLocalServiceBaseImpl;
062 import com.liferay.portlet.blogs.social.BlogsActivityKeys;
063 import com.liferay.portlet.blogs.util.BlogsUtil;
064 import com.liferay.portlet.blogs.util.LinkbackProducerUtil;
065 import com.liferay.portlet.blogs.util.comparator.EntryDisplayDateComparator;
066
067 import java.io.IOException;
068 import java.io.InputStream;
069
070 import java.util.Date;
071 import java.util.HashMap;
072 import java.util.HashSet;
073 import java.util.List;
074 import java.util.Locale;
075 import java.util.Map;
076 import java.util.Set;
077
078 import javax.portlet.PortletPreferences;
079
080 import javax.servlet.http.HttpServletRequest;
081
082 import net.htmlparser.jericho.Source;
083 import net.htmlparser.jericho.StartTag;
084
085
093 public class BlogsEntryLocalServiceImpl extends BlogsEntryLocalServiceBaseImpl {
094
095 @Override
096 public BlogsEntry addEntry(
097 long userId, String title, String description, String content,
098 int displayDateMonth, int displayDateDay, int displayDateYear,
099 int displayDateHour, int displayDateMinute, boolean allowPingbacks,
100 boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
101 String smallImageURL, String smallImageFileName,
102 InputStream smallImageInputStream, ServiceContext serviceContext)
103 throws PortalException, SystemException {
104
105
106
107 User user = userPersistence.findByPrimaryKey(userId);
108 long groupId = serviceContext.getScopeGroupId();
109
110 Date displayDate = PortalUtil.getDate(
111 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
112 displayDateMinute, user.getTimeZone(),
113 EntryDisplayDateException.class);
114
115 byte[] smallImageBytes = null;
116
117 try {
118 if ((smallImageInputStream != null) && smallImage) {
119 smallImageBytes = FileUtil.getBytes(smallImageInputStream);
120 }
121 }
122 catch (IOException ioe) {
123 }
124
125 Date now = new Date();
126
127 validate(
128 title, content, smallImage, smallImageURL, smallImageFileName,
129 smallImageBytes);
130
131 long entryId = counterLocalService.increment();
132
133 BlogsEntry entry = blogsEntryPersistence.create(entryId);
134
135 entry.setUuid(serviceContext.getUuid());
136 entry.setGroupId(groupId);
137 entry.setCompanyId(user.getCompanyId());
138 entry.setUserId(user.getUserId());
139 entry.setUserName(user.getFullName());
140 entry.setCreateDate(serviceContext.getCreateDate(now));
141 entry.setModifiedDate(serviceContext.getModifiedDate(now));
142 entry.setTitle(title);
143 entry.setUrlTitle(
144 getUniqueUrlTitle(entryId, title, null, serviceContext));
145 entry.setDescription(description);
146 entry.setContent(content);
147 entry.setDisplayDate(displayDate);
148 entry.setAllowPingbacks(allowPingbacks);
149 entry.setAllowTrackbacks(allowTrackbacks);
150 entry.setSmallImage(smallImage);
151 entry.setSmallImageId(counterLocalService.increment());
152 entry.setSmallImageURL(smallImageURL);
153 entry.setStatus(WorkflowConstants.STATUS_DRAFT);
154 entry.setStatusDate(serviceContext.getModifiedDate(now));
155 entry.setExpandoBridgeAttributes(serviceContext);
156
157 blogsEntryPersistence.update(entry, false);
158
159
160
161 if (serviceContext.isAddGroupPermissions() ||
162 serviceContext.isAddGuestPermissions()) {
163
164 addEntryResources(
165 entry, serviceContext.isAddGroupPermissions(),
166 serviceContext.isAddGuestPermissions());
167 }
168 else {
169 addEntryResources(
170 entry, serviceContext.getGroupPermissions(),
171 serviceContext.getGuestPermissions());
172 }
173
174
175
176 saveImages(smallImage, entry.getSmallImageId(), smallImageBytes);
177
178
179
180 updateAsset(
181 userId, entry, serviceContext.getAssetCategoryIds(),
182 serviceContext.getAssetTagNames(),
183 serviceContext.getAssetLinkEntryIds());
184
185
186
187 if (PropsValues.BLOGS_ENTRY_COMMENTS_ENABLED) {
188 mbMessageLocalService.addDiscussionMessage(
189 userId, entry.getUserName(), groupId,
190 BlogsEntry.class.getName(), entryId,
191 WorkflowConstants.ACTION_PUBLISH);
192 }
193
194
195
196 if ((trackbacks != null) && (trackbacks.length > 0)) {
197 serviceContext.setAttribute("trackbacks", trackbacks);
198 }
199 else {
200 serviceContext.setAttribute("trackbacks", null);
201 }
202
203 WorkflowHandlerRegistryUtil.startWorkflowInstance(
204 user.getCompanyId(), groupId, userId, BlogsEntry.class.getName(),
205 entry.getEntryId(), entry, serviceContext);
206
207 return entry;
208 }
209
210 @Override
211 public void addEntryResources(
212 BlogsEntry entry, boolean addGroupPermissions,
213 boolean addGuestPermissions)
214 throws PortalException, SystemException {
215
216 resourceLocalService.addResources(
217 entry.getCompanyId(), entry.getGroupId(), entry.getUserId(),
218 BlogsEntry.class.getName(), entry.getEntryId(), false,
219 addGroupPermissions, addGuestPermissions);
220 }
221
222 @Override
223 public void addEntryResources(
224 BlogsEntry entry, String[] groupPermissions,
225 String[] guestPermissions)
226 throws PortalException, SystemException {
227
228 resourceLocalService.addModelResources(
229 entry.getCompanyId(), entry.getGroupId(), entry.getUserId(),
230 BlogsEntry.class.getName(), entry.getEntryId(), groupPermissions,
231 guestPermissions);
232 }
233
234 @Override
235 public void addEntryResources(
236 long entryId, boolean addGroupPermissions,
237 boolean addGuestPermissions)
238 throws PortalException, SystemException {
239
240 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(entryId);
241
242 addEntryResources(entry, addGroupPermissions, addGuestPermissions);
243 }
244
245 @Override
246 public void addEntryResources(
247 long entryId, String[] groupPermissions, String[] guestPermissions)
248 throws PortalException, SystemException {
249
250 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(entryId);
251
252 addEntryResources(entry, groupPermissions, guestPermissions);
253 }
254
255 @Override
256 public void checkEntries() throws PortalException, SystemException {
257 Date now = new Date();
258
259 int count = blogsEntryPersistence.countByLtD_S(
260 now, WorkflowConstants.STATUS_SCHEDULED);
261
262 if (count == 0) {
263 return;
264 }
265
266 List<BlogsEntry> entries = blogsEntryPersistence.findByLtD_S(
267 now, WorkflowConstants.STATUS_SCHEDULED);
268
269 for (BlogsEntry entry : entries) {
270 ServiceContext serviceContext = new ServiceContext();
271
272 String[] trackbacks = StringUtil.split(entry.getTrackbacks());
273
274 serviceContext.setAttribute("trackbacks", trackbacks);
275
276 serviceContext.setCommand(Constants.UPDATE);
277
278 String layoutFullURL = PortalUtil.getLayoutFullURL(
279 entry.getGroupId(), PortletKeys.BLOGS);
280
281 serviceContext.setLayoutFullURL(layoutFullURL);
282
283 serviceContext.setScopeGroupId(entry.getGroupId());
284
285 updateStatus(
286 entry.getStatusByUserId(), entry.getEntryId(),
287 WorkflowConstants.STATUS_APPROVED, serviceContext);
288 }
289 }
290
291 @Override
292 public void deleteEntries(long groupId)
293 throws PortalException, SystemException {
294
295 for (BlogsEntry entry : blogsEntryPersistence.findByGroupId(groupId)) {
296 deleteEntry(entry);
297 }
298 }
299
300 @Override
301 public void deleteEntry(BlogsEntry entry)
302 throws PortalException, SystemException {
303
304
305
306 blogsEntryPersistence.remove(entry);
307
308
309
310 resourceLocalService.deleteResource(
311 entry.getCompanyId(), BlogsEntry.class.getName(),
312 ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
313
314
315
316 imageLocalService.deleteImage(entry.getSmallImageId());
317
318
319
320 subscriptionLocalService.deleteSubscriptions(
321 entry.getCompanyId(), BlogsEntry.class.getName(),
322 entry.getEntryId());
323
324
325
326 blogsStatsUserLocalService.updateStatsUser(
327 entry.getGroupId(), entry.getUserId(), entry.getDisplayDate());
328
329
330
331 assetEntryLocalService.deleteEntry(
332 BlogsEntry.class.getName(), entry.getEntryId());
333
334
335
336 expandoValueLocalService.deleteValues(
337 BlogsEntry.class.getName(), entry.getEntryId());
338
339
340
341 mbMessageLocalService.deleteDiscussionMessages(
342 BlogsEntry.class.getName(), entry.getEntryId());
343
344
345
346 ratingsStatsLocalService.deleteStats(
347 BlogsEntry.class.getName(), entry.getEntryId());
348
349
350
351 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
352 BlogsEntry.class);
353
354 indexer.delete(entry);
355
356
357
358 workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
359 entry.getCompanyId(), entry.getGroupId(),
360 BlogsEntry.class.getName(), entry.getEntryId());
361 }
362
363 @Override
364 public void deleteEntry(long entryId)
365 throws PortalException, SystemException {
366
367 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(entryId);
368
369 deleteEntry(entry);
370 }
371
372 @Override
373 public List<BlogsEntry> getCompanyEntries(
374 long companyId, Date displayDate, int status, int start, int end)
375 throws SystemException {
376
377 if (status == WorkflowConstants.STATUS_ANY) {
378 return blogsEntryPersistence.findByC_LtD(
379 companyId, displayDate, start, end);
380 }
381 else {
382 return blogsEntryPersistence.findByC_LtD_S(
383 companyId, displayDate, status, start, end);
384 }
385 }
386
387 @Override
388 public List<BlogsEntry> getCompanyEntries(
389 long companyId, Date displayDate, int status, int start, int end,
390 OrderByComparator obc)
391 throws SystemException {
392
393 if (status == WorkflowConstants.STATUS_ANY) {
394 return blogsEntryPersistence.findByC_LtD(
395 companyId, displayDate, start, end, obc);
396 }
397 else {
398 return blogsEntryPersistence.findByC_LtD_S(
399 companyId, displayDate, status, start, end, obc);
400 }
401 }
402
403 @Override
404 public int getCompanyEntriesCount(
405 long companyId, Date displayDate, int status)
406 throws SystemException {
407
408 if (status == WorkflowConstants.STATUS_ANY) {
409 return blogsEntryPersistence.countByC_LtD(companyId, displayDate);
410 }
411 else {
412 return blogsEntryPersistence.countByC_LtD_S(
413 companyId, displayDate, status);
414 }
415 }
416
417 @Override
418 public BlogsEntry[] getEntriesPrevAndNext(long entryId)
419 throws PortalException, SystemException {
420
421 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(entryId);
422
423 return blogsEntryPersistence.findByG_S_PrevAndNext(
424 entry.getEntryId(), entry.getGroupId(),
425 WorkflowConstants.STATUS_APPROVED,
426 new EntryDisplayDateComparator(true));
427 }
428
429 @Override
430 public BlogsEntry getEntry(long entryId)
431 throws PortalException, SystemException {
432
433 return blogsEntryPersistence.findByPrimaryKey(entryId);
434 }
435
436 @Override
437 public BlogsEntry getEntry(long groupId, String urlTitle)
438 throws PortalException, SystemException {
439
440 return blogsEntryPersistence.findByG_UT(groupId, urlTitle);
441 }
442
443 @Override
444 public List<BlogsEntry> getGroupEntries(
445 long groupId, Date displayDate, int status, int start, int end)
446 throws SystemException {
447
448 if (status == WorkflowConstants.STATUS_ANY) {
449 return blogsEntryPersistence.findByG_LtD(
450 groupId, displayDate, start, end);
451 }
452 else {
453 return blogsEntryPersistence.findByG_LtD_S(
454 groupId, displayDate, status, start, end);
455 }
456 }
457
458 @Override
459 public List<BlogsEntry> getGroupEntries(
460 long groupId, Date displayDate, int status, int start, int end,
461 OrderByComparator obc)
462 throws SystemException {
463
464 if (status == WorkflowConstants.STATUS_ANY) {
465 return blogsEntryPersistence.findByG_LtD(
466 groupId, displayDate, start, end, obc);
467 }
468 else {
469 return blogsEntryPersistence.findByG_LtD_S(
470 groupId, displayDate, status, start, end, obc);
471 }
472 }
473
474 @Override
475 public List<BlogsEntry> getGroupEntries(
476 long groupId, int status, int start, int end)
477 throws SystemException {
478
479 if (status == WorkflowConstants.STATUS_ANY) {
480 return blogsEntryPersistence.findByGroupId(groupId, start, end);
481 }
482 else {
483 return blogsEntryPersistence.findByG_S(groupId, status, start, end);
484 }
485 }
486
487 @Override
488 public List<BlogsEntry> getGroupEntries(
489 long groupId, int status, int start, int end, OrderByComparator obc)
490 throws SystemException {
491
492 if (status == WorkflowConstants.STATUS_ANY) {
493 return blogsEntryPersistence.findByGroupId(
494 groupId, start, end, obc);
495 }
496 else {
497 return blogsEntryPersistence.findByG_S(
498 groupId, status, start, end, obc);
499 }
500 }
501
502 @Override
503 public int getGroupEntriesCount(long groupId, Date displayDate, int status)
504 throws SystemException {
505
506 if (status == WorkflowConstants.STATUS_ANY) {
507 return blogsEntryPersistence.countByG_LtD(groupId, displayDate);
508 }
509 else {
510 return blogsEntryPersistence.countByG_LtD_S(
511 groupId, displayDate, status);
512 }
513 }
514
515 @Override
516 public int getGroupEntriesCount(long groupId, int status)
517 throws SystemException {
518
519 if (status == WorkflowConstants.STATUS_ANY) {
520 return blogsEntryPersistence.countByGroupId(groupId);
521 }
522 else {
523 return blogsEntryPersistence.countByG_S(groupId, status);
524 }
525 }
526
527 @Override
528 public List<BlogsEntry> getGroupsEntries(
529 long companyId, long groupId, Date displayDate, int status,
530 int start, int end)
531 throws SystemException {
532
533 return blogsEntryFinder.findByGroupIds(
534 companyId, groupId, displayDate, status, start, end);
535 }
536
537 @Override
538 public List<BlogsEntry> getGroupUserEntries(
539 long groupId, long userId, Date displayDate, int status, int start,
540 int end)
541 throws SystemException {
542
543 if (status == WorkflowConstants.STATUS_ANY) {
544 return blogsEntryPersistence.findByG_U_LtD(
545 groupId, userId, displayDate, start, end);
546 }
547 else {
548 return blogsEntryPersistence.findByG_U_LtD_S(
549 groupId, userId, displayDate, status, start, end);
550 }
551 }
552
553 @Override
554 public List<BlogsEntry> getGroupUserEntries(
555 long groupId, long userId, Date displayDate, int status, int start,
556 int end, OrderByComparator obc)
557 throws SystemException {
558
559 if (status == WorkflowConstants.STATUS_ANY) {
560 return blogsEntryPersistence.findByG_U_LtD(
561 groupId, userId, displayDate, start, end, obc);
562 }
563 else {
564 return blogsEntryPersistence.findByG_U_LtD_S(
565 groupId, userId, displayDate, status, start, end, obc);
566 }
567 }
568
569 @Override
570 public int getGroupUserEntriesCount(
571 long groupId, long userId, Date displayDate, int status)
572 throws SystemException {
573
574 if (status == WorkflowConstants.STATUS_ANY) {
575 return blogsEntryPersistence.countByG_U_LtD(
576 groupId, userId, displayDate);
577 }
578 else {
579 return blogsEntryPersistence.countByG_U_LtD_S(
580 groupId, userId, displayDate, status);
581 }
582 }
583
584 @Override
585 public List<BlogsEntry> getNoAssetEntries() throws SystemException {
586 return blogsEntryFinder.findByNoAssets();
587 }
588
589 @Override
590 public List<BlogsEntry> getOrganizationEntries(
591 long organizationId, Date displayDate, int status, int start,
592 int end)
593 throws SystemException {
594
595 return blogsEntryFinder.findByOrganizationId(
596 organizationId, displayDate, status, start, end, null);
597 }
598
599 @Override
600 public List<BlogsEntry> getOrganizationEntries(
601 long organizationId, Date displayDate, int status, int start,
602 int end, OrderByComparator obc)
603 throws SystemException {
604
605 return blogsEntryFinder.findByOrganizationId(
606 organizationId, displayDate, status, start, end, obc);
607 }
608
609 @Override
610 public int getOrganizationEntriesCount(
611 long organizationId, Date displayDate, int status)
612 throws SystemException {
613
614 return blogsEntryFinder.countByOrganizationId(
615 organizationId, displayDate, status);
616 }
617
618 @Override
619 public void subscribe(long userId, long groupId)
620 throws PortalException, SystemException {
621
622 subscriptionLocalService.addSubscription(
623 userId, groupId, BlogsEntry.class.getName(), groupId);
624 }
625
626 @Override
627 public void unsubscribe(long userId, long groupId)
628 throws PortalException, SystemException {
629
630 subscriptionLocalService.deleteSubscription(
631 userId, BlogsEntry.class.getName(), groupId);
632 }
633
634 @Override
635 public void updateAsset(
636 long userId, BlogsEntry entry, long[] assetCategoryIds,
637 String[] assetTagNames, long[] assetLinkEntryIds)
638 throws PortalException, SystemException {
639
640 boolean visible = false;
641
642 if (entry.isApproved()) {
643 visible = true;
644 }
645
646 String summary = HtmlUtil.extractText(
647 StringUtil.shorten(entry.getContent(), 500));
648
649 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
650 userId, entry.getGroupId(), entry.getCreateDate(),
651 entry.getModifiedDate(), BlogsEntry.class.getName(),
652 entry.getEntryId(), entry.getUuid(), 0, assetCategoryIds,
653 assetTagNames, visible, null, null, entry.getDisplayDate(), null,
654 ContentTypes.TEXT_HTML, entry.getTitle(), entry.getDescription(),
655 summary, null, null, 0, 0, null, false);
656
657 assetLinkLocalService.updateLinks(
658 userId, assetEntry.getEntryId(), assetLinkEntryIds,
659 AssetLinkConstants.TYPE_RELATED);
660 }
661
662 @Override
663 public BlogsEntry updateEntry(
664 long userId, long entryId, String title, String description,
665 String content, int displayDateMonth, int displayDateDay,
666 int displayDateYear, int displayDateHour, int displayDateMinute,
667 boolean allowPingbacks, boolean allowTrackbacks,
668 String[] trackbacks, boolean smallImage, String smallImageURL,
669 String smallImageFileName, InputStream smallImageInputStream,
670 ServiceContext serviceContext)
671 throws PortalException, SystemException {
672
673
674
675 User user = userPersistence.findByPrimaryKey(userId);
676
677 Date displayDate = PortalUtil.getDate(
678 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
679 displayDateMinute, user.getTimeZone(),
680 EntryDisplayDateException.class);
681
682 byte[] smallImageBytes = null;
683
684 try {
685 if ((smallImageInputStream != null) && smallImage) {
686 smallImageBytes = FileUtil.getBytes(smallImageInputStream);
687 }
688 }
689 catch (IOException ioe) {
690 }
691
692 validate(
693 title, content, smallImage, smallImageURL, smallImageFileName,
694 smallImageBytes);
695
696 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(entryId);
697
698 String oldUrlTitle = entry.getUrlTitle();
699
700 entry.setModifiedDate(serviceContext.getModifiedDate(null));
701 entry.setTitle(title);
702 entry.setUrlTitle(
703 getUniqueUrlTitle(entryId, title, oldUrlTitle, serviceContext));
704 entry.setDescription(description);
705 entry.setContent(content);
706 entry.setDisplayDate(displayDate);
707 entry.setAllowPingbacks(allowPingbacks);
708 entry.setAllowTrackbacks(allowTrackbacks);
709 entry.setSmallImage(smallImage);
710
711 if (entry.getSmallImageId() == 0) {
712 entry.setSmallImageId(counterLocalService.increment());
713 }
714
715 entry.setSmallImageURL(smallImageURL);
716
717 if (entry.isPending() || entry.isDraft()) {
718 }
719 else if (entry.isApproved()) {
720 entry.setStatus(WorkflowConstants.STATUS_DRAFT_FROM_APPROVED);
721 }
722 else {
723 entry.setStatus(WorkflowConstants.STATUS_DRAFT);
724 }
725
726 entry.setExpandoBridgeAttributes(serviceContext);
727
728 blogsEntryPersistence.update(entry, false);
729
730
731
732 if ((serviceContext.getGroupPermissions() != null) ||
733 (serviceContext.getGuestPermissions() != null)) {
734
735 updateEntryResources(
736 entry, serviceContext.getGroupPermissions(),
737 serviceContext.getGuestPermissions());
738 }
739
740
741
742 saveImages(smallImage, entry.getSmallImageId(), smallImageBytes);
743
744
745
746 updateAsset(
747 userId, entry, serviceContext.getAssetCategoryIds(),
748 serviceContext.getAssetTagNames(),
749 serviceContext.getAssetLinkEntryIds());
750
751
752
753 boolean pingOldTrackbacks = false;
754
755 if (!oldUrlTitle.equals(entry.getUrlTitle())) {
756 pingOldTrackbacks = true;
757 }
758
759 serviceContext.setAttribute(
760 "pingOldTrackbacks", String.valueOf(pingOldTrackbacks));
761
762 if (Validator.isNotNull(trackbacks)) {
763 serviceContext.setAttribute("trackbacks", trackbacks);
764 }
765 else {
766 serviceContext.setAttribute("trackbacks", null);
767 }
768
769 WorkflowHandlerRegistryUtil.startWorkflowInstance(
770 user.getCompanyId(), entry.getGroupId(), userId,
771 BlogsEntry.class.getName(), entry.getEntryId(), entry,
772 serviceContext);
773
774 return entry;
775 }
776
777 @Override
778 public void updateEntryResources(
779 BlogsEntry entry, String[] groupPermissions,
780 String[] guestPermissions)
781 throws PortalException, SystemException {
782
783 resourceLocalService.updateResources(
784 entry.getCompanyId(), entry.getGroupId(),
785 BlogsEntry.class.getName(), entry.getEntryId(), groupPermissions,
786 guestPermissions);
787 }
788
789 @Override
790 public BlogsEntry updateStatus(
791 long userId, long entryId, int status,
792 ServiceContext serviceContext)
793 throws PortalException, SystemException {
794
795
796
797 User user = userPersistence.findByPrimaryKey(userId);
798 Date now = new Date();
799
800 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(entryId);
801
802 int oldStatus = entry.getStatus();
803
804 if (oldStatus == WorkflowConstants.STATUS_DRAFT) {
805 serviceContext.setCommand(Constants.ADD);
806 }
807
808 if ((status == WorkflowConstants.STATUS_APPROVED) &&
809 now.before(entry.getDisplayDate())) {
810
811 status = WorkflowConstants.STATUS_SCHEDULED;
812 }
813
814 entry.setModifiedDate(serviceContext.getModifiedDate(now));
815 entry.setStatus(status);
816 entry.setStatusByUserId(user.getUserId());
817 entry.setStatusByUserName(user.getFullName());
818 entry.setStatusDate(serviceContext.getModifiedDate(now));
819
820 blogsEntryPersistence.update(entry, false);
821
822
823
824 blogsStatsUserLocalService.updateStatsUser(
825 entry.getGroupId(), user.getUserId(), entry.getDisplayDate());
826
827 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
828 BlogsEntry.class);
829
830 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
831
832 extraDataJSONObject.put("title", entry.getTitle());
833
834 if (status == WorkflowConstants.STATUS_APPROVED) {
835
836
837
838 assetEntryLocalService.updateVisible(
839 BlogsEntry.class.getName(), entryId, true);
840
841
842
843 if (oldStatus != WorkflowConstants.STATUS_SCHEDULED) {
844 if (serviceContext.isCommandUpdate()) {
845 socialActivityLocalService.addActivity(
846 user.getUserId(), entry.getGroupId(),
847 BlogsEntry.class.getName(), entryId,
848 BlogsActivityKeys.UPDATE_ENTRY,
849 extraDataJSONObject.toString(), 0);
850 }
851 else {
852 socialActivityLocalService.addUniqueActivity(
853 user.getUserId(), entry.getGroupId(),
854 BlogsEntry.class.getName(), entryId,
855 BlogsActivityKeys.ADD_ENTRY,
856 extraDataJSONObject.toString(), 0);
857 }
858 }
859
860
861
862 indexer.reindex(entry);
863
864
865
866 notifySubscribers(entry, serviceContext);
867
868
869
870 String[] trackbacks = (String[])serviceContext.getAttribute(
871 "trackbacks");
872 Boolean pingOldTrackbacks = GetterUtil.getBoolean(
873 (String)serviceContext.getAttribute("pingOldTrackbacks"));
874
875 pingGoogle(entry, serviceContext);
876 pingPingback(entry, serviceContext);
877 pingTrackbacks(
878 entry, trackbacks, pingOldTrackbacks, serviceContext);
879 }
880 else {
881
882
883
884 assetEntryLocalService.updateVisible(
885 BlogsEntry.class.getName(), entryId, false);
886
887
888
889 if (status == WorkflowConstants.STATUS_SCHEDULED) {
890 if (serviceContext.isCommandUpdate()) {
891 socialActivityLocalService.addActivity(
892 user.getUserId(), entry.getGroupId(),
893 BlogsEntry.class.getName(), entryId,
894 BlogsActivityKeys.UPDATE_ENTRY,
895 extraDataJSONObject.toString(), 0);
896 }
897 else {
898 socialActivityLocalService.addUniqueActivity(
899 user.getUserId(), entry.getGroupId(),
900 BlogsEntry.class.getName(), entryId,
901 BlogsActivityKeys.ADD_ENTRY,
902 extraDataJSONObject.toString(), 0);
903 }
904 }
905
906
907
908 indexer.delete(entry);
909 }
910
911 return entry;
912 }
913
914 protected String getUniqueUrlTitle(long entryId, long groupId, String title)
915 throws SystemException {
916
917 String urlTitle = BlogsUtil.getUrlTitle(entryId, title);
918
919 for (int i = 1;; i++) {
920 BlogsEntry entry = blogsEntryPersistence.fetchByG_UT(
921 groupId, urlTitle);
922
923 if ((entry == null) || (entryId == entry.getEntryId())) {
924 break;
925 }
926 else {
927 String suffix = StringPool.DASH + i;
928
929 String prefix = urlTitle;
930
931 if (urlTitle.length() > suffix.length()) {
932 prefix = urlTitle.substring(
933 0, urlTitle.length() - suffix.length());
934 }
935
936 urlTitle = prefix + suffix;
937 }
938 }
939
940 return urlTitle;
941 }
942
943 protected String getUniqueUrlTitle(
944 long entryId, String title, String oldUrlTitle,
945 ServiceContext serviceContext)
946 throws SystemException {
947
948 String serviceContextUrlTitle = GetterUtil.getString(
949 serviceContext.getAttribute("urlTitle"));
950
951 String urlTitle = null;
952
953 if (Validator.isNotNull(serviceContextUrlTitle)) {
954 urlTitle = BlogsUtil.getUrlTitle(entryId, serviceContextUrlTitle);
955 }
956 else if (Validator.isNotNull(oldUrlTitle)) {
957 return oldUrlTitle;
958 }
959 else {
960 urlTitle = getUniqueUrlTitle(
961 entryId, serviceContext.getScopeGroupId(), title);
962 }
963
964 BlogsEntry urlTitleEntry = blogsEntryPersistence.fetchByG_UT(
965 serviceContext.getScopeGroupId(), urlTitle);
966
967 if ((urlTitleEntry != null) &&
968 (urlTitleEntry.getEntryId() != entryId)) {
969
970 urlTitle = getUniqueUrlTitle(
971 entryId, serviceContext.getScopeGroupId(), urlTitle);
972 }
973
974 return urlTitle;
975 }
976
977 protected void notifySubscribers(
978 BlogsEntry entry, ServiceContext serviceContext)
979 throws SystemException {
980
981 if (!entry.isApproved()) {
982 return;
983 }
984
985 String layoutFullURL = serviceContext.getLayoutFullURL();
986
987 if (Validator.isNull(layoutFullURL)) {
988 return;
989 }
990
991 PortletPreferences preferences =
992 ServiceContextUtil.getPortletPreferences(serviceContext);
993
994 if (preferences == null) {
995 long ownerId = entry.getGroupId();
996 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
997 long plid = PortletKeys.PREFS_PLID_SHARED;
998 String portletId = PortletKeys.BLOGS;
999 String defaultPreferences = null;
1000
1001 preferences = portletPreferencesLocalService.getPreferences(
1002 entry.getCompanyId(), ownerId, ownerType, plid, portletId,
1003 defaultPreferences);
1004 }
1005
1006 if (serviceContext.isCommandAdd() &&
1007 BlogsUtil.getEmailEntryAddedEnabled(preferences)) {
1008 }
1009 else if (serviceContext.isCommandUpdate() &&
1010 BlogsUtil.getEmailEntryUpdatedEnabled(preferences)) {
1011 }
1012 else {
1013 return;
1014 }
1015
1016 String entryURL =
1017 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs" +
1018 StringPool.SLASH + entry.getEntryId();
1019
1020 String fromName = BlogsUtil.getEmailFromName(
1021 preferences, entry.getCompanyId());
1022 String fromAddress = BlogsUtil.getEmailFromAddress(
1023 preferences, entry.getCompanyId());
1024
1025 Map<Locale, String> localizedSubjectMap = null;
1026 Map<Locale, String> localizedBodyMap = null;
1027
1028 if (serviceContext.isCommandUpdate()) {
1029 localizedSubjectMap = BlogsUtil.getEmailEntryUpdatedSubjectMap(
1030 preferences);
1031 localizedBodyMap = BlogsUtil.getEmailEntryUpdatedBodyMap(
1032 preferences);
1033 }
1034 else {
1035 localizedSubjectMap = BlogsUtil.getEmailEntryAddedSubjectMap(
1036 preferences);
1037 localizedBodyMap = BlogsUtil.getEmailEntryAddedBodyMap(preferences);
1038 }
1039
1040 SubscriptionSender subscriptionSender = new SubscriptionSender();
1041
1042 subscriptionSender.setCompanyId(entry.getCompanyId());
1043 subscriptionSender.setContextAttributes(
1044 "[$BLOGS_ENTRY_STATUS_BY_USER_NAME$]", entry.getStatusByUserName(),
1045 "[$BLOGS_ENTRY_URL$]", entryURL);
1046 subscriptionSender.setContextUserPrefix("BLOGS_ENTRY");
1047 subscriptionSender.setFrom(fromAddress, fromName);
1048 subscriptionSender.setHtmlFormat(true);
1049 subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
1050 subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
1051 subscriptionSender.setMailId("blogs_entry", entry.getEntryId());
1052 subscriptionSender.setPortletId(PortletKeys.BLOGS);
1053 subscriptionSender.setReplyToAddress(fromAddress);
1054 subscriptionSender.setScopeGroupId(entry.getGroupId());
1055 subscriptionSender.setServiceContext(serviceContext);
1056 subscriptionSender.setUserId(entry.getUserId());
1057
1058 subscriptionSender.addPersistedSubscribers(
1059 BlogsEntry.class.getName(), entry.getGroupId());
1060
1061 subscriptionSender.flushNotificationsAsync();
1062 }
1063
1064 protected void pingGoogle(BlogsEntry entry, ServiceContext serviceContext)
1065 throws PortalException, SystemException {
1066
1067 if (!PropsValues.BLOGS_PING_GOOGLE_ENABLED || !entry.isApproved()) {
1068 return;
1069 }
1070
1071 String layoutFullURL = PortalUtil.getLayoutFullURL(
1072 serviceContext.getScopeGroupId(), PortletKeys.BLOGS);
1073
1074 if (Validator.isNull(layoutFullURL)) {
1075 return;
1076 }
1077
1078 if (layoutFullURL.contains(":
1079 if (_log.isDebugEnabled()) {
1080 _log.debug(
1081 "Not pinging Google because of localhost URL " +
1082 layoutFullURL);
1083 }
1084
1085 return;
1086 }
1087
1088 Group group = groupPersistence.findByPrimaryKey(entry.getGroupId());
1089
1090 StringBundler sb = new StringBundler(6);
1091
1092 String name = group.getDescriptiveName();
1093 String url = layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs";
1094 String changesURL =
1095 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs/rss";
1096
1097 sb.append("http:
1098 sb.append(HttpUtil.encodeURL(name));
1099 sb.append("&url=");
1100 sb.append(HttpUtil.encodeURL(url));
1101 sb.append("&changesURL=");
1102 sb.append(HttpUtil.encodeURL(changesURL));
1103
1104 String location = sb.toString();
1105
1106 if (_log.isInfoEnabled()) {
1107 _log.info("Pinging Google at " + location);
1108 }
1109
1110 try {
1111 String response = HttpUtil.URLtoString(sb.toString());
1112
1113 if (_log.isInfoEnabled()) {
1114 _log.info("Google ping response: " + response);
1115 }
1116 }
1117 catch (IOException ioe) {
1118 _log.error("Unable to ping Google at " + location, ioe);
1119 }
1120 }
1121
1122 protected void pingPingback(BlogsEntry entry, ServiceContext serviceContext)
1123 throws PortalException, SystemException {
1124
1125 if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
1126 !entry.isAllowPingbacks() || !entry.isApproved()) {
1127
1128 return;
1129 }
1130
1131 HttpServletRequest request = serviceContext.getRequest();
1132
1133 if (request == null) {
1134 return;
1135 }
1136
1137 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
1138 WebKeys.THEME_DISPLAY);
1139
1140 String layoutFullURL = PortalUtil.getLayoutFullURL(themeDisplay);
1141
1142 if (Validator.isNull(layoutFullURL)) {
1143 return;
1144 }
1145
1146 String sourceUri =
1147 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs/" +
1148 entry.getUrlTitle();
1149
1150 Source source = new Source(entry.getContent());
1151
1152 List<StartTag> tags = source.getAllStartTags("a");
1153
1154 for (StartTag tag : tags) {
1155 String targetUri = tag.getAttributeValue("href");
1156
1157 if (Validator.isNotNull(targetUri)) {
1158 try {
1159 LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
1160 }
1161 catch (Exception e) {
1162 _log.error("Error while sending pingback " + targetUri, e);
1163 }
1164 }
1165 }
1166 }
1167
1168 protected void pingTrackbacks(
1169 BlogsEntry entry, String[] trackbacks, boolean pingOldTrackbacks,
1170 ServiceContext serviceContext)
1171 throws PortalException, SystemException {
1172
1173 if (!PropsValues.BLOGS_TRACKBACK_ENABLED ||
1174 !entry.isAllowTrackbacks() || !entry.isApproved()) {
1175
1176 return;
1177 }
1178
1179 HttpServletRequest request = serviceContext.getRequest();
1180
1181 if (request == null) {
1182 return;
1183 }
1184
1185 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
1186 WebKeys.THEME_DISPLAY);
1187
1188 String layoutFullURL = PortalUtil.getLayoutFullURL(themeDisplay);
1189
1190 if (Validator.isNull(layoutFullURL)) {
1191 return;
1192 }
1193
1194 Map<String, String> parts = new HashMap<String, String>();
1195
1196 String excerpt = StringUtil.shorten(
1197 HtmlUtil.extractText(entry.getContent()),
1198 PropsValues.BLOGS_LINKBACK_EXCERPT_LENGTH);
1199 String url =
1200 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs/" +
1201 entry.getUrlTitle();
1202
1203 parts.put("title", entry.getTitle());
1204 parts.put("excerpt", excerpt);
1205 parts.put("url", url);
1206 parts.put("blog_name", entry.getUserName());
1207
1208 Set<String> trackbacksSet = null;
1209
1210 if (Validator.isNotNull(trackbacks)) {
1211 trackbacksSet = SetUtil.fromArray(trackbacks);
1212 }
1213 else {
1214 trackbacksSet = new HashSet<String>();
1215 }
1216
1217 if (pingOldTrackbacks) {
1218 trackbacksSet.addAll(
1219 SetUtil.fromArray(StringUtil.split(entry.getTrackbacks())));
1220
1221 entry.setTrackbacks(StringPool.BLANK);
1222
1223 blogsEntryPersistence.update(entry, false);
1224 }
1225
1226 Set<String> oldTrackbacks = SetUtil.fromArray(
1227 StringUtil.split(entry.getTrackbacks()));
1228
1229 Set<String> validTrackbacks = new HashSet<String>();
1230
1231 for (String trackback : trackbacksSet) {
1232 if (oldTrackbacks.contains(trackback)) {
1233 continue;
1234 }
1235
1236 try {
1237 if (LinkbackProducerUtil.sendTrackback(trackback, parts)) {
1238 validTrackbacks.add(trackback);
1239 }
1240 }
1241 catch (Exception e) {
1242 _log.error("Error while sending trackback at " + trackback, e);
1243 }
1244 }
1245
1246 if (!validTrackbacks.isEmpty()) {
1247 String newTrackbacks = StringUtil.merge(validTrackbacks);
1248
1249 if (Validator.isNotNull(entry.getTrackbacks())) {
1250 newTrackbacks += StringPool.COMMA + entry.getTrackbacks();
1251 }
1252
1253 entry.setTrackbacks(newTrackbacks);
1254
1255 blogsEntryPersistence.update(entry, false);
1256 }
1257 }
1258
1259 protected void saveImages(
1260 boolean smallImage, long smallImageId, byte[] smallImageBytes)
1261 throws PortalException, SystemException {
1262
1263 if (smallImage) {
1264 if (smallImageBytes != null) {
1265 imageLocalService.updateImage(smallImageId, smallImageBytes);
1266 }
1267 }
1268 else {
1269 imageLocalService.deleteImage(smallImageId);
1270 }
1271 }
1272
1273 protected void validate(
1274 String title, String content, boolean smallImage,
1275 String smallImageURL, String smallImageFileName,
1276 byte[] smallImageBytes)
1277 throws PortalException, SystemException {
1278
1279 if (Validator.isNull(title)) {
1280 throw new EntryTitleException();
1281 }
1282 else if (Validator.isNull(content)) {
1283 throw new EntryContentException();
1284 }
1285
1286 String[] imageExtensions = PrefsPropsUtil.getStringArray(
1287 PropsKeys.BLOGS_IMAGE_EXTENSIONS, StringPool.COMMA);
1288
1289 if (smallImage && Validator.isNull(smallImageURL) &&
1290 (smallImageBytes != null)) {
1291
1292 if (smallImageFileName != null) {
1293 boolean validSmallImageExtension = false;
1294
1295 for (String _imageExtension : imageExtensions) {
1296 if (StringPool.STAR.equals(_imageExtension) ||
1297 StringUtil.endsWith(
1298 smallImageFileName, _imageExtension)) {
1299
1300 validSmallImageExtension = true;
1301
1302 break;
1303 }
1304 }
1305
1306 if (!validSmallImageExtension) {
1307 throw new EntrySmallImageNameException(smallImageFileName);
1308 }
1309 }
1310
1311 long smallImageMaxSize = PrefsPropsUtil.getLong(
1312 PropsKeys.BLOGS_IMAGE_SMALL_MAX_SIZE);
1313
1314 if ((smallImageMaxSize > 0) &&
1315 ((smallImageBytes == null) ||
1316 (smallImageBytes.length > smallImageMaxSize))) {
1317
1318 throw new EntrySmallImageSizeException();
1319 }
1320 }
1321 }
1322
1323 private static Log _log = LogFactoryUtil.getLog(
1324 BlogsEntryLocalServiceImpl.class);
1325
1326 }