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