1

I wonder how to access node properties via another node with Rules. I already store the link of my other node in a field (of the original node), but I don't know if we can do that.

I'm using the Drupal Commerce 7.x, Rules Link, and Content Access modules.

Here is what I want to do: after a candidate (a particular user) clicks on a rules link in a 1st node, I want to grant access for that candidate to a 2nd node and do a redirection to that 2nd node.

Here is what I currently do and how it works : When an Advertiser creates a node of type "classified ad" i use a rule to do 2 things:

  1. Store the url of the primary node in one of the node's fields.
  2. Clone that node and convert it in another content type (= "classified complete").

Then with Content Access I block the access for all users except the author (in this case the Advertiser), administrator and super users.

When a candidate clicks on the link in the 1st node (with content type "classified ad"), the candidate spends 100 credits (using the Userpoints module). Next I need to grant the candidate access to the 2nd node (with content type "classified complete"), followed by a page redirect to that 2nd node.

a) My Rules Link export :

{
  "settings" : {
    "text" : "Access to contact informations",
    "link_type" : "confirm",
    "bundles" : { "classified" : "classified" },
    "entity_link" : 1,
    "view_mode" : { "full" : "full" },
    "confirm_question" : "spend credits",
    "confirm_description" : "Would you like to spend 100 credits to access contacts informations ?"
  },
  "name" : "access_to_contact_info_links",
  "label" : "authenticated user Link contact infos ",
  "path" : "access_to_contact_info_links",
  "entity_type" : "node",
  "rdf_mapping" : []
}

b) Rules Link Access condition (don't know how to export that) : I use a "user has role" condition and I check if the user is authenticated

c) Rules Link Reaction rule:

