1

I'm trying to filter published content by the values set inside of two fields (one or the other). Right now, I'm successfully filtering my content by one field:

Contextual Filter

If field_targetuser = logged in uid, than display content.

However, I also want to show content in which field_universal = YES , regardless of the logged in uid.

Naturally, implementing the first Contextual Filter and than a second only further filters the intial filter. What I'm trying to accomplish:

Show all content of this type if targetuser matches logged in user id, but ALSO show all content where field_universal = YES, regardless of what appears in the targetuser id.

Views setup:

enter image description here

2
  • Why don't you use the Views filters instead of the PHP filter? Commented May 27, 2016 at 3:19
  • @longboardnode Trying to? PHP filter was a suggested answer below.
    – Brittany
    Commented May 27, 2016 at 5:40

5 Answers 5

2
+50

It appears that you are trying to do and OR filter in contextual filters, and as @jreynolds mentions, OR conditional are not available in contextual filters out of the box. @jreynolds' solution is to move the arguments into the filters, which is a solution I like very much, but I also hesitate to use a sandbox module if I can avoid it. Instead I'm using Views Contextual Filters OR. Which has a dev version available. With this module installed you need to go into the query settings in the advanced section of your view and check a box next to "Contextual filters OR". The disadvantage of this, of course, is that you can't do more advanced logic like and'ing two filters and or'ing a third.

Another solution is to access the views api in a custom module and change the contextual filter query to be an OR query as explained in This answer.

UPDATE I think you should be able to accomplish this by putting both of your filters in contextual filters and using the module I recommended above. You currently search for your user field matching the currently logged in user in contextual filters. Now add a second contextual filter that matches for field_universal and provides a fixed default value of yes or whatever it is that needs to match in that field. That in combination with the Views Contextual Filters OR module should query for the message is meant for the current user OR the message is a universal one.

9
  • I installed the Views Contextual Filters OR module, and checked the appropriate box in the query settings. However, "Or" still doesn't seem to be an option in Contextual Filters when I click on the "add" dropdown?
    – Brittany
    Commented May 31, 2016 at 3:32
  • Once you check the box in query settings your contextual filters should all be running as an or query. If they aren't, maybe try clearing the cache. You can also turn on "show SQL query" in the views settings.
    – UltraBob
    Commented May 31, 2016 at 3:33
  • So when I add Content: universalswap (aka the content in this field) to my contextual filter, I want to say "if content: universalswap = Yes" - is there a way to do that from here? It looks like I can only do it from the Filter Criteria section?
    – Brittany
    Commented May 31, 2016 at 3:37
  • If you have one contextual filter that checks whether the logged in uid is == to the field_target_uid and another contextual filter that checks whether field_universalswap == "yes" the module you've enabled will put an OR between those two checks. Normally there would always be an AND between those two checks.
    – UltraBob
    Commented May 31, 2016 at 3:41
  • 1
    Your update = genius. A well deserved +50, my friend. Thank you so much!
    – Brittany
    Commented Jun 1, 2016 at 14:51
3

You can solve this without any additional modules or coding, just with pure Views + Entity Reference. Here is how:

  1. You need to add 1 more relationship to your current View (looking at your screenshot):
    • Entity Reference: Targeted User => This is the Entity Reference field that points to a User, what you call "targetuser"
  2. You need to add a "User: Current" filter to your view. Once you click on that, you should see the following: enter image description here This filter will allow you to select only the nodes where the targeteduser is the same as the logged-in (current) user.
  3. You need to place the universalswap in an OR relationship to the new filter inside a FILTER GROUP. Then place that group in an AND relationship to the rest of your filters, i.e. Type = Messages.

That should do it without any additional modules. Here is a screenshot of my final View configuration: enter image description here I am logged in as admin (uid:1) and you can see in the results that I am getting all messages that are either "Universal" or targeted at me.

Good luck!

