1

I have a Content Type with a user reference field.

I want that the user can display\access only to the nodes that referenced to him.

Can I do this with Views?

I already tried the modules Node access user reference and Node access node reference with no success because they have a huge bug. When the module is enabled many View becomes inaccessible ( https://www.drupal.org/node/1311460 ).

  • If you are willing to use the entity references and rules modules instead which could both be very beneficial elsewhere, there could be an easy solution. I don't wanna force either on ya so let me know. – Niall Murphy Feb 13 '16 at 3:45
  • @Niall Murphy : I'm willing to use entity reference and rules but how I can to do it? I cannot to set the rules condition and rules action. – kb8 Feb 13 '16 at 9:37
  • Solution added below.. Let me know if ya have any trouble with it. – Niall Murphy Feb 13 '16 at 10:42
2

Entity Reference and Rules Solution.

  1. Install both modules
  2. Add an entity reference field with unlimited values to your content type. Make sure it references users.
  3. For views, create a content view and add a contextual filter for the field you created. My test contextual filter was called Content: User Ref Test. Your contextual filter will have the same name as the field you created.
  4. In the contextual filter's settings, click Provide Default: User ID from logged in User. This will only show content where the user has been referenced.
  5. To make the content safe from typing in the url, create a Content is Viewed rule for that content type.
  6. In the conditions, choose "list contains item". The list is the entity reference field and the item is the logged in user. At the bottom of the condition, you then negate the rule. It should look like NOT Item in List "Parameter: List: [node:field-user-ref-test], Item: [site:current-user]
  7. Add a second data comparison condition that allows the admin (or you could do this by user role) to view the content. Negate this condition as well. NOT Data Comparison > Parameter: Data to compare: [site:current-user:uid], Data value: 1
  8. Add a system redirect to the homepage and a message explaining why the user couldn't view the content.

If it doesn't work, check to make sure the entity reference field is set to unlimited because that's why we use the list in rules.

  • Note that you can use a normal filter User: Current instead of a contextual filter. – Елин Й. Feb 13 '16 at 11:10
  • That's in a user view. You have to use a contextual filter in a content view. – Niall Murphy Feb 13 '16 at 11:13
  • 1
    No, if you have the relationship to the user, you can use a normal filter selecting that relationship. – Елин Й. Feb 13 '16 at 11:21
  • Ha, yea. I checked the filter list before adding the relationship. – Niall Murphy Feb 13 '16 at 11:24
  • Thank you @Niall Murphy but if my reference field is set to 1 value, can I use NOT Data Comparison instead of NOT Item in List "Parameter"? – kb8 Feb 13 '16 at 12:10
1

You can do that using views, following the steps to display only the nodes referencing the current user:

  1. Add a relationship to your field: Entity Reference: Referenced Entity A bridge to the User entity that is referenced via field_your_reference_field
  2. Add a filter criteria User: Current and select as Relationship the newly added relationship, which should be automatically selected if you don't have any other relationships in your view. Select the radio button Yes.
UPDATE:

As I read your question again, I saw you want to restrict the access, as well. There are many ways to achieve that. You may do that with Rules or using node access grants hook_node_access_records() and hook_node_grants(). If you need instructions on how to use node access grants, I can improve my answer. Otherwise, the solution with rules is already described by Niall Murphy.

UPDATE 2: Using node access grants

If you choose to use node access grants, then you don't need to do above filter on views. Since, views already respects the node access grants and filters the nodes readily.

You need to implement two functions in your custom module: hook_node_access_records() and hook_node_grants().

/**
 * Implements hook_node_access_records().
 */
function YOURMODULE_node_access_records($node) {
  $grants = array();
  if ($node->type == 'YOUR_CONTENT_TYPE') {
    $referenced_uid = $node->field_your_reference_field['und'][0]['target_id'];
    $grants[] = array(
      'realm' => 'YOUR_CONTENT_TYPE_referenced_user', // The naming of the realm is up to you.
      'gid' => $referenced_uid,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
    );
  }

  return $grants;
}

/**
 * Implements hook_node_grants().
 */
function YOURMODULE_node_grants($account, $op) {
  $grants['YOUR_CONTENT_TYPE_referenced_user'] = array($account->uid);

  return $grants;
}
Explanation of the above code:

The first function is called on saving the node and puts the node into a realm named YOUR_CONTENT_TYPE_referenced_user and gives it a Grant Id as the referenced user's uid.

Second function is called on every page call, so it is important not to do any heavy calculations on this part. This function gives the user the grant Id same as his user Id on the same realm. So that this user can view all nodes in that realm with a Grant Id equals to his user Id.

  • 1
    The rule is stop users from viewing the node anyway. – Niall Murphy Feb 13 '16 at 11:06
  • As I read the question again, I noticed that 'access' word :) – Елин Й. Feb 13 '16 at 11:08
  • The solution of Niall seems work well but I'm open to know node access grants. This I could serve afterwards. – kb8 Feb 13 '16 at 12:30
  • @kb8 I updated my answer an included a working example of how to implement node grants to control the access. – Елин Й. Feb 28 '16 at 16:12
0

Just add contextualy filter in it. Select option 'provide default value' and check the option, user id from logged in url. This view will give only the content uploaded by him/her.

  • It's not for author access. – Niall Murphy Feb 13 '16 at 10:27

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.