2

I need to show an "Add content" link to users but I need to consider user field values to give access to the node form. For example, is the boolean field "Subscription fee paid" is True.

I thought the Rules module could help me. But I can not find any event "Before creating new content", only "Before saving content". Indeed, I do not want users to fill the form before conditions are verified. Because after 5 or 10 minutes of completing a form, it would not be user-friendly to get a warning message like "*you are not allowed to do that!" ...

So I tried Rules link to create a sort of button, with conditions and reactions. For example, in a block, I show the Rules link. When accessed, if conditions are true, I redirect the user to the form. Unfortunately, Drupal uses the Rules link path by default (for example, submit-the-form) and not the redirection page url included in my rule (for example: node/add/article) and finally the page is not found, since nothing is behind the default path.

Well, I guess I am close but still stuck. Any suggestions?

EDIT : I have tried to create a rule, as suggested by @Pierre.Vriens. Here is the short code.

{ "rules_subscription_check" : {
    "LABEL" : "Subscription check",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "path" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "path_has_alias" : { "source" : "[site:url]\/node\/add\/manuscript-submission" } },
      { "data_is" : { "data" : [ "site:current-user:field-subscribed" ], "value" : "0" } }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "Sorry, subscription is needed to add that type of content.",
          "type" : "warning",
          "repeat" : "0"
        }
      },
      { "redirect" : { "url" : "no_access" } }
    ]
  }
}

Unfortunately, an unsubscribed but authentified user can still add content when he clicks on the form link.

  • @Pierre.Vriens I have tried your solution but the regular expression node\/add\/manuscript-submission is rejected by Rules. Since I am not familiar with Regex, I am trying a new option for the moment, using Panels and its visibilty rules, including tests on field values. I'll keep you informed. – Toki Nov 24 '15 at 14:09
  • Warning : preg_match(): Unknown modifier 'a' dans rules_data_text_comparison() – Toki Nov 24 '15 at 14:18
  • { "rules_subscription_check" : { "LABEL" : "Subscription check", "PLUGIN" : "reaction rule", "OWNER" : "rules", "REQUIRES" : [ "rules" ], "ON" : { "init" : [] }, "IF" : [ { "text_matches" : { "text" : [ "site:current-page:url" ], "match" : "node\\\/add\\\/manuscript-submission", "operation" : "regex" } }, ... – Toki Nov 24 '15 at 14:19
  • Surprisingly, in the rules code, the regular expression seems wrong? – Toki Nov 24 '15 at 14:20
  • That "regex" expression with ""node\\\/add\\\/manuscrip" looks really bizarre ... Have a look at my updated answer now. Curioous to hear if that will help ... – Pierre.Vriens Nov 24 '15 at 15:16
1

Try using Rules (System) event "Drupal is initializing" (= init), which is actually BEFORE your form is shown. If you still can't get it to work, you may have to add an extra condition (like the URL of such form?).

You may also want to look at my answer to the question "How to restrict access to a node via node/12 and allow access via a path like content/sometitle?". The sample there also includes such "Drupal is initializing".

However using a condition like path_has_alias will most likely NOT work either. Instead try replacing such condition with something similar to this Rules condition (in export format here):

{ "text_matches" : {
    "text" : [ "site:current-page:url" ],
    "match" : "node\/\\d+$",
    "operation" : "regex"
  }
}

In the above example, adapt the regular expression (= node\/\\d+$) to fit your URL naming for that form. In your case that regular expression should be something similar to node\/add\/manuscript-submission ...

To double check my own answer here (regex-stuff can be complicated ...), I created this prototype rule to get you going:

{ "rules_limit_access_url_node_add_something" : {
    "LABEL" : "Limit access URL node\/add\/*",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "3" : "3" } }
        }
      },
      { "OR" : [
          { "text_matches" : { "text" : [ "site:current-page:url" ], "match" : "node\/add\/book" } },
          { "text_matches" : {
              "text" : [ "site:current-page:url" ],
              "match" : "node\/add\/article",
              "operation" : "regex"
            }
          }
        ]
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "Adding content for selected content types (such as for \u0022\u003Cstrong\u003E[site:current-page:path]\u003C\/strong\u003E\u0022) triggers some extra (Rules) logic, as you can see here.",
          "type" : "warning"
        }
      }
    ]
  }
}

Some more details to understand this proto-type (and make it work for your case also):

  • my 1st condition was just to have "some other condition" (in my case: applies for admins only), that's like the "data_is"-condition in your question (ignore my condition here for the rest).
  • my rules action in my prototype is just for (easy) debugging, and as a proof that my rule works as I expect it to work (use whatever action you see fit in your case).
  • the text_matches Rules condition is the most important part for you to look at. Actually, you'll need 1 such condition for each of your content type you want your rule to apply to. In my prototype I decided to have it apply to these 2 content types (whereas I used 2 different techniques you can pick from):
    • article : just using an exact text match
    • book: using an (extremely basic) regular expression (which you may want to take advantage of if you have multiple content types that you can group together in a single regular expression.
  • in case you didn't notice: be aware of the or part of the Rule condition also ...

I suggest you replace the path_has_alias condition with the applicable parts of my prototype rule above (i.e. the text_matches Rules conditions). Together with the "Drupal is initializing" (as in your edited version already), it should work.

1

Based on previous answer by Pierre.Vriens, using only the Rules module and Drupal core modules.

Here is the final code for an effective rule if you need to check users values before they can add content :

{ "rules_subscription_check" : {
    "LABEL" : "Subscription check",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "node\/add\/manuscript-submission",
          "operation" : "regex"
        }
      },
      { "AND" : [] },
      { "data_is" : { "data" : [ "site:current-user:field-subscribed" ], "value" : "0" } }
    ],
    "DO" : [
      { "redirect" : { "url" : "\u003Cfront\u003E" } },
      { "drupal_message" : {
          "message" : "Sorry, subscription is needed to add that type of content.",
          "type" : "warning",
          "repeat" : "0"
        }
      }
    ]
  }
}

So if someone needs to activate a rule before adding a new content, do not forget to use "Drupal is initializing" (=init) as an event, like @Pierre.Vriens suggested. Then a text comparison between the current page url (where an user goes by clicking on a button, in my case) and the form url (for example node/add/article) using regular expression without any escape characters (automatically added by Rules and Drupal, apparently).

  • Chapeau! And +1 ... Next question? PS: looks like you did NOT need "rules link", right? If so maybe you want to add a small remark about that too in your answer? – Pierre.Vriens Nov 24 '15 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.