{ "rules_link_set_access_to_contact_info_links" : {
    "LABEL" : "Rules link: Access to contact info links rules set",
    "PLUGIN" : "rule set",
    "OWNER" : "rules",
    "REQUIRES" : [
      "rules",
      "userpoints_rules",
      "rules_conditional",
      "rules_i18n",
      "content_access_rules"
    ],
    "USES VARIABLES" : { "node" : { "label" : "node", "type" : "node" } },
    "RULES" : [
      { "RULE" : {
          "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } },
          "IF" : [
            { "user_has_role" : {
                "account" : [ "site:current-user" ],
                "roles" : { "value" : { "2" : "2" } }
              }
            }
          ],
          "DO" : [
            { "userpoints_rules_get_current_points" : {
                "USING" : { "user" : [ "site:current-user" ], "tid" : "86" },
                "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } }
              }
            },
            { "CONDITIONAL" : [
                {
                  "IF" : { "data_is" : { "data" : [ "loaded-points" ], "op" : "\u003C", "value" : "100" } },
                  "DO" : [
                    { "drupal_message" : { "message" : "You don\u0027t have enough credits !", "type" : "error" } }
                  ]
                },
                { "ELSE" : [
                    { "userpoints_action_grant_points" : {
                        "user" : [ "site:current-user" ],
                        "points" : "-100",
                        "tid" : "86",
                        "entity" : [ "" ],
                        "operation" : "Remove",
                        "display" : "1",
                        "moderate" : "approved"
                      }
                    },
                    { "CONDITIONAL" : [
                        {
                          "IF" : { "node_is_of_type" : {
                              "node" : [ "node" ],
                              "type" : { "value" : { "classified_complete" : "classified_complete" } }
                            }
                          },
                          "DO" : [
                            { "CONDITIONAL" : [
                                {
                                  "IF" : { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_link_to_unlocked_content_t" } },
                                  "DO" : [
                                    { "drupal_message" : { "message" : "Trying to grant access !" } },
                                    { "content_access_action_user_grant" : {
                                        "node" : [ "node" ],
                                        "content_access_user_view" : [ "site:current-user" ],
                                        "content_access_user_update" : [ "" ],
                                        "content_access_user_delete" : [ "" ]
                                      }
                                    },
                                    { "redirect" : { "url" : "[node:field-link-to-unlocked-content-t]", "destination" : "1" } }
                                  ]
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ],
          "LABEL" : "Enough Credits"
        }
      }
    ]
  }
}

**

Is it possible ?

  • Ok, making some progress (your edit confirms what I was guessing, so no more need for guessing). Please edit it again to explain (1) how you implemented "stock the link of my other node in a field" (ie is it just an integer field that contains the node id, or something else) (2) how you've configured the Rules link module for this scenario (i.e. include an export of (a) the Rules link (b) access conditions for the Rules link (c) reactions for the rules link (cfr to drupal.stackexchange.com/a/249720/39516 for a sample to explain all this). Rules link is great, but not easy! – Pierre.Vriens Dec 29 '17 at 16:48
  • @Pierre,1) i stock the url of the node "classified complete" into a field of the node "classified ad" 2) yes i can take the id instead of the url i just need to change the token used :). i'll try to replace my "users" thing in my primary post ^^ (sry i'm not talking very well this is not my natal language so my vocabulary is a bit reduced) – Quentin Jan 2 '18 at 15:12
  • Hi @Pierre sry to bother you, i up the post 'cause i rly need this to be fixed and you seems to be the only one who cares about it (or trying to understand it atleast, maybe my explanations are difficult to understand ). Without all my details to be simple i just need to grant access to a node with the id or url of it for a user (with content access and rules link), do you know how to do that ? Thanks in advance ! – Quentin Jan 4 '18 at 8:38
1

This is (was) quite a challenging question, for a number of reasons:

  • It's impossible to import your rule(s), and not only if you don't have the content types defined like in your case: you need the ACL module to have the Rules Action with machine name content_access_action_user_grant available (without that the import will fail). Moreover, the ACL module seems to be a weak module dependency of the Content Access module. So if ACL is NOT enabled, then trying to import your rule will fail.
  • For unknown (to me) reasons, your exported rule claims to have a dependency (cfr the "requires") related to the rules_i18n module. However, there is nothing in your rules that actually uses it. So I just removed that line prior to trying to import your rule in my environment.
  • Your naming conventions of your rules variables are pretty challenging: everything is called ... "node" ... that's asking for getting confused (since you have 2 different content types involved ...).

Anyway, have a look at this simplified (I think) Rules Component that replaces the "reaction"-rules (item "c)" in your question, with machine name rules_link_set_access_to_contact_info_links):

{ "rules_link_set_access_to_contact_info_links" : {
    "LABEL" : "Rules link: Access to contact info links rules set",
    "PLUGIN" : "rule set",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "userpoints_rules", "rules_conditional" ],
    "USES VARIABLES" : { "node" : { "label" : "node", "type" : "node" } },
    "RULES" : [
      { "RULE" : {
          "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } },
          "IF" : [
            { "user_has_role" : {
                "account" : [ "site:current-user" ],
                "roles" : { "value" : { "2" : "2" } }
              }
            }
          ],
          "DO" : [
            { "userpoints_rules_get_current_points" : {
                "USING" : { "user" : [ "site:current-user" ], "tid" : "86" },
                "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } }
              }
            },
            { "CONDITIONAL" : [
                {
                  "IF" : { "data_is" : { "data" : [ "loaded-points" ], "op" : "\u003C", "value" : "100" } },
                  "DO" : [
                    { "drupal_message" : { "message" : "You don\u0027t have enough credits !", "type" : "error" } }
                  ]
                },
                { "ELSE" : [
                    { "userpoints_action_grant_points" : {
                        "user" : [ "site:current-user" ],
                        "points" : "-100",
                        "tid" : "86",
                        "entity" : [ "" ],
                        "operation" : "Remove",
                        "display" : "1",
                        "moderate" : "approved"
                      }
                    },
                    { "component_rules_grant_access_to_a_node" : { "node_containing_classified_ad" : [ "node" ] } }
                  ]
                }
              ]
            }
          ],
          "LABEL" : "Reduce points and grant access"
        }
      }
    ]
  }
}

Apart from the label (which I changed from "Enough Credits" to "Reduce points and grant access"), the only difference with your original rules set, is that all Rules Actions after the Rules Action to deduct userpoints, have been replaced by an additional (new) Rules Component named rules_grant_access_to_a_node. And here is how that Rules Component looks like:

{ "rules_grant_access_to_a_node" : {
    "LABEL" : "Grant access to a node",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "content_access_rules" ],
    "USES VARIABLES" : { "node_containing_classified_ad" : { "label" : "Node containing classified ad", "type" : "node" } },
    "IF" : [
      { "node_is_of_type" : {
          "node" : [ "node-containing-classified-ad" ],
          "type" : { "value" : { "article" : "article" } }
        }
      }
    ],
    "DO" : [
      { "entity_fetch" : {
          "USING" : {
            "type" : "node",
            "id" : [ "node-containing-classified-ad:field-free-format-nr" ]
          },
          "PROVIDE" : { "entity_fetched" : { "fetched_classified_complete" : "Fetched classified complete" } }
        }
      },
      { "drupal_message" : { "message" : "Trying to grant access to node with Id = [fetched-classified-complete:field_free_format_nr]" } },
      { "content_access_action_user_grant" : {
          "node" : [ "fetched-classified-complete" ],
          "content_access_user_view" : [ "site:current-user" ],
          "content_access_user_update" : [ "" ],
          "content_access_user_delete" : [ "" ]
        }
      },
      { "redirect" : { "url" : [ "fetched-classified-complete:url" ] } }
    ]
  }
}

You should be able to import this Rules Component in your own site also, though you'll have to apply these corrections prior to importing:

  • replace machine name article by classified (assuming that's the content type for your "Classified Ad").
  • the field-free-format-nr (name it whatever you want) is an integer field defined for your "Classified ad", which contains (only!) the node Id for which you want to grant access (which relates to your "classified complete" content type). So as per your extra comment (= "...yes i can take the id instead of the url...") you'll need to slightly adapt the design of your content type.

Note these (way more?) meaningful variables I used (instead of just "node"):

  • node_containing_classified_ad
  • fetched_classified_complete

Some more details about this Rules Component:

  • Rules Condition: check the type of the node used as parameter. That will give us access (in the Rules Actions following them) to the crucial field field-free-format-nr.
  • Rules Actions:
    • Fetch entity by ID (i.e. a node) with ID indicated in node-containing-classified-ad:field-free-format-nr, and give it a name like fetched_classified_complete (see the importance of naming conventions for parameters!?!?!?).
    • Continue with the 3 Rules Actions similar to what is included in your question (but with a meaningful name like fetched_classified_complete). Note the adapted token in the redirect action also.

Voilà ...

  • Man i have no words, you're my hero !!! Thank you so much it works like a charm ! i'm so happy. I promess i'll try a better naming method for my next rules ^^ (i work on drupal since 1 month so its a bit fresh for now, i have a lot of things to learn). Thank you again for the time you spent on my issue <3 – Quentin Jan 5 '18 at 10:50
  • Hey @Quentin, merci for the kudos. May I say "What else did you expect?". I must admit this has been one of the most challenging questions to digest (understand, get clarifications about). And also not obvious to be able to import your exported rules in my Drupal environment (cfr the 3 bullets in the beginning of my answer). It would have been way more easy to downvote (or vote to close) the first version of your question, but I knew from the beginning that "fetch entity by ID" would solve your question. Next (Rules related) question? – Pierre.Vriens Jan 5 '18 at 11:00
  • sry about that @Pierre, you're right. For now i don't have any questions about rules ! i'm a bit stuck with views and filters, i try to display all ads except those who are created by the current-user in a page, I'm digging to find out :) – Quentin Jan 5 '18 at 15:10
  • Hey @Pierre how are you ? i'm comming back 'cause i need to display a rules link in the "classified" node only if my current user already have an access granted to the "classified complete" node. I don't know how to check that in "Access conditions" of rules link ! Do you have an idea ? – Quentin Jan 8 '18 at 9:58
  • alright i posted a new question there, drupal.stackexchange.com/questions/253316/… I was talking about "classified ad" just forgot the "ad" word. Yes i want to display a link when the content of it has an access granted. For exemple when i unlock a "classified complete" node via a "classified ad" node, my "classified complete" node has now an access granted, so now i want to display a link in the "classified ad" node who display if i already have an access granted to the "classified complete" node. – Quentin Jan 8 '18 at 12:36

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.