4

I currently have a user's profile set up with some extra fields and when that user obtains the role "paid user" an entity is created with a rule and a node that copies those extra fields in the profile is then published. I'm having an issue however, that whenever I update the user's profile fields, it creates ANOTHER node and leaves the old one.

I'm looking for a solution that will either delete the duplicate node OR will update the current one.

Does anyone have any ideas for this? I've tried the deduped module someone built for Drupal 7 but it doesn't seem to be working.

EDIT: Here is the second Rule I've created to try to unpublish the older node.

Event: Before saving a user account
Conditions: Entity exists by property(Entity type: Node, Property: Title, Value: [account:field-business-profile])

Data comparison(Parameter: Data to compare:[account:field-bus-name],Data value:[account:field-business-profile:title])

Actions: Unpublish content(Parameter:Content:[account:field-business-profile])

EDIT2: I've updated the second rule to rooby's edits. The original content remains published though. I've tried going back and forth between the account-business-profile:nid and account-unchanged-business-profile:nid to no avail. Here are some pictures I've uploaded of the rule and the two pieces of content: enter image description here enter image description here

  • 1
    I would think you would need 2 rules. One for creating a node when the paid user role is obtained and another that updates the existing node when a profile is updated. For this you will need some way of linking the user to their node so that rules can load the node for a given user when the profile is saved. – rooby Apr 21 '13 at 1:48
  • 1
    And maybe a 3rd rule to unpublish the node when the user loses that role. And maybe a 4th to delete the node if that user is ever deleted. – rooby Apr 21 '13 at 1:50
  • @rooby Yes I believe I do have to use two rules and have been trying to, but in the Data Selectors whenever I try to access the older Node, it does not appear in the list. – CR47 Apr 21 '13 at 2:11
  • 1
    If you have an entity reference field on the profile that links to the node, then you set that value on the profile when creating the node. Then later using rules you can load the node base on that entity reference value and update it. There has to be some way that the profile & node are linked or it will never work. – rooby Apr 21 '13 at 2:15
  • @rooby Well first let me thank you for the tip about linking profiles with entity reference. I'm still having issues with the older content not being unpublished. I've updated my question to show what I mean and how I have the rule set up. – CR47 Apr 21 '13 at 2:46
5

Moving to an answer so I don't overload your question with comments.

Your second rules doesn't seem to ever load the node you want to unpublish/edit.

You need an action for "Fetch entity by property" (although I would be wary of fetching by title, I prefer the safety of node ID). For this action you can limit it to 1, so it only gets one node (there should only be 1 anyway).

Then that will fetch your node, and then you can do comparisons on that node or unpublish that node (or whatever else you may want).

The problem is though is that at this stage rules only knows it is an entity, it doesn't know what type or anything so you can't actually access its fields or do node actions like unpublish on it.

So (I think this is the only way) you have to install the http://drupal.org/project/rules_conditional module.

Then after your "Fetch entity by property" action you can add a loop and loop over entity-fetched (it will return an array even though you specified to return 1.

Then in this loop add a "Conditional".

Then in the conditional add an "If". For the if you can do entity has field, or entity is of type and content is of type. You can add multiple Ifs. If you want multiple nested ifs you have to add it like conditional if entity is of type node conditional if content is of type page action unpublish node

Once you have added the ifs rules will know that the fetched-entity is a node and what fields it has.

Then you can add an unpublish action and select entity-fetched (or list-item because of the loop)

So your rule might look like this:

Event: Before saving a user account
Action: Fetch entity by property(Parameter: Entity type: Node, Property: Title, Value: [account:field-business-profile], Limit result count: 1 Provides variables: Fetched entity (entity_fetched))
Action Loop: (Property: List: [entity-fetched], List item: Current list item (list_item))
  Conditional:
    If: Entity is of type (Parameter: Entity: [list-item], Entity type: Node)
      Conditional:
        If: Content is of type (Parameter: Content: [list-item], Content types: Basic page)
          Action: Unpublish content (Parameter: Content: [list-item])

Or it could look like this (without the loop, just working on the 1st entity-fetched):

Event: Before saving a user account
Action: Fetch entity by property(Parameter: Entity type: Node, Property: Title, Value: [account:field-business-profile], Limit result count: 1 Provides variables: Fetched entity (entity_fetched))
Conditional:
  If: Entity is of type (Parameter: Entity: [entity-fetched:0], Entity type: Node)
    Conditional:
      If: Content is of type (Parameter: Content: [entity-fetched:0], Content types: Basic page)
        Action: Unpublish content (Parameter: Content: [entity-fetched:0])
  • Thank you again for your help, I'm much closer than I was before. When I am adding the Loop in my second action on the rule, the property:list: area shows entity-fetched:author:, entity-fetched:body:, entity-fetched:source:, but nothing else. I tried inputting just entity:fetched manually but it gave me an error that it did not meet the list requirements. – CR47 Apr 21 '13 at 4:04
  • 1
    At the second action rules doesn't yet know what fields are on the entity. You have to wait until after the check for content is type. or instead of content is type you could use entity has field, and check that it has the field you want. - Because you are only dealing with a single node, you could also leave out the loop and do "Entity has field" on "entity-fetched:0", which will be the first result from your "Fetch entity by property" action. – rooby Apr 21 '13 at 4:15
  • 1
    I added a similar solution, but without the loop. – rooby Apr 21 '13 at 4:22
  • 1
    I just re-read your comment and realised I missed the point. It definitely should show entity-fetched, without anything after it. – rooby Apr 21 '13 at 4:24
  • Thanks so much for all your help! You've saved me what might have been days of searching, haha. I haven't finished but I'm at a good place where I can rest easy and sleep. I will be updating tomorrow on progress for those interested. – CR47 Apr 21 '13 at 4:52
2

One approach I've used on a site in the past is to create the entity on profile creation and link it with a relation (I used the Relation module because at the time I couldn't get the rules integration of Entity Reference working).

I then used permissions (with the Revisioning module because I also needed to approve changes) to limit access to editing that profile to users with the appropriate role.

Then, when the user becomes a paid user, I simply have a rule that publishes the node by calling it through the relation, and another rule that unpublishes the node.

This approach creates one extra node in the database per user; some people may not like this but for me it was a good tradeoff for simplicity's sake.

To copy the values of the fields, since the nodes will already be created and you don't have to worry about saving the node first, you can just add an action set component to the rule that is a sequence of Set data value actions.

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.