I'm unable to filter nodes that have the same taxonomy terms as the user profile. I only want nodes to show that have at least one matching term.

Views settings below

Relationships
Node Revision: user
(user) User: Terms

Arguments
None

Filters
User: Active yes
(Terms for the user) User: Term - corresponding vocab selected

Thanks for the great module and for looking at my post.

Also, didn't know if this request was better suited for here or the forum, thought I'd try here first.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joachim’s picture

Status: Active » Postponed (maintainer needs more info)

I don't understand what it is you're trying to do with that view.

- what type of view is it?
- which user profile? the current user doing the viewing? It looks from the setup you have that you are trying to say 'show me nodes where the node terms are the same as the terms of the node author'. I strongly doubt you will be able to get that out of Views.

jcolby1028’s picture

joachim-

Thank you for your reply.

- what type of view is it? - Node View

- which user profile? - The current user

The project is a classifieds ad website similar to craigslist

I'm trying to have the user select his/her location and have it stored as a user term. When the user is looking at the Ads only the ones matching his/her location will show. This eliminates having to select a location every time the user visits the site.

If you tell me if there are any other means to achieve this I'd appreciate it greatly. I've tried many methods and with my limited coding ability I'm unable to customize modules, this module has been the closest to meeting my needs.

Thank you again,
Jesse

joachim’s picture

Status: Postponed (maintainer needs more info) » Closed (works as designed)

Okay, so you don't want this AT ALL.

Anything you add to a view is to do with the items the view shows. So in this case, nodes. 'User terms' has no meaning for a list of nodes.

What you need is a term argument and some PHP argument handling code that supplies a default argument based on the current user's term. And I'm afraid to say you will need coding ability.

jcolby1028’s picture

Bummer. Thanks for the information, you've saved me time and some frustration.

-Jesse

jcolby1028’s picture

Status: Closed (works as designed) » Closed (fixed)
d0t101101’s picture

I needed this functionality, and came up with this:

-Add Argument -> Taxonomy -> Taxonomy Term ID
-Provide default argument
-PHP Code
-PHP argument code:

global $user;
$query = "SELECT u.tid, t.vid, t.name FROM {term_user} u
            INNER JOIN {term_data} t ON t.tid = u.tid
            INNER JOIN {vocabulary} v ON t.vid = v.vid
            WHERE u.uid = %d
            ORDER BY v.weight, t.weight, t.name";
$result = db_query($query, $user->uid);
if ($result) {
  $termargs = '';
  while ($term = db_fetch_array($result)) {
    $termargs .= $term['tid']."+";
  }
  $termargs = substr($termargs,0,-1);
  return $termargs;
}
else {
  return FALSE;
}

-Check "Allow multiple terms per argument."

This allows me to create views showing only nodes that a user may like based on their user_terms selections. I hope to see this functionality built into the module, as its very useful for practically any site using user_terms!

Great module BTW,

.

d0t101101’s picture

Correction to the code above. This takes into account when a user hasn't setup their user_terms, and rather then displaying all, it returns none:

global $user;
$query = "SELECT u.tid, t.vid, t.name FROM {term_user} u
            INNER JOIN {term_data} t ON t.tid = u.tid
            INNER JOIN {vocabulary} v ON t.vid = v.vid
            WHERE u.uid = %d
            ORDER BY v.weight, t.weight, t.name";
$result = db_query($query, $user->uid);
if ($result) {
  $termargs = '';
  while ($term = db_fetch_array($result)) {
    $termargs .= $term['tid']."+";
    //drupal_set_message($term['tid']);
  }
  $termargs = substr($termargs,0,-1);
  if ($termargs) {
    return $termargs;
  }
}
else {
  return FALSE;
}
joachim’s picture

Title: View Filter » add default argument plugin that gives terms from the user
Category: support » feature
Priority: Minor » Normal
Status: Closed (fixed) » Active

