Frage

I'm trying to create a rule that does the following.

  • Event: After saving new content type Forum Topic

  • Conditions:

    • User has role 'authenticated', and
    • Content body contains link (this is the part I can't figure out)
  • Actions:

    • Unpublish Content

    • Show a message on the site:

      "Your user permissions currently do not allow for you to post a forum topic that contains a link. Please remove all links from your post and re-submit by clicking the following edit link: [node:edit-url]

      This precaution helps us keep our forum and comments spam free. If you would like the ability to post links, please e-mail the site admin: [site:mail]"

The general idea is that I want users to register to the forum and be able to create new forum topics but not be allowed to post links since this is the whole purpose behind spam. Once they make a few quality posts, I'll move them to a trusted user group that this rule doesn't apply to, allowing them to post links.

The reason why I don't want to use Text Formats to strip out tags is because the spam post will still be published, minus the links. This will lead to offensive, spammy posts still showing up in the forum index.

War es hilfreich?

Lösung

Enable the module PHP Filter that comes in core. This adds a new condition named Execute custom PHP code, which must return TRUE or FALSE.

Then write a PHP snippet in that condition that uses PHP's preg_match on the $node->body field. You can find regex patterns to check for valid URLs in many places, for example here.

Andere Tipps

Look at honeypot and hidden capchta before getting too many rules involved.

I trust the solution in argiepiano's answer works, but for all sorts of reasons mentioned in the answer to "What are the downsides of using PHP Filter code in blocks, nodes, views-args, etc?" you should try to avoid using the PHP filter whenever possible.

Here is a prototype of a rule, in Rules export format, that should also answer your question:

{ "rules_find_links_in_body" : {
    "LABEL" : "Find links in body",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_insert--article" : { "bundle" : "article" } },
    "IF" : [
      { "user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "2" : "2" } }
        }
      },
      { "OR" : [
          { "text_matches" : {
              "text" : [ "node:body:value" ],
              "match" : "http(|s):\/\/+",
              "operation" : "regex"
            }
          },
          { "text_matches" : {
              "text" : [ "node:body:value" ],
              "match" : "ANotAllowedTextStringInBody",
              "operation" : "regex"
            }
          }
        ]
      }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "Node body contains an URL ..." } }
    ]
  }
}

Some more details about the above prototype rule:

  • Rules Event = After saving new content of type "Article" (adapt the type to fit your needs).
  • Rules Conditions:
    • Check if the current user is an authenticated user.
    • Perform a text comparison, using a Regular Expression as the Comparison operation (which you can perfectly do in Rules, without using the PHP filter for it. For the actual regular expression, this rule uses http(|s)://+, which will discover strings that start with either http:// or https://, and which should be pretty close to the "contains a link" as in your question. Should you have additional / similar requirements to discover variations of this (say some other string like ANotAllowedTextStringInBody), another Rules Condition (with an OR) will take care of that also.
  • Rules Action = Show a message on the site (adapt the message to fit your needs), and add other relevant Rules Actions.

Voilà, no PHP filter needed.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit drupal.stackexchange
scroll top