/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.akismet.hook.service.impl;
import com.liferay.akismet.model.AkismetData;
import com.liferay.akismet.service.AkismetDataLocalServiceUtil;
import com.liferay.akismet.util.AkismetConstants;
import com.liferay.akismet.util.AkismetUtil;
import com.liferay.akismet.util.PortletPropsKeys;
import com.liferay.akismet.util.PrefsPortletPropsUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.servlet.HttpHeaders;
import com.liferay.portal.kernel.util.NotificationThreadLocal;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.wiki.model.WikiPage;
import com.liferay.wiki.service.WikiPageLocalService;
import com.liferay.wiki.service.WikiPageLocalServiceWrapper;
import java.util.Map;
/**
* @author Peter Shin
*/
public class AkismetWikiPageLocalServiceImpl
extends WikiPageLocalServiceWrapper {
public AkismetWikiPageLocalServiceImpl(
WikiPageLocalService wikiPageLocalService) {
super(wikiPageLocalService);
}
@Override
public WikiPage addPage(
long userId, long nodeId, String title, double version,
String content, String summary, boolean minorEdit, String format,
boolean head, String parentTitle, String redirectTitle,
ServiceContext serviceContext)
throws PortalException {
int workflowAction = serviceContext.getWorkflowAction();
if (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT) {
return super.addPage(
userId, nodeId, title, content, summary, minorEdit,
serviceContext);
}
WikiPage page = super.addPage(
userId, nodeId, title, version, content, summary, minorEdit, format,
head, parentTitle, redirectTitle, serviceContext);
AkismetData akismetData = updateAkismetData(page, serviceContext);
if (!isWikiEnabled(userId, nodeId, serviceContext)) {
return page;
}
String akismetContent = page.getTitle() + "\n\n" + page.getContent();
if (!AkismetUtil.isSpam(userId, akismetContent, akismetData)) {
return super.updateStatus(
userId, page.getResourcePrimKey(),
WorkflowConstants.STATUS_APPROVED, serviceContext);
}
boolean notificationEnabled = false;
try {
notificationEnabled = NotificationThreadLocal.isEnabled();
NotificationThreadLocal.setEnabled(false);
page.setSummary(AkismetConstants.WIKI_PAGE_PENDING_APPROVAL);
page.setStatus(WorkflowConstants.STATUS_APPROVED);
return super.updateWikiPage(page);
}
finally {
NotificationThreadLocal.setEnabled(notificationEnabled);
}
}
@Override
public WikiPage updatePage(
long userId, long nodeId, String title, double version,
String content, String summary, boolean minorEdit, String format,
String parentTitle, String redirectTitle,
ServiceContext serviceContext)
throws PortalException {
int workflowAction = serviceContext.getWorkflowAction();
if (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT) {
return super.updatePage(
userId, nodeId, title, version, content, summary, minorEdit,
format, parentTitle, redirectTitle, serviceContext);
}
WikiPage page = super.updatePage(
userId, nodeId, title, version, content, summary, minorEdit, format,
parentTitle, redirectTitle, serviceContext);
AkismetData akismetData = updateAkismetData(page, serviceContext);
if (!isWikiEnabled(userId, nodeId, serviceContext)) {
return page;
}
String akismetContent = page.getTitle() + "\n\n" + page.getContent();
if (!AkismetUtil.isSpam(userId, akismetContent, akismetData)) {
return super.updateStatus(
userId, page.getResourcePrimKey(),
WorkflowConstants.STATUS_APPROVED, serviceContext);
}
boolean notificationEnabled = false;
try {
notificationEnabled = NotificationThreadLocal.isEnabled();
NotificationThreadLocal.setEnabled(false);
page.setSummary(AkismetConstants.WIKI_PAGE_PENDING_APPROVAL);
page.setStatus(WorkflowConstants.STATUS_APPROVED);
page = super.updateWikiPage(page);
WikiPage previousPage = AkismetUtil.getWikiPage(
page.getNodeId(), page.getTitle(), page.getVersion(), true);
if (previousPage == null) {
return page;
}
ServiceContext newServiceContext = new ServiceContext();
newServiceContext.setFormDate(page.getModifiedDate());
return super.revertPage(
userId, nodeId, title, previousPage.getVersion(),
newServiceContext);
}
finally {
NotificationThreadLocal.setEnabled(notificationEnabled);
}
}
protected String getPermalink(
WikiPage page, ServiceContext serviceContext) {
StringBundler sb = new StringBundler(4);
sb.append(serviceContext.getPortalURL());
sb.append(serviceContext.getPathMain());
sb.append("/wiki/find_page?pageResourcePrimKey=");
sb.append(page.getResourcePrimKey());
return sb.toString();
}
protected boolean isWikiEnabled(
long userId, long nodeId, ServiceContext serviceContext)
throws PortalException {
if (!AkismetUtil.hasRequiredInfo(serviceContext)) {
return false;
}
User user = UserLocalServiceUtil.getUser(userId);
if (!AkismetUtil.isWikiEnabled(user.getCompanyId())) {
return false;
}
int checkThreshold = PrefsPortletPropsUtil.getInteger(
user.getCompanyId(), PortletPropsKeys.AKISMET_CHECK_THRESHOLD);
if (checkThreshold > 0) {
int count = super.getPagesCount(
userId, nodeId, WorkflowConstants.STATUS_APPROVED);
if (count > checkThreshold) {
return false;
}
}
return true;
}
protected AkismetData updateAkismetData(
WikiPage page, ServiceContext serviceContext) {
if (!AkismetUtil.hasRequiredInfo(serviceContext)) {
return null;
}
String permalink = getPermalink(page, serviceContext);
Map<String, String> headers = serviceContext.getHeaders();
String referrer = headers.get("referer");
String userAgent = headers.get(
StringUtil.toLowerCase(HttpHeaders.USER_AGENT));
String userIP = serviceContext.getRemoteAddr();
return AkismetDataLocalServiceUtil.updateAkismetData(
WikiPage.class.getName(), page.getPageId(),
AkismetConstants.TYPE_WIKI, permalink, referrer, userAgent, userIP,
StringPool.BLANK);
}
}