-2

How to force a user to post a node after registering?

The scenario would be the following: after registering, the user could not access the site without having created a node. Once this node is created, it would have access to the site normally.

2
  • You would need an event/hook for hook_user_login that checks if they have a node of specific type made, and if not, redirects them to your form to do so. You would want an event subscriber too, so they could not navigate anywhere without doing this.
    – Kevin
    Commented Apr 1, 2021 at 18:04
  • That's exactly what Rules provides - an event on user login and an event subscriber where actions are executed dependent upon conditions. All without writing code.
    – anonymous
    Commented Apr 1, 2021 at 18:37

1 Answer 1

2

Access to a Drupal site is provided by permissions, and permissions are assigned to Roles. So the first thing to do is to create two types of users - one which can access the site when logged on and one which can't access the site when logged on. After that we can talk about how and when to change a specific user from the "can't access" to the "can access" type.

A new user in Drupal is automatically assigned the "authenticated" role. Because you want new users by default to NOT have access to the site, you should edit the "authenticated" role to remove permissions. Test this to make sure that a new user has only the limited permissions you want them to have.

Now create a new role for your "full access" users. I will call that role "full member access". Edit the role to have the permissions you want. Test to make sure this is what you want.

Once you have the two roles setup, it is now time to figure out how to change a user from "authenticated" to "full member access". Because you tagged this issue as "rules" I assume you want to use Rules to do this. Rules provides a UI where you can do this without programming, and where you can easily modify your conditions for changing the user role or even take addition steps like sending the newly privileged user a welcome email, again without programming.

Here's the outline of what the Rule should look like, followed by an export of the Rule:

  • Event: After saving a new content item (This will happen when the user creates a new node. You may also restrict this event to fire only when content of a specific type is created.)

  • Condition: User has role(s) (Check to see if the user has the "full member access" role yet.)

  • Action: Add user role (This will add the "full member access" role to the user who just created a node and does not yet have full access.)

The following export of rules.reaction.upgrade_role_to_full_member_access.yml implements this:

langcode: en
status: true
dependencies: {  }
id: upgrade_role_to_full_member_access
label: 'Upgrade role to full member access'
events:
  -
    event_name: 'rules_entity_insert:node'
description: 'Upgrade role to full member access after user creates their first node.'
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 7d99ef94-f454-405e-bb0d-0375816dec79
  weight: 0
  conditions:
    id: rules_and
    uuid: 3b1072a4-4a67-470f-8cd9-500a24a21b7c
    weight: 0
    conditions:
      -
        id: rules_condition
        uuid: 5b49ef27-e37e-4793-bda9-9fdb3940f374
        weight: 0
        context_values:
          roles:
            - full_member_access
          operation: AND
        context_mapping:
          user: '@user.current_user_context:current_user'
        context_processors:
          roles:
            rules_tokens: {  }
          operation:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_user_has_role
        negate: true
  actions:
    id: rules_action_set
    uuid: 994d29d7-302e-4c50-a0b6-a559f74dff3d
    weight: 0
    actions:
      -
        id: rules_action
        uuid: 17e5bbfd-8966-4b7d-aec7-5b9158c1cf18
        weight: 0
        context_values:
          roles:
            - full_member_access
        context_mapping:
          user: '@user.current_user_context:current_user'
        context_processors:
          roles:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_user_role_add

The remaining issue is how to inform the new user that they need to create a node in order to get full access. To do this you can use another Rule that looks like this:

  • Event: User has logged in

  • Condition: User has role(s) (Check to see if the user is "authenticated" - if so the user still needs to create a node.)

  • Action: Show a message on the site (If the condition is TRUE then we know the user needs to create a node, so use this message to inform them of what they need to do.)

  • Action: Page redirect (Redirect the user to the node create page, /node/add.)

Or if you have a custom page/form set up for the creation of this first node, then you could simply redirect to that page instead.

The following export of rules.reaction.redirect_to_create_node.yml implements this:

langcode: en
status: true
dependencies: {  }
id: redirect_to_create_node
label: 'Redirect to create node'
events:
  -
    event_name: rules_user_login
description: 'Redirect user to node creation page on login, if user doesn''t already have full access.'
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 5e666529-2664-427c-b0b6-e51e9d464606
  weight: 0
  conditions:
    id: rules_and
    uuid: 6cd14b6a-d0d7-4226-99be-42f61ca3d2b0
    weight: 0
    conditions:
      -
        id: rules_condition
        uuid: c3c6c654-96e5-4cea-96f3-ba32a2cbf2ec
        weight: 0
        context_values:
          roles:
            - full_member_access
          operation: AND
        context_mapping:
          user: account
        context_processors:
          roles:
            rules_tokens: {  }
          operation:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_user_has_role
        negate: true
  actions:
    id: rules_action_set
    uuid: bacfc01b-bdb8-4386-92ca-1e7dad78574e
    weight: 0
    actions:
      -
        id: rules_action
        uuid: e25bbe11-ef49-4061-a05c-9af5c715cbf6
        weight: 0
        context_values:
          message: 'You need to create a new node using the form on this page before you will be allowed access to the site.'
          type: warning
          repeat: false
        context_mapping: {  }
        context_processors:
          message:
            rules_tokens: {  }
          type:
            rules_tokens: {  }
          repeat:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_system_message
      -
        id: rules_action
        uuid: a449cefe-e3f8-488c-b2ac-ec4cb5e3e835
        weight: 0
        context_values:
          url: /node/add
        context_mapping: {  }
        context_processors:
          url:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_page_redirect

Note also that in order to make this work, you will have to temporarily use the Rules patch at https://www.drupal.org/project/rules/issues/2800749#comment-13942286 - that patch adds the necessary feature to manipulate Roles like this. That patch is already RTBC and should be committed to Rules within the next month, so after that the patch won't be needed anymore.

2
  • Thanks anonymous for this great answer. However, I found that in the process it was better to change the user's role when their node was published (and therefore moderated). I posted another question.
    – Hgfdsoiu
    Commented Apr 2, 2021 at 15:17
  • Yeah, but that's trivial to change in the above answer if your needs change, like they just did ... Just change the event and conditions in the above Rule. That's what makes Rules convenient, you can make these changes from the UI without writing or rewriting the code. A similar example is given in drupal.org/project/rules/issues/2978800#comment-12678208 where in that case the user is unblocked once a node created by that user is published.
    – anonymous
    Commented Apr 3, 2021 at 20:08

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