mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-25 19:17:13 +08:00
Refactoring spam filter customization
--HG-- branch : 1.x
This commit is contained in:
@@ -1,28 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using Orchard.AntiSpam.Models;
|
|
||||||
using Orchard.AntiSpam.Services;
|
|
||||||
using Orchard.AntiSpam.Settings;
|
|
||||||
|
|
||||||
namespace Orchard.AntiSpam.EventHandlers {
|
|
||||||
public class DefaultCheckSpamEventHandler : ICheckSpamEventHandler {
|
|
||||||
private readonly ISpamService _spamService;
|
|
||||||
|
|
||||||
public DefaultCheckSpamEventHandler(ISpamService spamService) {
|
|
||||||
_spamService = spamService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckSpam(dynamic context) {
|
|
||||||
if(!_spamService.GetSpamFilters().Any()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Checked = true;
|
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(context.Text)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.IsSpam = _spamService.CheckForSpam(context.Text, SpamFilterAction.One, context.Content) == SpamStatus.Spam;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using Orchard.Events;
|
|
||||||
|
|
||||||
namespace Orchard.AntiSpam.EventHandlers {
|
|
||||||
public interface ICheckSpamEventHandler : IEventHandler {
|
|
||||||
/// <param name="context">
|
|
||||||
/// Dynamic object representing the parameters for the call
|
|
||||||
/// - Content (in IContent): the IContent that should trigger events when checked
|
|
||||||
/// - Text (in string): the text which is submitted for spam analysis
|
|
||||||
/// - Checked (out bool): will be assigned to true if the spam could be checked
|
|
||||||
/// - IsPam (out bool): True if the text has been reported as spam
|
|
||||||
/// </param>
|
|
||||||
void CheckSpam(dynamic context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
namespace Orchard.AntiSpam.Models {
|
||||||
|
public class CommentCheckContext {
|
||||||
|
/// <summary>
|
||||||
|
/// The front page or home URL of the instance making the request. For a blog
|
||||||
|
/// or wiki this would be the front page. Note: Must be a full URI, including http://.
|
||||||
|
/// </summary>
|
||||||
|
public string Url { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IP address of the comment submitter.
|
||||||
|
/// </summary>
|
||||||
|
public string UserIp { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User agent string of the web browser submitting the comment - typically
|
||||||
|
/// the HTTP_USER_AGENT cgi variable. Not to be confused with the user agent
|
||||||
|
/// of your Akismet library.
|
||||||
|
/// </summary>
|
||||||
|
public string UserAgent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The content of the HTTP_REFERER header should be sent here.
|
||||||
|
/// </summary>
|
||||||
|
public string Referrer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The permanent location of the entry the comment was submitted to.
|
||||||
|
/// </summary>
|
||||||
|
public string Permalink { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// May be blank, comment, trackback, pingback, or a made up value like "registration".
|
||||||
|
/// </summary>
|
||||||
|
public string CommentType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name submitted with the comment
|
||||||
|
/// </summary>
|
||||||
|
public string CommentAuthor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Email address submitted with the comment
|
||||||
|
/// </summary>
|
||||||
|
public string CommentAuthorEmail { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// URL submitted with comment
|
||||||
|
/// </summary>
|
||||||
|
public string CommentAuthorUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The content that was submitted.
|
||||||
|
/// </summary>
|
||||||
|
public string CommentContent { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -93,8 +93,6 @@
|
|||||||
<Compile Include="Drivers\SpamFilterPartDriver.cs" />
|
<Compile Include="Drivers\SpamFilterPartDriver.cs" />
|
||||||
<Compile Include="Drivers\ReCaptchaPartDriver.cs" />
|
<Compile Include="Drivers\ReCaptchaPartDriver.cs" />
|
||||||
<Compile Include="Drivers\SubmissionLimitPartDriver.cs" />
|
<Compile Include="Drivers\SubmissionLimitPartDriver.cs" />
|
||||||
<Compile Include="EventHandlers\DefaultCheckSpamEventHandler.cs" />
|
|
||||||
<Compile Include="EventHandlers\ICheckSpamEventHandler.cs" />
|
|
||||||
<Compile Include="Handlers\AkismetSettingsPartHandler.cs" />
|
<Compile Include="Handlers\AkismetSettingsPartHandler.cs" />
|
||||||
<Compile Include="Handlers\ReCaptchaSettingsPartHandler.cs" />
|
<Compile Include="Handlers\ReCaptchaSettingsPartHandler.cs" />
|
||||||
<Compile Include="Handlers\TypePadSettingsPartHandler.cs" />
|
<Compile Include="Handlers\TypePadSettingsPartHandler.cs" />
|
||||||
@@ -102,6 +100,7 @@
|
|||||||
<Compile Include="Migrations.cs" />
|
<Compile Include="Migrations.cs" />
|
||||||
<Compile Include="Models\AkismetSettingsPartRecord.cs" />
|
<Compile Include="Models\AkismetSettingsPartRecord.cs" />
|
||||||
<Compile Include="Models\AkismetSettingsPart.cs" />
|
<Compile Include="Models\AkismetSettingsPart.cs" />
|
||||||
|
<Compile Include="Models\CommentCheckContext.cs" />
|
||||||
<Compile Include="Models\ReCaptchaSettingsPart.cs" />
|
<Compile Include="Models\ReCaptchaSettingsPart.cs" />
|
||||||
<Compile Include="Models\ReCaptchaSettingsPartRecord.cs" />
|
<Compile Include="Models\ReCaptchaSettingsPartRecord.cs" />
|
||||||
<Compile Include="Models\TypePadSettingsPart.cs" />
|
<Compile Include="Models\TypePadSettingsPart.cs" />
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Text;
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using Orchard.AntiSpam.Models;
|
using Orchard.AntiSpam.Models;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
using Orchard.Utility.Extensions;
|
|
||||||
|
|
||||||
namespace Orchard.AntiSpam.Services {
|
namespace Orchard.AntiSpam.Services {
|
||||||
public class AkismetApiSpamFilter : ISpamFilter {
|
public class AkismetApiSpamFilter : ISpamFilter {
|
||||||
@@ -26,9 +25,9 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
|
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public SpamStatus CheckForSpam(string text) {
|
public SpamStatus CheckForSpam(CommentCheckContext context) {
|
||||||
try {
|
try {
|
||||||
var result = ExecuteValidateRequest(text, "comment-check");
|
var result = ExecuteValidateRequest(context, "comment-check");
|
||||||
|
|
||||||
if (HandleValidateResponse(_context, result)) {
|
if (HandleValidateResponse(_context, result)) {
|
||||||
return SpamStatus.Spam;
|
return SpamStatus.Spam;
|
||||||
@@ -42,25 +41,25 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportSpam(string text) {
|
public void ReportSpam(CommentCheckContext context) {
|
||||||
try {
|
try {
|
||||||
var result = ExecuteValidateRequest(text, "submit-spam");
|
var result = ExecuteValidateRequest(context, "submit-spam");
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Logger.Error(e, "An error occured while reporting spam");
|
Logger.Error(e, "An error occured while reporting spam");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportHam(string text) {
|
public void ReportHam(CommentCheckContext context) {
|
||||||
try {
|
try {
|
||||||
var result = ExecuteValidateRequest(text, "submit-ham");
|
var result = ExecuteValidateRequest(context, "submit-ham");
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Logger.Error(e, "An error occured while reporting ham");
|
Logger.Error(e, "An error occured while reporting ham");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ExecuteValidateRequest(string text, string action) {
|
private string ExecuteValidateRequest(CommentCheckContext context, string action) {
|
||||||
var uri = String.Format(AkismetApiPattern, _apiKey, _endpoint, action);
|
var uri = String.Format(AkismetApiPattern, _apiKey, _endpoint, action);
|
||||||
|
|
||||||
WebRequest request = WebRequest.Create(uri);
|
WebRequest request = WebRequest.Create(uri);
|
||||||
@@ -68,13 +67,16 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
request.Timeout = 5000; //milliseconds
|
request.Timeout = 5000; //milliseconds
|
||||||
request.ContentType = "application/x-www-form-urlencoded";
|
request.ContentType = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
var postData = String.Format(CultureInfo.InvariantCulture, "blog={0}&user_ip={1}&user_agent={2}&referrer={3}&comment_content={4}",
|
var postData = "blog=" + HttpUtility.UrlEncode(context.Url)
|
||||||
HttpUtility.UrlEncode(_context.Request.ToApplicationRootUrlString()),
|
+ "&user_ip=" + HttpUtility.UrlEncode(context.UserIp)
|
||||||
HttpUtility.UrlEncode(_context.Request.ServerVariables["REMOTE_ADDR"]),
|
+ "&user_agent=" + HttpUtility.UrlEncode(context.UserAgent)
|
||||||
HttpUtility.UrlEncode(_context.Request.UserAgent),
|
+ "&referrer=" + HttpUtility.UrlEncode(context.Referrer)
|
||||||
HttpUtility.UrlEncode(Convert.ToString(_context.Request.UrlReferrer)),
|
+ "&permalink=" + HttpUtility.UrlEncode(context.Permalink)
|
||||||
HttpUtility.UrlEncode(text)
|
+ "&comment_type=" + HttpUtility.UrlEncode(context.CommentType)
|
||||||
);
|
+ "&comment_author=" + HttpUtility.UrlEncode(context.CommentAuthor)
|
||||||
|
+ "&comment_author_email=" + HttpUtility.UrlEncode(context.CommentAuthorEmail)
|
||||||
|
+ "&comment_author_url=" + HttpUtility.UrlEncode(context.CommentAuthorUrl)
|
||||||
|
+ "&comment_content=" + HttpUtility.UrlEncode(context.CommentContent);
|
||||||
|
|
||||||
byte[] content = Encoding.UTF8.GetBytes(postData);
|
byte[] content = Encoding.UTF8.GetBytes(postData);
|
||||||
using (Stream stream = request.GetRequestStream()) {
|
using (Stream stream = request.GetRequestStream()) {
|
||||||
|
|||||||
@@ -13,22 +13,25 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
private readonly IEnumerable<ISpamFilterProvider> _providers;
|
private readonly IEnumerable<ISpamFilterProvider> _providers;
|
||||||
private readonly ISpamEventHandler _spamEventHandler;
|
private readonly ISpamEventHandler _spamEventHandler;
|
||||||
private readonly IRulesManager _rulesManager;
|
private readonly IRulesManager _rulesManager;
|
||||||
|
private readonly IWorkContextAccessor _workContextAccessor;
|
||||||
|
|
||||||
public DefaultSpamService(
|
public DefaultSpamService(
|
||||||
ITokenizer tokenizer,
|
ITokenizer tokenizer,
|
||||||
IEnumerable<ISpamFilterProvider> providers,
|
IEnumerable<ISpamFilterProvider> providers,
|
||||||
ISpamEventHandler spamEventHandler,
|
ISpamEventHandler spamEventHandler,
|
||||||
IRulesManager rulesManager
|
IRulesManager rulesManager,
|
||||||
|
IWorkContextAccessor workContextAccessor
|
||||||
) {
|
) {
|
||||||
_tokenizer = tokenizer;
|
_tokenizer = tokenizer;
|
||||||
_providers = providers;
|
_providers = providers;
|
||||||
_spamEventHandler = spamEventHandler;
|
_spamEventHandler = spamEventHandler;
|
||||||
_rulesManager = rulesManager;
|
_rulesManager = rulesManager;
|
||||||
|
_workContextAccessor = workContextAccessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpamStatus CheckForSpam(string text, SpamFilterAction action, IContent content) {
|
public SpamStatus CheckForSpam(CommentCheckContext context, SpamFilterAction action, IContent content) {
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(text)) {
|
if (string.IsNullOrWhiteSpace(context.CommentContent)) {
|
||||||
return SpamStatus.Ham;
|
return SpamStatus.Ham;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,13 +41,13 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case SpamFilterAction.AllOrNothing:
|
case SpamFilterAction.AllOrNothing:
|
||||||
if (spamFilters.All(x => x.CheckForSpam(text) == SpamStatus.Spam)) {
|
if (spamFilters.All(x => x.CheckForSpam(context) == SpamStatus.Spam)) {
|
||||||
result = SpamStatus.Spam;
|
result = SpamStatus.Spam;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SpamFilterAction.One:
|
case SpamFilterAction.One:
|
||||||
if (spamFilters.Any(x => x.CheckForSpam(text) == SpamStatus.Spam)) {
|
if (spamFilters.Any(x => x.CheckForSpam(context) == SpamStatus.Spam)) {
|
||||||
result = SpamStatus.Spam;
|
result = SpamStatus.Spam;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,57 +74,67 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SpamStatus CheckForSpam(SpamFilterPart part) {
|
public SpamStatus CheckForSpam(SpamFilterPart part) {
|
||||||
|
|
||||||
var settings = part.TypePartDefinition.Settings.GetModel<SpamFilterPartSettings>();
|
var settings = part.TypePartDefinition.Settings.GetModel<SpamFilterPartSettings>();
|
||||||
|
var context = CreateCommentCheckContext(part, _workContextAccessor.GetContext());
|
||||||
|
|
||||||
// evaluate the text to submit to the spam filters
|
if (string.IsNullOrWhiteSpace(context.CommentContent)) {
|
||||||
var text = _tokenizer.Replace(settings.Pattern, new Dictionary<string, object> { { "Content", part.ContentItem } });
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(text)) {
|
|
||||||
return SpamStatus.Ham;
|
return SpamStatus.Ham;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = CheckForSpam(text, settings.Action, part);
|
var result = CheckForSpam(context, settings.Action, part);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportSpam(string text) {
|
public void ReportSpam(CommentCheckContext context) {
|
||||||
var spamFilters = GetSpamFilters().ToList();
|
var spamFilters = GetSpamFilters().ToList();
|
||||||
|
|
||||||
foreach(var filter in spamFilters) {
|
foreach(var filter in spamFilters) {
|
||||||
filter.ReportSpam(text);
|
filter.ReportSpam(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportSpam(SpamFilterPart part) {
|
public void ReportSpam(SpamFilterPart part) {
|
||||||
var settings = part.TypePartDefinition.Settings.GetModel<SpamFilterPartSettings>();
|
ReportSpam(CreateCommentCheckContext(part, _workContextAccessor.GetContext()));
|
||||||
|
|
||||||
// evaluate the text to submit to the spam filters
|
|
||||||
var text = _tokenizer.Replace(settings.Pattern, new Dictionary<string, object> { { "Content", part.ContentItem } });
|
|
||||||
|
|
||||||
ReportSpam(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportHam(string text) {
|
public void ReportHam(CommentCheckContext context) {
|
||||||
var spamFilters = GetSpamFilters().ToList();
|
var spamFilters = GetSpamFilters().ToList();
|
||||||
|
|
||||||
foreach (var filter in spamFilters) {
|
foreach (var filter in spamFilters) {
|
||||||
filter.ReportHam(text);
|
filter.ReportHam(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportHam(SpamFilterPart part) {
|
public void ReportHam(SpamFilterPart part) {
|
||||||
var settings = part.TypePartDefinition.Settings.GetModel<SpamFilterPartSettings>();
|
ReportHam(CreateCommentCheckContext(part, _workContextAccessor.GetContext()));
|
||||||
|
|
||||||
// evaluate the text to submit to the spam filters
|
|
||||||
var text = _tokenizer.Replace(settings.Pattern, new Dictionary<string, object> { { "Content", part.ContentItem } });
|
|
||||||
|
|
||||||
ReportHam(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ISpamFilter> GetSpamFilters() {
|
public IEnumerable<ISpamFilter> GetSpamFilters() {
|
||||||
return _providers.SelectMany(x => x.GetSpamFilters()).Where(x => x != null);
|
return _providers.SelectMany(x => x.GetSpamFilters()).Where(x => x != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CommentCheckContext CreateCommentCheckContext(SpamFilterPart part, WorkContext workContext) {
|
||||||
|
var settings = part.TypePartDefinition.Settings.GetModel<SpamFilterPartSettings>();
|
||||||
|
|
||||||
|
var data = new Dictionary<string, object> {{"Content", part.ContentItem}};
|
||||||
|
|
||||||
|
var context = new CommentCheckContext {
|
||||||
|
Url = _tokenizer.Replace(settings.UrlPattern, data),
|
||||||
|
Permalink = _tokenizer.Replace(settings.PermalinkPattern, data),
|
||||||
|
CommentAuthor = _tokenizer.Replace(settings.CommentAuthorPattern, data),
|
||||||
|
CommentAuthorEmail = _tokenizer.Replace(settings.CommentAuthorEmailPattern, data),
|
||||||
|
CommentAuthorUrl = _tokenizer.Replace(settings.CommentAuthorUrlPattern, data),
|
||||||
|
CommentContent = _tokenizer.Replace(settings.CommentContentPattern, data),
|
||||||
|
};
|
||||||
|
|
||||||
|
if(workContext.HttpContext != null) {
|
||||||
|
context.UserIp = workContext.HttpContext.Request.ServerVariables["REMOTE_ADDR"];
|
||||||
|
context.UserAgent = workContext.HttpContext.Request.UserAgent;
|
||||||
|
context.Referrer = Convert.ToString(workContext.HttpContext.Request.UrlReferrer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,20 +9,20 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if some content is spam.
|
/// Checks if some content is spam.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to check.</param>
|
/// <param name="context">The comment to check.</param>
|
||||||
/// <returns><value>SpamStatus.Spam</value> if the text has been categorized as spam, <value>SpamStatus.Ham</value> otherwise.</returns>
|
/// <returns><value>SpamStatus.Spam</value> if the comment has been categorized as spam, <value>SpamStatus.Ham</value> otherwise.</returns>
|
||||||
SpamStatus CheckForSpam(string text);
|
SpamStatus CheckForSpam(CommentCheckContext context);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitely report some content as spam in order to improve the service.
|
/// Explicitely report some content as spam in order to improve the service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to report as spam.</param>
|
/// <param name="context">The comment to report as spam.</param>
|
||||||
void ReportSpam(string text);
|
void ReportSpam(CommentCheckContext context);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitely report some content as ham in order to improve the service.
|
/// Explicitely report some content as ham in order to improve the service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to report as ham (false positive).</param>
|
/// <param name="context">The comment to report as ham (false positive).</param>
|
||||||
void ReportHam(string text);
|
void ReportHam(CommentCheckContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ using Orchard.ContentManagement;
|
|||||||
|
|
||||||
namespace Orchard.AntiSpam.Services {
|
namespace Orchard.AntiSpam.Services {
|
||||||
public interface ISpamService : IDependency {
|
public interface ISpamService : IDependency {
|
||||||
SpamStatus CheckForSpam(string text, SpamFilterAction action, IContent content);
|
SpamStatus CheckForSpam(CommentCheckContext text, SpamFilterAction action, IContent content);
|
||||||
SpamStatus CheckForSpam(SpamFilterPart part);
|
SpamStatus CheckForSpam(SpamFilterPart part);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitely report some content as spam in order to improve the service.
|
/// Explicitely report some content as spam in order to improve the service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to report as spam.</param>
|
/// <param name="context">The comment context to report as spam.</param>
|
||||||
void ReportSpam(string text);
|
void ReportSpam(CommentCheckContext context);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitely report some content as ham in order to improve the service.
|
/// Explicitely report some content as ham in order to improve the service.
|
||||||
@@ -23,8 +23,8 @@ namespace Orchard.AntiSpam.Services {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitely report some content as ham in order to improve the service.
|
/// Explicitely report some content as ham in order to improve the service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to report as ham (false positive).</param>
|
/// <param name="context">The comment context to report as ham (false positive).</param>
|
||||||
void ReportHam(string text);
|
void ReportHam(CommentCheckContext context);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitely report some content as ham in order to improve the service.
|
/// Explicitely report some content as ham in order to improve the service.
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
namespace Orchard.AntiSpam.Settings {
|
namespace Orchard.AntiSpam.Settings {
|
||||||
public class SpamFilterPartSettings {
|
public class SpamFilterPartSettings {
|
||||||
public SpamFilterAction Action { get; set; }
|
public SpamFilterAction Action { get; set; }
|
||||||
public string Pattern { get; set; }
|
|
||||||
public bool DeleteSpam { get; set; }
|
public bool DeleteSpam { get; set; }
|
||||||
|
|
||||||
|
public string UrlPattern { get; set; }
|
||||||
|
public string PermalinkPattern { get; set; }
|
||||||
|
public string CommentAuthorPattern { get; set; }
|
||||||
|
public string CommentAuthorEmailPattern { get; set; }
|
||||||
|
public string CommentAuthorUrlPattern { get; set; }
|
||||||
|
public string CommentContentPattern { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -30,8 +30,13 @@ namespace Orchard.AntiSpam.Settings {
|
|||||||
|
|
||||||
if (updateModel.TryUpdateModel(settings, "SpamFilterPartSettings", null, null)) {
|
if (updateModel.TryUpdateModel(settings, "SpamFilterPartSettings", null, null)) {
|
||||||
builder.WithSetting("SpamFilterPartSettings.Action", settings.Action.ToString());
|
builder.WithSetting("SpamFilterPartSettings.Action", settings.Action.ToString());
|
||||||
builder.WithSetting("SpamFilterPartSettings.Pattern", settings.Pattern);
|
|
||||||
builder.WithSetting("SpamFilterPartSettings.DeleteSpam", settings.DeleteSpam.ToString(CultureInfo.InvariantCulture));
|
builder.WithSetting("SpamFilterPartSettings.DeleteSpam", settings.DeleteSpam.ToString(CultureInfo.InvariantCulture));
|
||||||
|
builder.WithSetting("SpamFilterPartSettings.UrlPattern", settings.UrlPattern);
|
||||||
|
builder.WithSetting("SpamFilterPartSettings.PermalinkPattern", settings.PermalinkPattern);
|
||||||
|
builder.WithSetting("SpamFilterPartSettings.CommentAuthorPattern", settings.CommentAuthorPattern);
|
||||||
|
builder.WithSetting("SpamFilterPartSettings.CommentAuthorUrlPattern", settings.CommentAuthorUrlPattern);
|
||||||
|
builder.WithSetting("SpamFilterPartSettings.CommentAuthorEmailPattern", settings.CommentAuthorEmailPattern);
|
||||||
|
builder.WithSetting("SpamFilterPartSettings.CommentContentPattern", settings.CommentContentPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return DefinitionTemplate(settings);
|
yield return DefinitionTemplate(settings);
|
||||||
|
|||||||
@@ -15,14 +15,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<label for="@Html.FieldIdFor(m => m.Pattern)">@T("Analyzed text")</label>
|
|
||||||
<div>
|
|
||||||
@Html.TextBoxFor(m => m.Pattern, new { @class = "text large tokenized" })
|
|
||||||
<span class="hint">@T("The tokenized pattern generating the text to submit to spam filters.")</span>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div>
|
<div>
|
||||||
@Html.EditorFor(m => m.DeleteSpam)
|
@Html.EditorFor(m => m.DeleteSpam)
|
||||||
@@ -30,3 +22,52 @@
|
|||||||
<span class="hint">@T("Enable to have spam automatically deleted when found. You won't be able to find false positive.")</span>
|
<span class="hint">@T("Enable to have spam automatically deleted when found. You won't be able to find false positive.")</span>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.UrlPattern)">@T("Url")</label>
|
||||||
|
<div>
|
||||||
|
@Html.TextBoxFor(m => m.UrlPattern, new { @class = "text large tokenized" })
|
||||||
|
<span class="hint">@T("The front page or home URL of the instance making the request. For a blog or wiki this would be the front page. Note: Must be a full URI, including http://.")</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.PermalinkPattern)">@T("Permalink")</label>
|
||||||
|
<div>
|
||||||
|
@Html.TextBoxFor(m => m.PermalinkPattern, new { @class = "text large tokenized" })
|
||||||
|
<span class="hint">@T("The permanent location of the entry the content item was submitted to.")</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.CommentAuthorPattern)">@T("Author")</label>
|
||||||
|
<div>
|
||||||
|
@Html.TextBoxFor(m => m.CommentAuthorPattern, new { @class = "text large tokenized" })
|
||||||
|
<span class="hint">@T("Name submitted with the content item.")</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.CommentAuthorEmailPattern)">@T("Author's email")</label>
|
||||||
|
<div>
|
||||||
|
@Html.TextBoxFor(m => m.CommentAuthorEmailPattern, new { @class = "text large tokenized" })
|
||||||
|
<span class="hint">@T("Email address submitted with the content item.")</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.CommentAuthorUrlPattern)">@T("Author's url")</label>
|
||||||
|
<div>
|
||||||
|
@Html.TextBoxFor(m => m.CommentAuthorUrlPattern, new { @class = "text large tokenized" })
|
||||||
|
<span class="hint">@T("URL submitted with the content item.")</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.CommentContentPattern)">@T("Comment content")</label>
|
||||||
|
<div>
|
||||||
|
@Html.TextBoxFor(m => m.CommentContentPattern, new { @class = "text large tokenized" })
|
||||||
|
<span class="hint">@T("The content that was submitted.")</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|||||||
@@ -21,10 +21,12 @@ namespace Orchard.Comments.Tokens {
|
|||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
public void Describe(dynamic context) {
|
public void Describe(dynamic context) {
|
||||||
context.For("Content", T("Content Items"), T("Content Items"))
|
context.For("Content", T("Comments"), T("Comments"))
|
||||||
.Token("CommentedOn", T("Commented On"), T("The content item this comment was created on."))
|
.Token("CommentedOn", T("Commented On"), T("The content item this comment was created on."))
|
||||||
.Token("CommentMessage", T("Comment Message"), T("The text of the comment itself"))
|
.Token("CommentMessage", T("Comment Message"), T("The text of the comment itself"))
|
||||||
.Token("CommentAuthor", T("Comment Author"), T("The author of the comment."))
|
.Token("CommentAuthor", T("Comment Author"), T("The author of the comment."))
|
||||||
|
.Token("CommentAuthorUrl", T("Comment Author Url"), T("The url provided by the author of the comment."))
|
||||||
|
.Token("CommentAuthorEmail", T("Comment Author Email"), T("The email provided by the author of the comment."))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +36,8 @@ namespace Orchard.Comments.Tokens {
|
|||||||
.Chain("CommentedOn", "Content", (Func<IContent, object>)(content => _contentManager.Get(content.As<CommentPart>().CommentedOn)))
|
.Chain("CommentedOn", "Content", (Func<IContent, object>)(content => _contentManager.Get(content.As<CommentPart>().CommentedOn)))
|
||||||
.Token("CommentMessage", (Func<IContent, object>)(content => content.As<CommentPart>().CommentText))
|
.Token("CommentMessage", (Func<IContent, object>)(content => content.As<CommentPart>().CommentText))
|
||||||
.Token("CommentAuthor", (Func<IContent, object>)CommentAuthor)
|
.Token("CommentAuthor", (Func<IContent, object>)CommentAuthor)
|
||||||
|
.Token("CommentAuthorUrl", (Func<IContent, object>)(content => content.As<CommentPart>().SiteName))
|
||||||
|
.Token("CommentAuthorEmail", (Func<IContent, object>)(content => content.As<CommentPart>().Email))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user