Looks pretty good. You've got the main part of it there. If someone can wrap this up in a Views default argument plugin, I'll commit the patch.

A few minor points about the code:

- there's no need for either of those joins as the only thing you want back is the tid.
- use implode() instead of concatenation and trimming the last +
- you're using global $user which is all you can do in this code; however if this were a plugin I'd suggest trying to subclass the default user plugin so you can also get the terms from the user at a path like /user/UID/yourviewhere.

d0t101101’s picture

Well I'd like to make REALLY good, so here you go :)

global $user;
$query = "SELECT tid FROM {term_user} WHERE uid = %d";
$result = db_query($query, $user->uid);
if ($result) {
  $terms = array();
  while ($term = db_fetch_array($result)) {
    $terms[] = $term['tid'];
  }
  if ($terms) {
    $termargs = implode("+", $terms);
    return $termargs;
  }
}
else {
  return FALSE;
}

Regarding your last suggestion, would you kindly give me an example of how to "subclass the default user plugin"?

Thanks,
.

joachim’s picture

Look in Views module at the existing plugins. Also, image module implements a default argument plugin -- see image_views_plugins().

jordojuice’s picture

Version: 6.x-1.0-beta3 » 6.x-1.3
Category: feature » task

I know it's been a while since this post has been updated, but I have been looking for a way to do exactly this. I am using User Terms and need to be able to display a list of nodes with terms that match those on the user's profile. I made a Page and tried each of the samples above in a Node type Views argument but even with no filters all I got was a list of several duplicates of the current user instead of the nodes I was looking for. What could I have missed? I used all the same argument settings from #6 and other than that just a few fields and sorting criteria. Any help would be much appreciated.

joachim’s picture

Version: 6.x-1.3 » 6.x-1.x-dev
Component: Miscellaneous » Code
Category: task » feature

Like I said in #3, this requires custom code.

It could be added to this module if someone provides a patch. When I say 'someone', I mean one of the people commenting on this issue asking for the feature.

jordojuice’s picture

Version: 6.x-1.x-dev » 6.x-1.3
Component: Code » Miscellaneous
Category: feature » task
Status: Active » Fixed

I got it! I had separate vocabularies between the two, but when I switch to the same vocabulary it works great!

jordojuice’s picture

Component: Miscellaneous » Code
Category: task » feature
Status: Fixed » Active

Gotcha. I think it's well worth it as many of us have spent hours getting nowhere on this. I see what I can do.

schultetwin’s picture

Status: Active » Needs review
FileSize
4.13 KB
2.21 KB

Alright, so I was going to do this fairly extensively on my site, so I created this plugin. Please look at it and see what you think.

Patch file contains plugin file as well as additional code for user_terms.views.inc.

joachim’s picture

The patch looks pretty good.

Though it doesn't cover all the cases this issue is about: reading up I see we really have three different things being discussed here:

- get terms from the current user
- get terms from the author of the displayed node
- get terms from the displayed user profile

I'm not sure whether it's best to try to fold these all into one plugin or make separate ones :/

schultetwin’s picture

Okay, I was able to get those as well. I totally changed the code, basing them off the to built in user arguments. I remade the patch. I've separated current user in one default argument, and displayed and user profile in the other (as is done in the user module).

Tell me what you think.

schultetwin’s picture

Sorry, I made a few more changes. The patch in #17 does not work.

joachim’s picture

Status: Needs review » Needs work

> I totally changed the code, basing them off the to built in user arguments

Oh wow. That is really clever! :)

Just a few tweaks needed:

+++ b/profiles/drupal_commons/modules/contrib/user_terms/user_terms_plugin_argument_default_user_terms_current.inc
@@ -0,0 +1,80 @@
+  var $option_name = 'default_argument_user_terms_current';

I'm not sure that we need this pattern. Why not just use the option name directly in the code? There's no reuse of things that need to refer to it that I can see.

+    $user = user_load($uid);