6
  • This should be the accepted answer! Commented May 31, 2016 at 13:43
  • targetUser is not an entity reference - it is a text field. This view is acting as the backend for an app - and thus the app is posting the uid to targetuser field manually. Unfortunately I can't make this field an Entity Reference, as I'm unable to post to it with a simple text value from my app...
    – Brittany
    Commented May 31, 2016 at 15:20
  • That's too bad, you are missing all the niceties of entity references. If you wanted however, you could trigger an entity reference creation on a node_save event and populate an entity reference field automatically. Commented May 31, 2016 at 15:27
  • Sure, this seems like an totally easy req. At the same time, you can get more options if you set your data right, for this or for future tasks. Setting up a rule to do that auto-conversion (text to entity-reference) would offer lots of benefits, including solving this one here in a clean way. Commented May 31, 2016 at 15:46
  • I think I fixed it... See my answer below. The results seem to work swimmingly?
    – Brittany
    Commented May 31, 2016 at 15:50
1

The most straightforward way to do this in my view would be to add field_targetuser and field_universal to your fields and exclude them from display then create a views Global: PHP filter with the following filter code in

global $user;

if($user->uid == $data->field_targetuser || $data->field_universal == "yes")          
{
    return false;
} else {
    return true;
}

The code here basically checks to see if the current uid matches the targetuser field or the field_universal equals yes. If either of these conditions are met the filter returns false which displays the result, otherwise return true which excludes the result.

Hope this is what you were looking for :-)

6
  • Strangely, this code in global:php under filter criteria gives me no results (even though there should be results visible)?
    – Brittany
    Commented May 27, 2016 at 0:43
  • Try dropping dsm($data); into your php filter and just double check that the property names i've put in the conditional match the property names on the data object. If they're incorrect just replace them with the ones from your data object. Commented May 27, 2016 at 0:53
  • Property names are correct. When I remove global $user, all results are visible but not filtered (not sure if that helps or not). Though $user doesn't seem to be in the view list of available variables :/
    – Brittany
    Commented May 27, 2016 at 0:58
  • See edit above (included list of available variables).
    – Brittany
    Commented May 27, 2016 at 1:05
  • $user is a global variable that refers to the currently accessing user so it shouldn't be in the $data. I noticed there is no field_universal in your available variables but there is field_universalswap. Is this the field you're using to decide if a row can be viewed by all users? If so you need to replace $data->field_universal with $data->field_universalswap Commented May 27, 2016 at 8:03
1

What you need is a way to move the contextual filters down into the normal filter section of Views where you can apply conditional logic on them (in your case an OR condition)

There is a module for that: Views arguments in filters

There are at least two problems with arguments as they are currently used in Views:

  • Many people find it difficult to wrap their head around how arguments work.
  • It is not possible to use operators on arguments, for example to show all nodes created after the timestamp value you provide in an argument, or display all the nodes that in their title contain the word/phrase in the argument. There is just "equals" or "not equals". (Unless you more or less code your own argument handlers, which would end up a special case that few others can make use of.)
3
  • No download link for this module?
    – Brittany
    Commented May 29, 2016 at 16:40
  • Yes you have to install git and download as per instructions on module page. Very easy. Commented May 30, 2016 at 5:22
  • See my answer below - think I found a simpler solution.
    – Brittany
    Commented May 31, 2016 at 16:09
0

It appears as though the below view settings fixed the issue. This setup displays Messages for the current user, OR messages in which field_universalswap = Yes...

Because the field_targetuser is always the logged in user, it displays current user's messages. If the field_targetuser does not match the current user, it still displays those messages if field_universalswap = Yes.

My only tick about this route: It also displays messages I've sent - not sure that's a bad thing yet though...

enter image description here

5
  • The (current user == author of a message) condition is not the same as (current user == targeted user) though. Right? Commented May 31, 2016 at 16:12
  • @StefanosPetrakis Ugh, nevermind. Not showing messages from other users if universalswap = No... Lol. Damn.
    – Brittany
    Commented May 31, 2016 at 16:32
  • Have you tried my updated answer? I think it is likely that that will do it for you.
    – UltraBob
    Commented Jun 1, 2016 at 5:44
  • @UltraBob Just saw your updated answer; implemented, and I think it worked... Double checking now : ) Stand by!! lol
    – Brittany
    Commented Jun 1, 2016 at 14:42
  • Fingers crossed.
    – UltraBob
    Commented Jun 1, 2016 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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