Hi. I'm assuming some custom views php code is what is needed here but not sure.

Here is what i need done and am willing to pay for...

I have a site with 2 roles:
admin
partner

I would like to be able to show a node reference drop down menu to only show current users's nodes. So each user can only node-ref to other nodes that they authored.

BUT if the user is an admin, they need to see the entire nodes list.

I thought this could be done with some views filters.
Using user:current as a filter does part of this requirement... but changing that list based on if the current user is as admin role is the part I don't know how to do.

I've looked at people saying to use views_or and viewsphpfilter... and this is all fine but I don't know exactly how to set this up and what code will work to do what I have described.

Please contact me if you can help with this project. And if you have some examples of doing something like this before that would be good to see to make sure we are on the same page.

Thanks
-j

Comments

WorldFallz’s picture

Something to consider...

you could do it by creating 2 different block views and controlling which role sees which view via the block role visibility settings.

nikit’s picture

This module can help to you: http://drupal.org/project/views_or
Then, add filters: {Current logged user} OR {user roles = admin role}

tomjtyeung’s picture

just use filter => add "user: current" => choose "yes"

nikit’s picture

Incorrect.

criznach’s picture

I've just set this up on my scratch site and believe I have what you want.

The "views or" module did not work because the "User: Role" filter applies to the node's creator roles instead of the current user's roles. I used "views_php" rather than "viewsphpfilter" because it offers a 7.x upgrade path.

To make this work, install and enable "viewsphpfilter", then edit your view. Your view should return the title field, and should probably filter on "Node: Published" and "Node: Type". Add a filter of type "Global: PHP". In the "SQL filter code box", enter the following:

// Change this to the name of your admin role if necessary
$admin_role = 'admin';
global $user;
// If user is part of the role specified above...
if (in_array($admin_role, $user->roles)) {
  return 'TRUE';
} else {
  // Otherwise return a SQL where clause
  // support table prefix if necessary
  return "{node}.uid = ". $user->uid;
}

Change $admin_role to your desired role.

Save and preview. This worked for me with 3 roles where 1 was admin. Let me know if it works.

Chris

nikit’s picture

yes, this is another solution, but it's take more resources from server, because acquire all needed data from DB, only after hide not-needed items by calculating PHP code.
Views Or module give possibility for Views to acquire only needed data.

criznach’s picture

No it doesn't. Look at the generated SQL query and you will see it's a WHERE clause. Not executed for every row in PHP.

For a user with the admin role:

SELECT node.nid AS nid,
   node.title AS node_title
 FROM node node 
 WHERE (node.status <> 0) AND (node.type in ('parent')) AND (TRUE)
   ORDER BY node_title ASC

For a user without admin role:

SELECT node.nid AS nid,
   node.title AS node_title
 FROM node node 
 WHERE (node.status <> 0) AND (node.type in ('parent')) AND (5 = node.uid)
   ORDER BY node_title ASC
nikit’s picture

ah, i am sorry, good comment for investigating this module more time. Thanks.

criznach’s picture

Sorry, I meant to write "enable Views PHP" rather than "enable viewsphpfilter". I'm not using viewsphpfilter at all.

rbrownell’s picture

Hi There;

Thanks for posting this script. Quick question though. I tried it using the latest version of views and views php and it doesn't seem to be working any more. Is it still working for you? Does it go in as a filter or contextual filter?

-R

criznach’s picture

I haven't tried it with the latest versions. Try logging the SQL queries using the devel module and see if it's generating something like what you see above. If not, you can post here and I'll try to help.

rbrownell’s picture

My content type is called "book", and the name of the group that can see all of the books as opposed to just their own are called "moderator."

This filter is put in to the Filter Criteria (I figured it wasn't a contextual filter since Global: PHP was not an option in the context filter) of D7's Views 3 using the Views PHP Module and the Global: PHP Filter (without the PHP tags as per the instructions on the filter).

$admin_role = 'moderator';
global $user;
if (in_array($admin_role, $user->roles)) {
  return 'TRUE';
} else {
  return "{node}.uid = ". $user->uid;
}

For the user that is within the "moderator" group it yields:
SELECT node.title AS node_title, node.nid AS nid FROM node node WHERE (( (node.status = '1') AND (node.type IN ('book')) ))

For everyone else it yields:
SELECT node.title AS node_title, node.nid AS nid FROM node node WHERE (( (node.status = '1') AND (node.type IN ('book')) ))

Both end up yielding empty lists despite the fact that both users own content and it is published and also of the 'book' type. Is this the code or the Views PHP Module?

Thank you so much for responding. I honestly didn't think anyone was because this post is really old. :)

criznach’s picture

I watch my posts on the d.o dashboard page. :)

It looks like Views PHP filters have changed for Views 3. You no longer add a SQL where clause, but instead you can examine the contents of the row and return TRUE/FALSE to exclude it. Probably not as efficient as SQL, but here's some rough code that is close to what you need...

$admin_role = 'admin';
global $user;
// If user is part of the role specified above...
if (in_array($admin_role, $user->roles)) {
  // Do not exclude this row by returning FALSE
  return FALSE;
  // Otherwise check if the current user was the node author
  // $row->uid below may need to be adjusted for your view.
} else if ($row->uid == $user->uid) {
  // Do not exclude this row by returning FALSE
  return FALSE;
}
// Default to excluding this row by returning TRUE
return TRUE;

I haven't tested this, but I think it's close.

rbrownell’s picture

It worked. Initially I was experiencing an error but I figured out that it was because I needed to have the UID as a field (excluded of course) in order for $row->uid to be an available variable.

It seems to run pretty fast too. I remember the php filter when it was SQL based, I wonder why they changed it?

Thank you so much for this!

-Ryan

criznach’s picture

It shouldn't be a problem unless your queries return thousands of results. Pagers help with that. If it got more complex and slowed down due to filters you could alter the SQL query with a custom module.

But this makes me wonder... What if you want 20 items per page, but the filter removes 10 of them? I should look at the code...

LarsKramer’s picture

With Views for Drupal 7 you can make two displays using the same path, use filter "current user = author" on one of them, and then only give admin role access to the one without filter. Then Drupal will automatically show the right display depending on user role. Very cool. however, I don't think this is possible with Drupal 6, at least not with Views 2.x.

nikit’s picture

May be via Context?
But task here about "node reference", I assume this will not work for your comment, is it?