Don't say $user when you don't mean the current user; it can lead to security holes if a 'global $user' is later added in the same scope. Use $account instead.

schultetwin’s picture

Status: Needs work » Needs review
FileSize
8.95 KB

I'm not sure why one would use the $option_name variable. I used it mostly because the plugins that comes with views use them. I don't see that it really matters either way, but if you'd like I can in and replace all instances.

Thank you for pointing out the $user variable thing, I forgot about that.

joachim’s picture

Status: Needs review » Needs work

You've still got $option_name defined and then not used.

While you're rerolling, could you make sure:

- there's a newline at the end of each file
- roll from the base folder of the module rather than your base Drupal

A few tweaks for capitalization:

- 'title' => t('Taxonomy Term IDs from logged in user'),
- 'title' => t('Taxonomy Term ID from user URL'),

I've followed the pattern of existing Views plugins.

And while we're at it...

I much prefer a pattern where a variable is set and then returned, rather than returning an expression. It makes debugging much easier, as I just had to do to figure out why it wasn't working:

          $tids = implode("+", $tids);
        }
        // Return all tids.
        else {
          $tids = implode("+", array_keys($account->user_terms));
        }

        dsm($tids); // I can figure it out now.
        return $tids;
      }

(BTW it didn't work because I am a numpty and added a user terms argument rather than node taxonomy...)

I'd quite like a one-line comment on each of the sections in get_argument, eg:
// Try to get a current node object and if there is one, its author.

Though if we have $user = menu_get_object('user', $i), why do we need if (arg(0) == 'user' && is_numeric(arg(1))) { ?
Also, can any of this be inherited from the parent class?

schultetwin’s picture

Sorry, haven't rerolled the patch yet. Probably won't happen until next week. This is the problem I'm running into. First, the reason to use $this->option_name is to allow other classes to extend you class. (So, effectively, there form options also app

The views_plugin_argument_default_user class defines it's form as:
$form[$option->name]
Which makes it hard to add additional form items to it. If I just chose not to use $option->name variable, then the fields that would appear for the default user argument only then appear for my argument. In short, I'm trying to find a way around that. I'm not sure the user classes are the best to use for this argument.

Mark

joachim’s picture

Oh right I get it.
The $option_name is actually some subform magic to make these element only appear when our radio button is selected.

And I see that you can't reuse anything much from the parent because of that. Hmm :/

schultetwin’s picture

Yeah. That's quite annoying. I could try posting a patch for views module, but I doubt that it will be used, as only bug fixes are going into views 2.x, and this won't be an issue for views 3.x.

I guess I could just build it for views 3, but I think it would be most helpful for most people, including myself for views 2.

rickh’s picture

Hey guys, is there any way to display the users who have the same user term. For example user being viewed has selected Apple as his favourite fruit. Other users who like apples.

rickh’s picture

Hey guys, implemented the patch and I get the following error in my view.

warning: array_filter() [function.array-filter]: The first argument should be an array in /home/woopycoz/public_html/sites/all/modules/user_terms/user_terms_plugin_argument_default_user_terms_current.inc on line 57.

Line 57 is included at options below

 $form[$this->option_name]['vids'] = array(
      '#prefix' => '<div><div id="edit-options-default-argument-user-terms-tid-vids">',
      '#suffix' => '</div></div>',
      '#type' => 'checkboxes',
      '#title' => t('Vocabularies'),
      '#options' => $options,
      '#default_value' => isset($this->argument->options[$this->option_name]['vids']) ? $this->argument->options[$this->option_name]['vids'] : array(),
      '#process' => array('expand_checkboxes', 'views_process_dependency'),
      '#dependency' => array(
        'radio:options[default_action]' => array('default'),
        'radio:options[default_argument_type]' => array($this->id),
        'edit-options-default-argument-user-terms-tid-limit' => array(TRUE),
      ),
      '#dependency_count' => 3,
    );
  }